git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@3306 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.2
@@ -25,6 +25,10 @@ Michael Voigt | |||
2009-02-11 Stephane Letz <letz@grame.fr> | |||
* Merge Solaris branch back on trunk. | |||
2009-02-10 Stephane Letz <letz@grame.fr> | |||
* Add a resample quality parameter in netadapter. | |||
2009-02-09 Stephane Letz <letz@grame.fr> | |||
@@ -76,6 +80,14 @@ Michael Voigt | |||
* Cleanup server starting code for clients directly linked with libjackserver.so. | |||
2009-01-09 Stephane Letz <letz@grame.fr> | |||
* JackProfiler scan already running clients (so can now be added anytime in the graph). | |||
2009-01-09 Stephane Letz <letz@grame.fr> | |||
* New JackProfiler class for real-time server monitoring. | |||
2009-01-07 Stephane Letz <letz@grame.fr> | |||
* Use up to BUFFER_SIZE_MAX frames in midi ports, fix for ticket #117. | |||
@@ -88,6 +100,8 @@ Michael Voigt | |||
2008-12-18 Stephane Letz <letz@grame.fr> | |||
* For ALSA driver, synchronize with latest jack1 memops functions. | |||
* Use memops functions in JackOSSDriver. | |||
* Use memops functions in JackOSSAdapter. | |||
2008-12-17 Stephane Letz <letz@grame.fr> | |||
@@ -95,15 +109,37 @@ Michael Voigt | |||
2008-12-16 Stephane Letz <letz@grame.fr> | |||
* Fix JackOSSDriver::SetBufferSize (was crashing when restoring old size), fix ticket #111. | |||
* Force memory page in of profiling array in JackOSSDriver::Open. | |||
* Cleanup profiling code. | |||
* Client and library global context cleanup in case of incorrect shutdown handling (that is applications not correctly closing client after server has shutdown). | |||
2008-12-08 Stephane Letz <letz@grame.fr> | |||
* Forbid JackOSSDriver to run in "aynchronous" mode, correct DSP CPU computation. | |||
2008-12-04 Stephane Letz <letz@grame.fr> | |||
* More profiling in JackOSSDriver: sample conversion duration is measured. | |||
2008-12-02 Stephane Letz <letz@grame.fr> | |||
* Optimize JackOSSDriver: no samples conversion if ports are not connected. | |||
2008-12-01 Stephane Letz <letz@grame.fr> | |||
* Force preload of memory table in JackEngineProfiling. | |||
2008-11-27 Stephane Letz <letz@grame.fr> | |||
* Add timing profiling code in JackOSSDriver. | |||
* Report ringbuffer.c fixes from jack1. | |||
2008-11-21 Stephane Letz <letz@grame.fr> | |||
* Report ringbuffer.c fixes from jack1. | |||
* Better isolation of server and clients system resources to allow starting the server in several user account at the same time. | |||
* Correct ressource cleanup in case of driver open failure. | |||
2008-11-19 Stephane Letz <letz@grame.fr> | |||
@@ -119,12 +155,13 @@ Michael Voigt | |||
* Fix jackctl_server_unload_internal. | |||
2008-10-30 Stephane Letz <letz@grame.fr> | |||
* Fix Midi port initialization in JackNetDriver. | |||
* Correct JackClient::ShutDown. | |||
* Correct JackClient::ShutDown. | |||
* TimeOut management in JackNetUnixSocket on Solaris. | |||
2008-10-23 Stephane Letz <letz@grame.fr> | |||
* In JackOSSDriver, vmix mode is used by default, exclusif (O_EXCL) mode can be selected with -e option. | |||
* Fix a crash in JackEngine::Close when backend cannot be loaded. | |||
* Tim Blechmann optimization patch. | |||
* Backport of latest Paul alsa_seqmidi changes. | |||
@@ -147,6 +184,38 @@ Michael Voigt | |||
* Checking for libsamplerate in waf, fix ticket #89." | |||
* Header cleanup, add --clients and --ports options in configure. | |||
2008-09-22 Stephane Letz <letz@grame.fr> | |||
* Socket time out implementation on Solaris. | |||
* Fix a conflict with Audio Hijack in JackCoreAudioDriver. | |||
2008-10-10 Stephane Letz <letz@grame.fr> | |||
* Improve OSS backend : SNDCTL_DSP_SETFRAGMENT must be done before, use of AFMT_S16_LE kind of values. | |||
2008-10-09 Stephane Letz <letz@grame.fr> | |||
* First version of OSS backend. | |||
* Use a mutex to make jack_client_open/jack_client_close thread safe, remove use of jack_init/jack_uninit. | |||
2008-10-08 Stephane Letz <letz@grame.fr> | |||
* Fix a SMP related bug introduced in rev 2957 : remove the __SMP__ flag and define LOCK for SMP in all cases. | |||
2008-10-03 Stephane Letz <letz@grame.fr> | |||
* Add engine profiling tools. | |||
2008-10-02 Stephane Letz <letz@grame.fr> | |||
* Correct file permission for jack-shm-registry POSIX shared memory segment. | |||
* Checking for libsamplerate in waf, fix ticket #89." | |||
* Header cleanup, add --clients and --ports options in configure. | |||
2008-10-01 Stephane Letz <letz@grame.fr> | |||
* First Solaris version. | |||
2008-09-22 Stephane Letz <letz@grame.fr> | |||
* Cleanup jack_port_id_t/jack_port_t mess, should work again on 64 bits machines." | |||
@@ -1098,7 +1098,11 @@ EXPORT jack_port_t* jack_port_register(jack_client_t* ext_client, const char* po | |||
jack_error("jack_port_register called with a NULL port name or a NULL port_type"); | |||
return NULL; | |||
} else { | |||
#if defined(__x86_64__) || defined(__ppc64__) | |||
return (jack_port_t *)((uint64_t)client->PortRegister(port_name, port_type, flags, buffer_size)); | |||
#else | |||
return (jack_port_t *)client->PortRegister(port_name, port_type, flags, buffer_size); | |||
#endif | |||
} | |||
} | |||
@@ -1349,7 +1353,11 @@ EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* por | |||
if (!manager) | |||
return NULL; | |||
int res = manager->GetPort(portname); // returns a port index at least > 1 | |||
#if defined(__x86_64__) || defined(__ppc64__) | |||
return (res == NO_PORT) ? NULL : (jack_port_t*)((uint64_t)res); | |||
#else | |||
return (res == NO_PORT) ? NULL : (jack_port_t*)res; | |||
#endif | |||
} | |||
} | |||
@@ -1359,7 +1367,11 @@ EXPORT jack_port_t* jack_port_by_id(jack_client_t* ext_client, jack_port_id_t id | |||
JackLibGlobals::CheckContext(); | |||
#endif | |||
/* jack_port_t* type is actually the port index */ | |||
#if defined(__x86_64__) || defined(__ppc64__) | |||
return (jack_port_t*)((uint64_t)id); | |||
#else | |||
return (jack_port_t*)id; | |||
#endif | |||
} | |||
EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client) | |||
@@ -23,8 +23,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
#include <stdlib.h> | |||
#include <assert.h> | |||
#include "driver_interface.h" | |||
#ifdef __linux__ | |||
#include "JackAlsaAdapter.h" | |||
#endif | |||
@@ -37,6 +35,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
#include "JackPortAudioAdapter.h" | |||
#endif | |||
#if defined(__sun__) || defined(sun) | |||
#include "JackOSSAdapter.h" | |||
#endif | |||
#ifdef __cplusplus | |||
extern "C" | |||
{ | |||
@@ -65,6 +67,11 @@ extern "C" | |||
#ifdef __APPLE__ | |||
adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackCoreAudioAdapter(buffer_size, sample_rate, params)); | |||
#endif | |||
#if defined(__sun__) || defined(sun) | |||
adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackOSSAdapter(buffer_size, sample_rate, params)); | |||
#endif | |||
assert(adapter); | |||
if (adapter->Open() == 0) | |||
@@ -33,16 +33,15 @@ namespace Jack | |||
class SERVER_EXPORT JackAudioDriver : public JackDriver | |||
{ | |||
private: | |||
protected: | |||
int ProcessAsync(); | |||
int ProcessSync(); | |||
void ProcessGraphAsync(); | |||
void ProcessGraphSync(); | |||
void WaitUntilNextCycle(); | |||
protected: | |||
virtual int ProcessAsync(); | |||
virtual int ProcessSync(); | |||
int fCaptureChannels; | |||
int fPlaybackChannels; | |||
@@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
#if defined (__APPLE__) | |||
#include <Accelerate/Accelerate.h> | |||
#elif defined (__SSE__) | |||
#elif defined (__SSE__) && !defined (__sun__) | |||
#include <xmmintrin.h> | |||
#endif | |||
@@ -46,7 +46,7 @@ static inline void MixAudioBuffer(float* mixbuffer, float* buffer, jack_nframes_ | |||
frames = frames % 4; | |||
while (frames_group > 0) { | |||
#ifdef __SSE__ | |||
#if defined (__SSE__) && !defined (__sun__) | |||
__m128 vec = _mm_add_ps(_mm_load_ps(mixbuffer), _mm_load_ps(buffer)); | |||
_mm_store_ps(mixbuffer, vec); | |||
@@ -97,7 +97,7 @@ static void AudioBufferMixdown(void* mixbuffer, void** src_buffers, int src_coun | |||
void* buffer; | |||
// Copy first buffer | |||
#ifdef __SSE__ | |||
#if defined (__SSE__) && !defined (__sun__) | |||
jack_nframes_t frames_group = nframes / 4; | |||
jack_nframes_t remaining_frames = nframes % 4; | |||
@@ -362,7 +362,7 @@ bool JackClient::Execute() | |||
if (GetEngineControl()->fRealTime) | |||
set_threaded_log_function(); | |||
if (fThreadFun) { | |||
// Execute a dummy cycle to be sure thread has the correct properties (ensure thread creation is finished) | |||
WaitSync(); | |||
@@ -57,17 +57,27 @@ | |||
#ifdef WIN32 | |||
#define jack_server_dir "server" | |||
#define jack_client_dir "client" | |||
#define ADDON_DIR "jack" | |||
#elif __APPLE__ | |||
#define ADDON_DIR "jackmp" | |||
#endif | |||
#ifdef __APPLE__ | |||
#define jack_server_dir "/tmp" | |||
#define jack_client_dir "/tmp" | |||
#define JACK_DEFAULT_DRIVER "coreaudio" | |||
#else | |||
#endif | |||
#ifdef __linux__ | |||
#define jack_server_dir "/dev/shm" | |||
#define jack_client_dir "/dev/shm" | |||
#define JACK_DEFAULT_DRIVER "alsa" | |||
#endif | |||
#if defined(__sun__) || defined(sun) | |||
#define jack_server_dir "/tmp" | |||
#define jack_client_dir "/tmp" | |||
#define JACK_DEFAULT_DRIVER "oss" | |||
#endif | |||
#define jack_server_entry "jackdmp_entry" | |||
#define jack_client_entry "jack_client" | |||
@@ -21,7 +21,6 @@ | |||
*/ | |||
#ifndef WIN32 | |||
#include <stdbool.h> | |||
#include <stdint.h> | |||
#include <dirent.h> | |||
#include <pthread.h> | |||
@@ -42,6 +41,7 @@ | |||
#include "JackTools.h" | |||
#include "JackControlAPI.h" | |||
#include "JackLockedEngine.h" | |||
#include "JackConstants.h" | |||
using namespace Jack; | |||
@@ -561,7 +561,11 @@ jackctl_wait_signals(sigset_t signals) | |||
bool waiting = true; | |||
while (waiting) { | |||
#if defined(sun) && !defined(__sun__) // SUN compiler only, to check | |||
sigwait(&signals); | |||
#else | |||
sigwait(&signals, &sig); | |||
#endif | |||
fprintf(stderr, "jack main caught signal %d\n", sig); | |||
switch (sig) { | |||
@@ -467,6 +467,17 @@ int JackEngine::GetClientPID(const char* name) | |||
return 0; | |||
} | |||
int JackEngine::GetClientRefNum(const char* name) | |||
{ | |||
for (int i = 0; i < CLIENT_NUM; i++) { | |||
JackClientInterface* client = fClientTable[i]; | |||
if (client && (strcmp(client->GetClientControl()->fName, name) == 0)) | |||
return client->GetClientControl()->fRefNum; | |||
} | |||
return -1; | |||
} | |||
// Used for external clients | |||
int JackEngine::ClientExternalOpen(const char* name, int pid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) | |||
{ | |||
@@ -91,6 +91,7 @@ class SERVER_EXPORT JackEngine | |||
int ClientDeactivate(int refnum); | |||
int GetClientPID(const char* name); | |||
int GetClientRefNum(const char* name); | |||
// Internal client management | |||
int GetInternalClientName(int int_ref, char* name_res); | |||
@@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
namespace Jack | |||
{ | |||
static inline _jack_time_t JACK_MAX(_jack_time_t a, _jack_time_t b) | |||
static inline jack_time_t JACK_MAX(jack_time_t a, jack_time_t b) | |||
{ | |||
return (a < b) ? b : a; | |||
} | |||
@@ -46,6 +46,9 @@ void JackEngineControl::CycleBegin(JackClientInterface** table, | |||
{ | |||
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) | |||
@@ -24,9 +24,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
#include "JackShmMem.h" | |||
#include "JackFrameTimer.h" | |||
#include "JackTransportEngine.h" | |||
#include "JackConstants.h" | |||
#include "types.h" | |||
#include <stdio.h> | |||
#ifdef JACK_MONITOR | |||
#include "JackEngineProfiling.h" | |||
#endif | |||
namespace Jack | |||
{ | |||
@@ -78,6 +83,10 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem | |||
// Timer | |||
JackFrameTimer fFrameTimer; | |||
#ifdef JACK_MONITOR | |||
JackEngineProfiling fProfiler; | |||
#endif | |||
JackEngineControl(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, const char* server_name) | |||
{ | |||
@@ -105,6 +114,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem | |||
fMaxDelayedUsecs = 0.f; | |||
fXrunDelayedUsecs = 0.f; | |||
} | |||
~JackEngineControl() | |||
{} | |||
@@ -0,0 +1,330 @@ | |||
/* | |||
Copyright (C) 2008 Grame & RTL | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU Lesser General Public License as published by | |||
the Free Software Foundation; either version 2.1 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU Lesser General Public License for more details. | |||
You should have received a copy of the GNU Lesser General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
*/ | |||
#include "JackEngineProfiling.h" | |||
#include "JackGraphManager.h" | |||
#include "JackClientControl.h" | |||
#include "JackClientInterface.h" | |||
#include "JackTime.h" | |||
namespace Jack | |||
{ | |||
JackEngineProfiling::JackEngineProfiling():fAudioCycle(0) | |||
{ | |||
jack_info("Engine profiling activated, beware %ld MBytes are needed to record profiling points...", sizeof(fProfileTable) / (1024 * 1024)); | |||
// Force memory page in | |||
memset(fProfileTable, 0, sizeof(fProfileTable)); | |||
} | |||
JackEngineProfiling::~JackEngineProfiling() | |||
{ | |||
// Window monitoring | |||
int max_client = 0; | |||
char buffer[1024]; | |||
char* nameTable[CLIENT_NUM]; | |||
FILE* file = fopen("JackEngineProfiling.log", "w"); | |||
jack_info("Write server and clients timing data..."); | |||
if (file == NULL) { | |||
jack_error("JackEngineProfiling::Save cannot open JackEngineProfiling.log file"); | |||
} else { | |||
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); | |||
} | |||
} | |||
} | |||
fclose(file); | |||
} | |||
// Driver period | |||
file = fopen("Timing1.plot", "w"); | |||
if (file == NULL) { | |||
jack_error("JackEngineProfiling::Save cannot open Timing1.log file"); | |||
} else { | |||
fprintf(file, "set grid\n"); | |||
fprintf(file, "set title \"Audio driver timing\"\n"); | |||
fprintf(file, "set xlabel \"audio cycles\"\n"); | |||
fprintf(file, "set ylabel \"usec\"\n"); | |||
fprintf(file, "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n"); | |||
fprintf(file, "set output 'Timing1.pdf\n"); | |||
fprintf(file, "set terminal pdf\n"); | |||
fprintf(file, "set grid\n"); | |||
fprintf(file, "set title \"Audio driver timing\"\n"); | |||
fprintf(file, "set xlabel \"audio cycles\"\n"); | |||
fprintf(file, "set ylabel \"usec\"\n"); | |||
fprintf(file, "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n"); | |||
fclose(file); | |||
} | |||
// Driver end date | |||
file = fopen("Timing2.plot", "w"); | |||
if (file == NULL) { | |||
jack_error("JackEngineProfiling::Save cannot open Timing2.log file"); | |||
} else { | |||
fprintf(file, "set grid\n"); | |||
fprintf(file, "set title \"Driver end date\"\n"); | |||
fprintf(file, "set xlabel \"audio cycles\"\n"); | |||
fprintf(file, "set ylabel \"usec\"\n"); | |||
fprintf(file, "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n"); | |||
fprintf(file, "set output 'Timing2.pdf\n"); | |||
fprintf(file, "set terminal pdf\n"); | |||
fprintf(file, "set grid\n"); | |||
fprintf(file, "set title \"Driver end date\"\n"); | |||
fprintf(file, "set xlabel \"audio cycles\"\n"); | |||
fprintf(file, "set ylabel \"usec\"\n"); | |||
fprintf(file, "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n"); | |||
fclose(file); | |||
} | |||
// Clients end date | |||
if (max_client > 0) { | |||
file = fopen("Timing3.plot", "w"); | |||
if (file == NULL) { | |||
jack_error("JackEngineProfiling::Save cannot open Timing3.log file"); | |||
} else { | |||
fprintf(file, "set multiplot\n"); | |||
fprintf(file, "set grid\n"); | |||
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++) { | |||
if (i == 0) { | |||
if ((i + 1) == max_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)]); | |||
} 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)]); | |||
} | |||
} 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 { | |||
sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, nameTable[(i + 1)]); | |||
} | |||
fprintf(file, buffer); | |||
} | |||
fprintf(file, "\n unset multiplot\n"); | |||
fprintf(file, "set output 'Timing3.pdf\n"); | |||
fprintf(file, "set terminal pdf\n"); | |||
fprintf(file, "set multiplot\n"); | |||
fprintf(file, "set grid\n"); | |||
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++) { | |||
if (i == 0) { | |||
if ((i + 1) == max_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)]); | |||
} 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)]); | |||
} | |||
} 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 { | |||
sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, nameTable[(i + 1)]); | |||
} | |||
fprintf(file, buffer); | |||
} | |||
fclose(file); | |||
} | |||
} | |||
// Clients scheduling | |||
if (max_client > 0) { | |||
file = fopen("Timing4.plot", "w"); | |||
if (file == NULL) { | |||
jack_error("JackEngineProfiling::Save cannot open Timing4.log file"); | |||
} else { | |||
fprintf(file, "set multiplot\n"); | |||
fprintf(file, "set grid\n"); | |||
fprintf(file, "set title \"Clients scheduling latency\"\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++) { | |||
if ((i + 1) == max_client) // Last client | |||
sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), nameTable[(i + 1)]); | |||
else | |||
sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7), nameTable[(i + 1)]); | |||
fprintf(file, buffer); | |||
} | |||
fprintf(file, "\n unset multiplot\n"); | |||
fprintf(file, "set output 'Timing4.pdf\n"); | |||
fprintf(file, "set terminal pdf\n"); | |||
fprintf(file, "set multiplot\n"); | |||
fprintf(file, "set grid\n"); | |||
fprintf(file, "set title \"Clients scheduling latency\"\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++) { | |||
if ((i + 1) == max_client) // Last client | |||
sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), nameTable[(i + 1)]); | |||
else | |||
sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7), nameTable[(i + 1)]); | |||
fprintf(file, buffer); | |||
} | |||
fclose(file); | |||
} | |||
} | |||
// Clients duration | |||
if (max_client > 0) { | |||
file = fopen("Timing5.plot", "w"); | |||
if (file == NULL) { | |||
jack_error("JackEngineProfiling::Save cannot open Timing5.log file"); | |||
} else { | |||
fprintf(file, "set multiplot\n"); | |||
fprintf(file, "set grid\n"); | |||
fprintf(file, "set title \"Clients duration\"\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++) { | |||
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 | |||
sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) + 1, nameTable[(i + 1)]); | |||
fprintf(file, buffer); | |||
} | |||
fprintf(file, "\n unset multiplot\n"); | |||
fprintf(file, "set output 'Timing5.pdf\n"); | |||
fprintf(file, "set terminal pdf\n"); | |||
fprintf(file, "set multiplot\n"); | |||
fprintf(file, "set grid\n"); | |||
fprintf(file, "set title \"Clients duration\"\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++) { | |||
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 | |||
sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) + 1, nameTable[(i + 1)]); | |||
fprintf(file, buffer); | |||
} | |||
fclose(file); | |||
} | |||
} | |||
} | |||
void JackEngineProfiling::Profile(JackClientInterface** table, | |||
JackGraphManager* manager, | |||
jack_time_t period_usecs, | |||
jack_time_t cur_cycle_begin, | |||
jack_time_t prev_cycle_end) | |||
{ | |||
fAudioCycle = (fAudioCycle + 1) % TIME_POINTS; | |||
// Keeps cycle data | |||
fProfileTable[fAudioCycle].fPeriodUsecs = period_usecs; | |||
fProfileTable[fAudioCycle].fCurCycleBegin = cur_cycle_begin; | |||
fProfileTable[fAudioCycle].fPrevCycleEnd = prev_cycle_end; | |||
fProfileTable[fAudioCycle].fAudioCycle = fAudioCycle; | |||
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); | |||
fProfileTable[fAudioCycle].fClientTable[i].fRefNum = i; | |||
fProfileTable[fAudioCycle].fClientTable[i].fSignaledAt = timing->fSignaledAt; | |||
fProfileTable[fAudioCycle].fClientTable[i].fAwakeAt = timing->fAwakeAt; | |||
fProfileTable[fAudioCycle].fClientTable[i].fFinishedAt = timing->fFinishedAt; | |||
fProfileTable[fAudioCycle].fClientTable[i].fStatus = timing->fStatus; | |||
} | |||
} | |||
} | |||
JackTimingMeasure* JackEngineProfiling::GetCurMeasure() | |||
{ | |||
return &fProfileTable[fAudioCycle]; | |||
} | |||
} // end of namespace |
@@ -1,6 +1,5 @@ | |||
/* | |||
Copyright (C) 2003 Paul Davis | |||
Copyright (C) 2004-2008 Grame | |||
Copyright (C) 2008 Grame & RTL | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU Lesser General Public License as published by | |||
@@ -18,17 +17,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
*/ | |||
#ifndef __JackEngineTiming__ | |||
#define __JackEngineTiming__ | |||
#ifndef __JackEngineProfiling__ | |||
#define __JackEngineProfiling__ | |||
#include "types.h" | |||
#include "JackTypes.h" | |||
#include "JackConstants.h" | |||
#include "JackShmMem.h" | |||
namespace Jack | |||
{ | |||
#define TIME_POINTS 1000 | |||
#define TIME_POINTS 250000 | |||
#define FAILURE_TIME_POINTS 10000 | |||
#define FAILURE_WINDOW 10 | |||
/*! | |||
\brief Timing stucture for a client. | |||
@@ -50,36 +52,41 @@ struct JackTimingMeasureClient | |||
struct JackTimingMeasure | |||
{ | |||
unsigned int fAudioCycle; | |||
jack_time_t fEngineTime; | |||
jack_time_t fPeriodUsecs; | |||
jack_time_t fCurCycleBegin; | |||
jack_time_t fPrevCycleEnd; | |||
JackTimingMeasureClient fClientTable[CLIENT_NUM]; | |||
}; | |||
/*! | |||
\brief Client timing. | |||
\brief Client timing monitoring. | |||
*/ | |||
class JackClientInterface; | |||
class JackGraphManager; | |||
class JackEngineTiming | |||
class SERVER_EXPORT JackEngineProfiling | |||
{ | |||
private: | |||
JackTimingMeasure fMeasure[TIME_POINTS]; | |||
JackTimingMeasure fProfileTable[TIME_POINTS]; | |||
char fNameTable[CLIENT_NUM][JACK_CLIENT_NAME_SIZE + 1]; | |||
unsigned int fAudioCycle; | |||
jack_time_t fPrevCycleTime; | |||
jack_time_t fCurCycleTime; | |||
public: | |||
JackEngineTiming():fAudioCycle(0),fPrevCycleTime(0),fCurCycleTime(0) | |||
{} | |||
~JackEngineTiming() | |||
{} | |||
JackEngineProfiling(); | |||
~JackEngineProfiling(); | |||
void Profile(JackClientInterface** table, | |||
JackGraphManager* manager, | |||
jack_time_t period_usecs, | |||
jack_time_t cur_cycle_begin, | |||
jack_time_t prev_cycle_end); | |||
JackTimingMeasure* GetCurMeasure(); | |||
void GetTimeMeasure(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end); | |||
void ClearTimeMeasures(); | |||
}; | |||
} // end of namespace |
@@ -1,71 +0,0 @@ | |||
/* | |||
Copyright (C) 2003 Paul Davis | |||
Copyright (C) 2004-2008 Grame | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU Lesser General Public License as published by | |||
the Free Software Foundation; either version 2.1 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU Lesser General Public License for more details. | |||
You should have received a copy of the GNU Lesser General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
*/ | |||
#include "JackEngineTiming.h" | |||
#include "JackGraphManager.h" | |||
#include "JackClientControl.h" | |||
#include "JackClientInterface.h" | |||
#include "JackTime.h" | |||
namespace Jack | |||
{ | |||
void JackEngineTiming::GetTimeMeasure(JackClientInterface** table, | |||
JackGraphManager* manager, | |||
jack_time_t cur_cycle_begin, | |||
jack_time_t prev_cycle_end) | |||
{ | |||
int pos = (++fAudioCycle) % TIME_POINTS; | |||
fPrevCycleTime = fCurCycleTime; | |||
fCurCycleTime = cur_cycle_begin; | |||
if (fPrevCycleTime > 0) { | |||
fMeasure[pos].fEngineTime = fPrevCycleTime; | |||
fMeasure[pos].fAudioCycle = fAudioCycle; | |||
for (int i = 0; i < CLIENT_NUM; i++) { | |||
JackClientInterface* client = table[i]; | |||
JackClientTiming* timing = manager->GetClientTiming(i); | |||
if (client && client->GetClientControl()->fActive) { | |||
fMeasure[pos].fClientTable[i].fRefNum = i; | |||
fMeasure[pos].fClientTable[i].fSignaledAt = timing->fSignaledAt; | |||
fMeasure[pos].fClientTable[i].fAwakeAt = timing->fAwakeAt; | |||
fMeasure[pos].fClientTable[i].fFinishedAt = timing->fFinishedAt; | |||
fMeasure[pos].fClientTable[i].fStatus = timing->fStatus; | |||
} | |||
} | |||
} | |||
} | |||
void JackEngineTiming::ClearTimeMeasures() | |||
{ | |||
for (int i = 0; i < TIME_POINTS; i++) { | |||
for (int j = 0; j < CLIENT_NUM; j++) { | |||
fMeasure[i].fClientTable[j].fRefNum = 0; | |||
fMeasure[i].fClientTable[j].fSignaledAt = 0; | |||
fMeasure[i].fClientTable[j].fAwakeAt = 0; | |||
fMeasure[i].fClientTable[j].fFinishedAt = 0; | |||
} | |||
} | |||
fPrevCycleTime = fCurCycleTime = 0; | |||
} | |||
} // end of namespace |
@@ -196,7 +196,13 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble | |||
JackLock lock(this); | |||
return fEngine.GetClientPID(name); | |||
} | |||
int GetClientRefNum(const char* name) | |||
{ | |||
JackLock lock(this); | |||
return fEngine.GetClientRefNum(name); | |||
} | |||
}; | |||
} // end of namespace | |||
@@ -508,10 +508,9 @@ namespace Jack | |||
JackNetMasterManager::~JackNetMasterManager() | |||
{ | |||
jack_log ( "JackNetMasterManager::~JackNetMasterManager" ); | |||
jack_info ( "Exiting net manager..." ); | |||
fRunning = false; | |||
jack_client_stop_thread ( fManagerClient, fManagerThread ); | |||
jack_client_kill_thread ( fManagerClient, fManagerThread ); | |||
master_list_t::iterator it; | |||
for ( it = fMasterList.begin(); it != fMasterList.end(); it++ ) | |||
delete ( *it ); | |||
@@ -0,0 +1,291 @@ | |||
/* | |||
Copyright (C) 2009 Grame | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation; either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
*/ | |||
#include "JackProfiler.h" | |||
#include "JackServerGlobals.h" | |||
#include "JackEngineControl.h" | |||
#include "JackLockedEngine.h" | |||
#include "JackArgParser.h" | |||
#include <assert.h> | |||
#include <string> | |||
namespace Jack | |||
{ | |||
JackProfilerClient::JackProfilerClient(jack_client_t* client, const char* name) | |||
:fClient(client) | |||
{ | |||
char port_name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; | |||
fRefNum = JackServerGlobals::fInstance->GetEngine()->GetClientRefNum(name); | |||
snprintf(port_name, sizeof(port_name) - 1, "%s:scheduling", name); | |||
fSchedulingPort = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | |||
snprintf(port_name, sizeof(port_name) - 1, "%s:duration", name); | |||
fDurationPort = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | |||
} | |||
JackProfilerClient::~JackProfilerClient() | |||
{ | |||
jack_port_unregister(fClient, fSchedulingPort); | |||
jack_port_unregister(fClient, fDurationPort); | |||
} | |||
#ifdef JACK_MONITOR | |||
JackProfiler::JackProfiler(jack_client_t* client, const JSList* params) | |||
:fClient(client), fLastMeasure(NULL) | |||
#else | |||
JackProfiler::JackProfiler(jack_client_t* client, const JSList* params) | |||
:fClient(client) | |||
#endif | |||
{ | |||
jack_log("JackProfiler::JackProfiler"); | |||
fCPULoadPort = fDriverPeriodPort = fDriverEndPort = NULL; | |||
const JSList* node; | |||
const jack_driver_param_t* param; | |||
for (node = params; node; node = jack_slist_next(node)) { | |||
param = (const jack_driver_param_t*)node->data; | |||
switch (param->character) { | |||
case 'c': | |||
fCPULoadPort = jack_port_register(client, "cpu_load", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | |||
break; | |||
case 'p': | |||
fDriverPeriodPort = jack_port_register(client, "driver_period", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | |||
break; | |||
case 'e': | |||
fDriverEndPort = jack_port_register(client, "driver_end_time", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | |||
break; | |||
} | |||
} | |||
// Resigster all running clients | |||
const char **ports = jack_get_ports(client, NULL, NULL, 0); | |||
if (ports) { | |||
for (int i = 0; ports[i]; ++i) { | |||
std::string str = std::string(ports[i]); | |||
ClientRegistration(str.substr(0, str.find_first_of(':')).c_str(), 1, this); | |||
} | |||
free(ports); | |||
} | |||
jack_set_process_callback(client, Process, this); | |||
jack_set_client_registration_callback(client, ClientRegistration, this); | |||
jack_activate(client); | |||
} | |||
JackProfiler::~JackProfiler() | |||
{ | |||
jack_log("JackProfiler::~JackProfiler"); | |||
} | |||
void JackProfiler::ClientRegistration(const char* name, int val, void *arg) | |||
{ | |||
#ifdef JACK_MONITOR | |||
JackProfiler* profiler = static_cast<JackProfiler*>(arg); | |||
// Filter client or "system" name | |||
if (strcmp(name, jack_get_client_name(profiler->fClient)) == 0 || strcmp(name, "system") == 0) | |||
return; | |||
profiler->fMutex.Lock(); | |||
if (val) { | |||
std::map<std::string, JackProfilerClient*>::iterator it = profiler->fClientTable.find(name); | |||
if (it == profiler->fClientTable.end()) { | |||
jack_log("Client %s added", name); | |||
profiler->fClientTable[name] = new JackProfilerClient(profiler->fClient, name); | |||
} | |||
} else { | |||
std::map<std::string, JackProfilerClient*>::iterator it = profiler->fClientTable.find(name); | |||
if (it != profiler->fClientTable.end()) { | |||
jack_log("Client %s removed", name); | |||
profiler->fClientTable.erase(it); | |||
delete((*it).second); | |||
} | |||
} | |||
profiler->fMutex.Unlock(); | |||
#endif | |||
} | |||
int JackProfiler::Process(jack_nframes_t nframes, void* arg) | |||
{ | |||
JackProfiler* profiler = static_cast<JackProfiler*>(arg); | |||
if (profiler->fCPULoadPort) { | |||
float* buffer_cpu_load = (float*)jack_port_get_buffer(profiler->fCPULoadPort, nframes); | |||
float cpu_load = jack_cpu_load(profiler->fClient); | |||
for (unsigned int i = 0; i < nframes; i++) { | |||
buffer_cpu_load[i] = cpu_load / 100.f; | |||
} | |||
} | |||
#ifdef JACK_MONITOR | |||
JackEngineControl* control = JackServerGlobals::fInstance->GetEngineControl(); | |||
JackEngineProfiling* engine_profiler = &control->fProfiler; | |||
JackTimingMeasure* measure = engine_profiler->GetCurMeasure(); | |||
if (profiler->fLastMeasure && profiler->fMutex.Trylock()) { | |||
if (profiler->fDriverPeriodPort) { | |||
float* buffer_driver_period = (float*)jack_port_get_buffer(profiler->fDriverPeriodPort, nframes); | |||
float value1 = (float(measure->fPeriodUsecs) - float(measure->fCurCycleBegin - profiler->fLastMeasure->fCurCycleBegin)) / float(measure->fPeriodUsecs); | |||
for (unsigned int i = 0; i < nframes; i++) { | |||
buffer_driver_period[i] = value1; | |||
} | |||
} | |||
if (profiler->fDriverEndPort) { | |||
float* buffer_driver_end_time = (float*)jack_port_get_buffer(profiler->fDriverEndPort, nframes); | |||
float value2 = (float(measure->fPrevCycleEnd - profiler->fLastMeasure->fCurCycleBegin)) / float(measure->fPeriodUsecs); | |||
for (unsigned int i = 0; i < nframes; i++) { | |||
buffer_driver_end_time[i] = value2; | |||
} | |||
} | |||
std::map<std::string, JackProfilerClient*>::iterator it; | |||
for (it = profiler->fClientTable.begin(); it != profiler->fClientTable.end(); it++) { | |||
int ref = (*it).second->fRefNum; | |||
long d5 = long(measure->fClientTable[ref].fSignaledAt - profiler->fLastMeasure->fCurCycleBegin); | |||
long d6 = long(measure->fClientTable[ref].fAwakeAt - profiler->fLastMeasure->fCurCycleBegin); | |||
long d7 = long(measure->fClientTable[ref].fFinishedAt - profiler->fLastMeasure->fCurCycleBegin); | |||
float* buffer_scheduling = (float*)jack_port_get_buffer((*it).second->fSchedulingPort, nframes); | |||
float value3 = float(d6 - d5) / float(measure->fPeriodUsecs); | |||
jack_log("Scheduling %f", value3); | |||
for (unsigned int i = 0; i < nframes; i++) { | |||
buffer_scheduling[i] = value3; | |||
} | |||
float* buffer_duration = (float*)jack_port_get_buffer((*it).second->fDurationPort, nframes); | |||
float value4 = float(d7 - d6) / float(measure->fPeriodUsecs); | |||
jack_log("Duration %f", value4); | |||
for (unsigned int i = 0; i < nframes; i++) { | |||
buffer_duration[i] = value4; | |||
} | |||
} | |||
profiler->fMutex.Unlock(); | |||
} | |||
profiler->fLastMeasure = measure; | |||
#endif | |||
return 0; | |||
} | |||
} // namespace Jack | |||
#ifdef __cplusplus | |||
extern "C" | |||
{ | |||
#endif | |||
#include "driver_interface.h" | |||
using namespace Jack; | |||
static Jack::JackProfiler* profiler = NULL; | |||
SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor() | |||
{ | |||
jack_driver_desc_t* desc = (jack_driver_desc_t*)calloc(1, sizeof(jack_driver_desc_t)); | |||
strcpy(desc->name, "profiler"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 | |||
strcpy(desc->desc, "real-time server profiling"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 | |||
desc->nparams = 3; | |||
desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); | |||
int i = 0; | |||
strcpy(desc->params[i].name, "cpu-load"); | |||
desc->params[i].character = 'c'; | |||
desc->params[i].type = JackDriverParamBool; | |||
desc->params[i].value.i = TRUE; | |||
strcpy(desc->params[i].short_desc, "Show DSP CPU load"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
i++; | |||
strcpy(desc->params[i].name, "driver-period"); | |||
desc->params[i].character = 'p'; | |||
desc->params[i].type = JackDriverParamBool; | |||
desc->params[i].value.i = TRUE; | |||
strcpy(desc->params[i].short_desc, "Show driver period"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
i++; | |||
strcpy(desc->params[i].name, "driver-end-time"); | |||
desc->params[i].character = 'e'; | |||
desc->params[i].type = JackDriverParamBool; | |||
desc->params[i].value.i = TRUE; | |||
strcpy(desc->params[i].short_desc, "Show driver end time"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
return desc; | |||
} | |||
SERVER_EXPORT int jack_internal_initialize(jack_client_t* jack_client, const JSList* params) | |||
{ | |||
if (profiler) { | |||
jack_info("profiler already loaded"); | |||
return 1; | |||
} | |||
jack_log("Loading profiler"); | |||
try { | |||
profiler = new Jack::JackProfiler(jack_client, params); | |||
assert(profiler); | |||
return 0; | |||
} catch (...) { | |||
return 1; | |||
} | |||
} | |||
SERVER_EXPORT int jack_initialize(jack_client_t* jack_client, const char* load_init) | |||
{ | |||
JSList* params = NULL; | |||
bool parse_params = true; | |||
int res = 1; | |||
jack_driver_desc_t* desc = jack_get_descriptor(); | |||
Jack::JackArgParser parser ( load_init ); | |||
if ( parser.GetArgc() > 0 ) | |||
parse_params = parser.ParseParams ( desc, ¶ms ); | |||
if (parse_params) { | |||
res = jack_internal_initialize ( jack_client, params ); | |||
parser.FreeParams ( params ); | |||
} | |||
return res; | |||
} | |||
SERVER_EXPORT void jack_finish(void* arg) | |||
{ | |||
Jack::JackProfiler* profiler = static_cast<Jack::JackProfiler*>(arg); | |||
if (profiler) { | |||
jack_log("Unloading profiler"); | |||
delete profiler; | |||
} | |||
} | |||
#ifdef __cplusplus | |||
} | |||
#endif |
@@ -0,0 +1,80 @@ | |||
/* | |||
Copyright (C) 2009 Grame | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation; either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
*/ | |||
#ifndef __JackProfiler__ | |||
#define __JackProfiler__ | |||
#include "JackConstants.h" | |||
#include "JackPlatformPlug.h" | |||
#include "jack.h" | |||
#include "jslist.h" | |||
#include <map> | |||
#include <string> | |||
#ifdef JACK_MONITOR | |||
#include "JackEngineProfiling.h" | |||
#endif | |||
namespace Jack | |||
{ | |||
struct JackProfilerClient { | |||
int fRefNum; | |||
jack_client_t* fClient; | |||
jack_port_t* fSchedulingPort; | |||
jack_port_t* fDurationPort; | |||
JackProfilerClient(jack_client_t* client, const char* name); | |||
~JackProfilerClient(); | |||
}; | |||
/*! | |||
\brief Server real-time monitoring | |||
*/ | |||
class JackProfiler | |||
{ | |||
private: | |||
jack_client_t* fClient; | |||
jack_port_t* fCPULoadPort; | |||
jack_port_t* fDriverPeriodPort; | |||
jack_port_t* fDriverEndPort; | |||
#ifdef JACK_MONITOR | |||
JackTimingMeasure* fLastMeasure; | |||
std::map<std::string, JackProfilerClient*> fClientTable; | |||
JackMutex fMutex; | |||
#endif | |||
public: | |||
JackProfiler(jack_client_t* jack_client, const JSList* params); | |||
~JackProfiler(); | |||
static int Process(jack_nframes_t nframes, void* arg); | |||
static void ClientRegistration(const char* name, int val, void *arg); | |||
}; | |||
} | |||
#endif |
@@ -226,6 +226,7 @@ int JackServer::SetBufferSize(jack_nframes_t buffer_size) | |||
return fAudioDriver->Start(); | |||
} else { // Failure: try to restore current value | |||
jack_error("Cannot SetBufferSize for audio driver, restore current value %ld", current_buffer_size); | |||
fAudioDriver->SetBufferSize(current_buffer_size); | |||
fFreewheelDriver->SetBufferSize(current_buffer_size); | |||
fEngineControl->InitFrameTime(); | |||
fAudioDriver->Start(); | |||
@@ -102,7 +102,17 @@ void JackShmMem::operator delete(void* obj) | |||
void LockMemoryImp(void* ptr, size_t size) | |||
{ | |||
if (CHECK_MLOCK(ptr, size)) { | |||
if (CHECK_MLOCK((char*)ptr, size)) { | |||
jack_log("Succeeded in locking %u byte memory area", size); | |||
} else { | |||
jack_error("Cannot lock down memory area (%s)", strerror(errno)); | |||
} | |||
} | |||
void InitLockMemoryImp(void* ptr, size_t size) | |||
{ | |||
if (CHECK_MLOCK((char*)ptr, size)) { | |||
memset(ptr, 0, size); | |||
jack_log("Succeeded in locking %u byte memory area", size); | |||
} else { | |||
jack_error("Cannot lock down memory area (%s)", strerror(errno)); | |||
@@ -111,7 +121,7 @@ void LockMemoryImp(void* ptr, size_t size) | |||
void UnlockMemoryImp(void* ptr, size_t size) | |||
{ | |||
if (CHECK_MUNLOCK(ptr, size)) { | |||
if (CHECK_MUNLOCK((char*)ptr, size)) { | |||
jack_log("Succeeded in unlocking %u byte memory area", size); | |||
} else { | |||
jack_error("Cannot unlock down memory area (%s)", strerror(errno)); | |||
@@ -35,7 +35,10 @@ namespace Jack | |||
{ | |||
SERVER_EXPORT void LockMemoryImp(void* ptr, size_t size); | |||
SERVER_EXPORT void InitLockMemoryImp(void* ptr, size_t size); | |||
SERVER_EXPORT void UnlockMemoryImp(void* ptr, size_t size); | |||
SERVER_EXPORT void LockAllMemory(); | |||
SERVER_EXPORT void UnlockAllMemory(); | |||
class JackMem | |||
{ | |||
@@ -28,6 +28,7 @@ | |||
#include <process.h> | |||
#endif | |||
using namespace std; | |||
namespace Jack { | |||
@@ -38,7 +39,7 @@ namespace Jack { | |||
int JackTools::GetPID() | |||
{ | |||
#ifdef WIN32 | |||
return _getpid(); | |||
return _getpid(); | |||
#else | |||
return getpid(); | |||
#endif | |||
@@ -26,9 +26,12 @@ | |||
#define __jack_jslist_h__ | |||
#include <stdlib.h> | |||
#include <jack/systemdeps.h> | |||
#ifdef sun | |||
#define __inline__ | |||
#endif | |||
typedef struct _JSList JSList; | |||
typedef int (*JCompareFunc) (void* a, void* b); | |||
@@ -29,8 +29,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
#include <sys/types.h> | |||
#else | |||
#define __inline__ inline | |||
//#define vsnprintf _vsnprintf | |||
//#define snprintf _snprintf | |||
typedef char int8_t; | |||
typedef unsigned char uint8_t; | |||
typedef short int16_t; | |||
@@ -44,7 +42,7 @@ typedef HANDLE pthread_t; | |||
typedef int64_t _jack_time_t; | |||
#endif // WIN32 */ | |||
#if defined(__APPLE__) || defined(__linux__) | |||
#if defined(__APPLE__) || defined(__linux__) || defined(__sun__) || defined(sun) | |||
#include <inttypes.h> | |||
#include <pthread.h> | |||
@@ -30,10 +30,15 @@ | |||
#include <stdlib.h> | |||
#include <stdint.h> | |||
#include <limits.h> | |||
#ifdef __linux__ | |||
#include <endian.h> | |||
#endif | |||
#include "memops.h" | |||
#if defined (__SSE2__) && !defined (__sun__) | |||
#include <emmintrin.h> | |||
#endif | |||
/* Notes about these *_SCALING values. | |||
the MAX_<N>BIT values are floating point. when multiplied by | |||
@@ -162,15 +167,13 @@ | |||
/* Linear Congruential noise generator. From the music-dsp list | |||
* less random than rand(), but good enough and 10x faster | |||
*/ | |||
static unsigned int seed = 22222; | |||
inline unsigned int fast_rand() { | |||
static unsigned int seed = 22222; | |||
seed = (seed * 96314165) + 907633515; | |||
return seed; | |||
} | |||
/* functions for native float sample data */ | |||
void sample_move_floatLE_sSs (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) { | |||
@@ -222,7 +225,6 @@ void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsign | |||
float_24u32 (*src, z); | |||
#if __BYTE_ORDER == __LITTLE_ENDIAN | |||
dst[0]=(char)(z>>24); | |||
dst[1]=(char)(z>>16); | |||
@@ -241,11 +243,57 @@ void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsign | |||
void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | |||
{ | |||
#if defined (__SSE2__) && !defined (__sun__) | |||
__m128 int_max = _mm_set1_ps(SAMPLE_24BIT_MAX_F); | |||
__m128 int_min = _mm_sub_ps(_mm_setzero_ps(), int_max); | |||
__m128 factor = int_max; | |||
unsigned long unrolled = nsamples / 4; | |||
nsamples = nsamples & 3; | |||
while (unrolled--) { | |||
__m128 in = _mm_load_ps(src); | |||
__m128 scaled = _mm_mul_ps(in, factor); | |||
__m128 clipped = _mm_min_ps(int_max, _mm_max_ps(scaled, int_min)); | |||
__m128i y = _mm_cvttps_epi32(clipped); | |||
__m128i shifted = _mm_slli_epi32(y, 8); | |||
__m128i shuffled1 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(0, 3, 2, 1)); | |||
__m128i shuffled2 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(1, 0, 3, 2)); | |||
__m128i shuffled3 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(2, 1, 0, 3)); | |||
_mm_store_ss((float*)dst, (__m128)shifted); | |||
dst += dst_skip; | |||
_mm_store_ss((float*)dst, (__m128)shuffled1); | |||
dst += dst_skip; | |||
_mm_store_ss((float*)dst, (__m128)shuffled2); | |||
dst += dst_skip; | |||
_mm_store_ss((float*)dst, (__m128)shuffled3); | |||
dst += dst_skip; | |||
src+= 4; | |||
} | |||
while (nsamples--) { | |||
__m128 in = _mm_load_ss(src); | |||
__m128 scaled = _mm_mul_ss(in, factor); | |||
__m128 clipped = _mm_min_ss(int_max, _mm_max_ss(scaled, int_min)); | |||
int y = _mm_cvttss_si32(clipped); | |||
*((int *) dst) = y<<8; | |||
dst += dst_skip; | |||
src++; | |||
} | |||
#else | |||
while (nsamples--) { | |||
float_24u32 (*src, *((int32_t*) dst)); | |||
dst += dst_skip; | |||
src++; | |||
} | |||
#endif | |||
} | |||
void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) | |||
@@ -279,6 +327,34 @@ void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsign | |||
void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) | |||
{ | |||
#if defined (__SSE2__) && !defined (__sun__) | |||
unsigned long unrolled = nsamples / 4; | |||
static float inv_sample_max_24bit = 1.0 / SAMPLE_24BIT_SCALING; | |||
__m128 factor = _mm_set1_ps(inv_sample_max_24bit); | |||
while (unrolled--) | |||
{ | |||
int i1 = *((int *) src); | |||
src+= src_skip; | |||
int i2 = *((int *) src); | |||
src+= src_skip; | |||
int i3 = *((int *) src); | |||
src+= src_skip; | |||
int i4 = *((int *) src); | |||
src+= src_skip; | |||
__m128i src = _mm_set_epi32(i1, i2, i3, i4); | |||
__m128i shifted = _mm_srai_epi32(src, 8); | |||
__m128 as_float = _mm_cvtepi32_ps(shifted); | |||
__m128 divided = _mm_mul_ps(as_float, factor); | |||
_mm_storeu_ps(dst, divided); | |||
dst += 4; | |||
} | |||
nsamples = nsamples & 3; | |||
#endif | |||
/* ALERT: signed sign-extension portability !!! */ | |||
while (nsamples--) { | |||
@@ -579,7 +655,6 @@ void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned | |||
} | |||
void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) | |||
{ | |||
/* ALERT: signed sign-extension portability !!! */ | |||
while (nsamples--) { | |||
@@ -652,7 +727,6 @@ memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, | |||
void | |||
memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, | |||
unsigned long dst_skip_bytes, unsigned long src_skip_bytes) | |||
{ | |||
while (src_bytes) { | |||
memcpy(dst, src, 3); | |||
@@ -665,7 +739,6 @@ memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, | |||
void | |||
memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, | |||
unsigned long dst_skip_bytes, unsigned long src_skip_bytes) | |||
{ | |||
while (src_bytes) { | |||
*((int *) dst) = *((int *) src); |
@@ -27,6 +27,10 @@ extern "C" | |||
{ | |||
#endif | |||
#ifdef sun | |||
#define __inline__ | |||
#endif | |||
typedef enum { | |||
None, | |||
Rectangular, | |||
@@ -87,7 +91,6 @@ void sample_merge_d32u24_sS (char *dst, jack_default_audio_sample_t *sr | |||
static __inline__ void | |||
sample_merge (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt) | |||
{ | |||
while (cnt--) { | |||
*dst += *src; | |||
@@ -98,7 +101,6 @@ sample_merge (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src | |||
static __inline__ void | |||
sample_memcpy (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt) | |||
{ | |||
memcpy (dst, src, cnt * sizeof (jack_default_audio_sample_t)); | |||
} |
@@ -28,6 +28,10 @@ extern "C" | |||
*/ | |||
#ifdef USE_POSIX_SHM | |||
#ifndef NAME_MAX | |||
#define NAME_MAX 255 | |||
#endif | |||
#ifndef SHM_NAME_MAX | |||
#define SHM_NAME_MAX NAME_MAX | |||
#endif | |||
@@ -21,15 +21,18 @@ def create_jack_process_obj(bld, target, sources, uselib = None): | |||
env_includes = ['../macosx', '../posix', '../macosx/coreaudio'] | |||
if bld.env['IS_LINUX']: | |||
env_includes = ['../linux', '../posix', '../linux/alsa'] | |||
if bld.env['IS_SUN']: | |||
env_includes = ['../solaris', '../posix', '../solaris/oss'] | |||
process.includes = ['.'] + env_includes + ['jack', '..'] | |||
process.name = target | |||
process.target = target | |||
process.source = sources | |||
process.env.append_value("CPPFLAGS", "-fvisibility=hidden") | |||
if bld.env['IS_LINUX']: | |||
process.env.append_value("CPPFLAGS", "-fvisibility=hidden") | |||
if bld.env['IS_MACOSX']: | |||
process.env.append_value("CPPFLAGS", "-mmacosx-version-min=10.4 -arch i386 -arch ppc") | |||
#process.env.append_value("LINKFLAGS", "-arch i386 -arch ppc") | |||
process.env.append_value("LINKFLAGS", "") | |||
process.env.append_value("CPPFLAGS", "-fvisibility=hidden") | |||
process.install_path = '${ADDON_DIR}/' | |||
process.uselib_local = uselib.name | |||
return process | |||
@@ -58,6 +61,7 @@ def build(bld): | |||
'timestamps.c', | |||
'JackTools.cpp', | |||
'JackMessageBuffer.cpp', | |||
'JackEngineProfiling.cpp', | |||
] | |||
includes = ['.', './jack', '..'] | |||
@@ -70,12 +74,23 @@ def build(bld): | |||
'../posix/JackFifo.cpp', | |||
'../posix/JackProcessSync.cpp', | |||
'../posix/JackSocket.cpp', | |||
'../linux/JackLinuxTime.c', | |||
'../linux/JackLinuxTime.c', | |||
] | |||
includes = ['../linux', '../posix'] + includes | |||
uselib.append('RT') | |||
uselib.append('DL') | |||
if bld.env['IS_SUN']: | |||
common_libsources += [ | |||
'../posix/JackPosixThread.cpp', | |||
'../posix/JackFifo.cpp', | |||
'../posix/JackProcessSync.cpp', | |||
'../posix/JackSocket.cpp', | |||
'../solaris/JackSolarisTime.c', | |||
] | |||
includes = ['../solaris', '../posix'] + includes | |||
uselib.append('RT') | |||
if bld.env['IS_MACOSX']: | |||
common_libsources += [ | |||
'../posix/JackProcessSync.cpp', | |||
@@ -83,7 +98,7 @@ def build(bld): | |||
'../macosx/JackMachThread.cpp', | |||
'../macosx/JackMachSemaphore.cpp', | |||
'../macosx/JackMachPort.cpp', | |||
'../macosx/JackMachTime.c', | |||
'../macosx/JackMachTime.c', | |||
] | |||
includes = ['../macosx', '../macosx/RPC', '../posix'] + includes | |||
@@ -125,6 +140,14 @@ def build(bld): | |||
'../posix/JackNetUnixSocket.cpp', | |||
] | |||
if bld.env['IS_SUN']: | |||
serverlib.source += [ | |||
'../posix/JackSocketServerChannel.cpp', | |||
'../posix/JackSocketNotifyChannel.cpp', | |||
'../posix/JackSocketServerNotifyChannel.cpp', | |||
'../posix/JackNetUnixSocket.cpp', | |||
] | |||
if bld.env['IS_MACOSX']: | |||
serverlib.source += [ | |||
'../macosx/JackMachServerChannel.cpp', | |||
@@ -136,12 +159,19 @@ def build(bld): | |||
] | |||
serverlib.vnum = bld.env['JACK_API_VERSION'] | |||
serverlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") | |||
if bld.env['IS_LINUX']: | |||
serverlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") | |||
if bld.env['IS_MACOSX']: | |||
serverlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") | |||
serverlib.env.append_value("CPPFLAGS", "-mmacosx-version-min=10.4 -arch i386 -arch ppc") | |||
#serverlib.env.append_value("LINKFLAGS", "-framework CoreAudio -framework vecLib -single_module -arch i386 -arch ppc") | |||
serverlib.env.append_value("LINKFLAGS", "-framework CoreAudio -framework vecLib -single_module") | |||
serverlib.env.append_value("LINKFLAGS", "-compatibility_version 1 -current_version 1") | |||
serverlib.env.append_value("LINKFLAGS", "-compatibility_version 1 -current_version 1") | |||
if bld.env['IS_SUN']: | |||
serverlib.env.append_value("LINKFLAGS", "-lnsl -lsocket") | |||
clientlib = bld.new_task_gen('cxx', 'shlib') | |||
clientlib.features.append('cc') | |||
@@ -165,6 +195,12 @@ def build(bld): | |||
'../posix/JackPosixServerLaunch.cpp', | |||
] | |||
if bld.env['IS_SUN']: | |||
clientlib.source += [ | |||
'../posix/JackSocketClientChannel.cpp', | |||
'../posix/JackPosixServerLaunch.cpp', | |||
] | |||
if bld.env['IS_MACOSX']: | |||
clientlib.source += [ | |||
'../macosx/JackMachClientChannel.cpp', | |||
@@ -174,15 +210,24 @@ def build(bld): | |||
] | |||
clientlib.vnum = bld.env['JACK_API_VERSION'] | |||
clientlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") | |||
if bld.env['IS_LINUX']: | |||
clientlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") | |||
if bld.env['IS_MACOSX']: | |||
clientlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") | |||
clientlib.env.append_value("CPPFLAGS", "-mmacosx-version-min=10.4 -arch i386 -arch ppc") | |||
#clientlib.env.append_value("LINKFLAGS", "-framework CoreAudio -framework vecLib -single_module -arch i386 -arch ppc") | |||
clientlib.env.append_value("LINKFLAGS", "-framework CoreAudio -framework vecLib -single_module") | |||
#clientlib.env.append_value("LINKFLAGS", "-framework CoreAudio -framework vecLib -single_module -arch i386 -arch ppc" | |||
clientlib.env.append_value("LINKFLAGS", "-framework CoreAudio -framework vecLib -single_module") | |||
clientlib.env.append_value("LINKFLAGS", "-compatibility_version 1 -current_version 1") | |||
if bld.env['IS_SUN']: | |||
clientlib.env.append_value("LINKFLAGS", "-lnsl -lsocket") | |||
create_jack_process_obj(bld, 'netmanager', 'JackNetManager.cpp', serverlib) | |||
create_jack_process_obj(bld, 'profiler', 'JackProfiler.cpp', serverlib) | |||
net_adapter_sources = [ | |||
'JackResampler.cpp', | |||
'JackLibSampleRateResampler.cpp', | |||
@@ -201,7 +246,7 @@ def build(bld): | |||
'JackAudioAdapter.cpp', | |||
'JackAudioAdapterInterface.cpp', | |||
'JackAudioAdapterFactory.cpp', | |||
] | |||
] | |||
if bld.env['BUILD_ADAPTER'] and bld.env['IS_MACOSX']: | |||
audio_adapter_sources += ['../macosx/coreaudio/JackCoreAudioAdapter.cpp'] | |||
@@ -214,6 +259,11 @@ def build(bld): | |||
process = create_jack_process_obj(bld, 'audioadapter', audio_adapter_sources, serverlib) | |||
process.uselib = ['ALSA', 'SAMPLERATE'] | |||
if bld.env['BUILD_ADAPTER'] and bld.env['IS_SUN']: | |||
audio_adapter_sources += ['../solaris/oss/JackOSSAdapter.cpp', 'memops.c'] | |||
process = create_jack_process_obj(bld, 'audioadapter', audio_adapter_sources, serverlib) | |||
process.uselib = 'SAMPLERATE' | |||
#audio_adapter_sources += ['../windows/JackPortAudioAdapter.cpp'] | |||
#process = create_jack_process_obj(bld, 'audioadapter', audio_adapter_sources, serverlib) | |||
@@ -0,0 +1,92 @@ | |||
/** @file cpu_load.c | |||
* | |||
*/ | |||
#include <stdio.h> | |||
#include <errno.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <math.h> | |||
#include <signal.h> | |||
#ifndef WIN32 | |||
#include <unistd.h> | |||
#endif | |||
#include <jack/jack.h> | |||
jack_client_t *client; | |||
static void signal_handler ( int sig ) | |||
{ | |||
jack_client_close ( client ); | |||
fprintf ( stderr, "signal received, exiting ...\n" ); | |||
exit ( 0 ); | |||
} | |||
/** | |||
* JACK calls this shutdown_callback if the server ever shuts down or | |||
* decides to disconnect the client. | |||
*/ | |||
void | |||
jack_shutdown ( void *arg ) | |||
{ | |||
exit ( 1 ); | |||
} | |||
int | |||
main ( int argc, char *argv[] ) | |||
{ | |||
jack_options_t options = JackNullOption; | |||
jack_status_t status; | |||
/* open a client connection to the JACK server */ | |||
client = jack_client_open ("jack_cpu_load", options, &status); | |||
if ( client == NULL ) | |||
{ | |||
fprintf ( stderr, "jack_client_open() failed, " | |||
"status = 0x%2.0x\n", status ); | |||
if ( status & JackServerFailed ) | |||
{ | |||
fprintf ( stderr, "Unable to connect to JACK server\n" ); | |||
} | |||
exit ( 1 ); | |||
} | |||
jack_on_shutdown ( client, jack_shutdown, 0 ); | |||
/* Tell the JACK server that we are ready to roll. Our | |||
* process() callback will start running now. */ | |||
if ( jack_activate ( client ) ) | |||
{ | |||
fprintf ( stderr, "cannot activate client" ); | |||
exit ( 1 ); | |||
} | |||
/* install a signal handler to properly quits jack client */ | |||
#ifdef WIN32 | |||
signal ( SIGINT, signal_handler ); | |||
signal ( SIGABRT, signal_handler ); | |||
signal ( SIGTERM, signal_handler ); | |||
#else | |||
signal ( SIGQUIT, signal_handler ); | |||
signal ( SIGTERM, signal_handler ); | |||
signal ( SIGHUP, signal_handler ); | |||
signal ( SIGINT, signal_handler ); | |||
#endif | |||
while (1) | |||
{ | |||
printf("jack DSP load %f\n", jack_cpu_load(client)); | |||
#ifdef WIN32 | |||
Sleep ( 1000 ); | |||
#else | |||
sleep ( 1 ); | |||
#endif | |||
} | |||
jack_client_close ( client ); | |||
exit ( 0 ); | |||
} |
@@ -53,8 +53,8 @@ process (jack_nframes_t nframes, void *arg) | |||
paTestData *data = (paTestData*)arg; | |||
int i; | |||
out1 = jack_port_get_buffer (output_port1, nframes); | |||
out2 = jack_port_get_buffer (output_port2, nframes); | |||
out1 = (jack_default_audio_sample_t*)jack_port_get_buffer (output_port1, nframes); | |||
out2 = (jack_default_audio_sample_t*)jack_port_get_buffer (output_port2, nframes); | |||
for( i=0; i<nframes; i++ ) | |||
{ | |||
@@ -94,7 +94,8 @@ main (int argc, char *argv[]) | |||
client_name = argv[1]; | |||
if (argc >= 3) { /* server name specified? */ | |||
server_name = argv[2]; | |||
options |= JackServerName; | |||
int my_option = JackNullOption | JackServerName; | |||
options = (jack_options_t)my_option; | |||
} | |||
} else { /* use basename of argv[0] */ | |||
client_name = strrchr(argv[0], '/'); | |||
@@ -19,6 +19,7 @@ example_programs = { | |||
'jack_evmon' : 'evmon.c', | |||
'jack_monitor_client' : 'monitor_client.c', | |||
'jack_thru' : 'thru_client.c', | |||
'jack_cpu_load' : 'cpu_load.c', | |||
'jack_server_control' : 'server_control.cpp', | |||
} | |||
@@ -51,6 +52,8 @@ def build(bld): | |||
os_incdir = ['../linux', '../posix'] | |||
if bld.env['IS_MACOSX']: | |||
os_incdir = ['../macosx', '../posix'] | |||
if bld.env['IS_SUN']: | |||
os_incdir = ['../solaris', '../posix'] | |||
for example_program, example_program_source in example_programs.items(): | |||
prog = bld.new_task_gen('cxx', 'program') | |||
prog.features.append('cc') | |||
@@ -62,6 +65,8 @@ def build(bld): | |||
prog.env.append_value("LINKFLAGS", "") | |||
if bld.env['IS_LINUX']: | |||
prog.uselib = 'RT' | |||
if bld.env['IS_SUN']: | |||
prog.env.append_value("LINKFLAGS", "-lm") | |||
if example_program == 'jack_server_control': | |||
prog.uselib_local = 'serverlib' | |||
else: | |||
@@ -92,10 +97,9 @@ def build(bld): | |||
prog.env.append_value("CPPFLAGS", "-mmacosx-version-min=10.4 -arch i386 -arch ppc") | |||
#prog.env.append_value("LINKFLAGS", "-arch i386 -arch ppc") | |||
prog.env.append_value("LINKFLAGS", "") | |||
prog.uselib = 'SNDFILE' | |||
if bld.env['IS_LINUX']: | |||
prog.uselib = 'RT SNDFILE' | |||
if bld.env['IS_MACOSX']: | |||
prog.uselib = 'SNDFILE' | |||
prog.uselib_local = 'clientlib' | |||
prog.target = 'jack_rec' | |||
@@ -109,6 +113,8 @@ def build(bld): | |||
lib.env.append_value("CPPFLAGS", "-mmacosx-version-min=10.4 -arch i386 -arch ppc") | |||
#lib.env.append_value("LINKFLAGS", "-arch i386 -arch ppc") | |||
lib.env.append_value("LINKFLAGS", "") | |||
if bld.env['IS_SUN']: | |||
lib.env.append_value("LINKFLAGS", "-lm") | |||
lib.uselib_local = 'serverlib' | |||
lib.install_path = '${ADDON_DIR}/' | |||
@@ -40,7 +40,7 @@ def build(bld): | |||
'alsa/alsa_rawmidi.c', | |||
'alsa/alsa_seqmidi.c', | |||
'alsa/alsa_midi_jackmp.cpp', | |||
'alsa/memops.c', | |||
'../common/memops.c', | |||
'alsa/generic_hw.c', | |||
'alsa/hdsp.c', | |||
'alsa/hammerfall.c', | |||
@@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
#include <mach/mach_time.h> | |||
#include <unistd.h> | |||
double __jack_time_ratio; | |||
static double __jack_time_ratio; | |||
SERVER_EXPORT void JackSleep(long usec) | |||
{ | |||
@@ -481,8 +481,6 @@ | |||
4B80D7EB0BA0D17400F035BB /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; | |||
4B80D7EC0BA0D17400F035BB /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; | |||
4B80D7ED0BA0D17400F035BB /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; | |||
4B8F3D4B0E06C4A10096D19C /* JackEngineTiming.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8F3D490E06C4A10096D19C /* JackEngineTiming.cpp */; }; | |||
4B8F3D4C0E06C4A10096D19C /* JackEngineTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B8F3D4A0E06C4A10096D19C /* JackEngineTiming.h */; }; | |||
4B93F1990E87992100E4ECCD /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; | |||
4B93F19A0E87992200E4ECCD /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; | |||
4B93F19B0E87992300E4ECCD /* JackProcessSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AA0E703B690066E42F /* JackProcessSync.cpp */; }; | |||
@@ -512,11 +510,11 @@ | |||
4BA7BDD00DC22F4500AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BA7BDCB0DC22F4500AA3457 /* Jackservermp.framework */; }; | |||
4BA7BDD10DC22F4500AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BA7BDCB0DC22F4500AA3457 /* Jackservermp.framework */; }; | |||
4BA7BDD20DC22F4500AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BA7BDCB0DC22F4500AA3457 /* Jackservermp.framework */; }; | |||
4BA7BE0F0DC232A400AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; | |||
4BA7BE1A0DC2347500AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; | |||
4BA7BE200DC234FB00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; | |||
4BA7BE240DC2350D00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; | |||
4BA7BE270DC2352A00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; }; | |||
4BA7BE0F0DC232A400AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; | |||
4BA7BE1A0DC2347500AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; | |||
4BA7BE200DC234FB00AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; | |||
4BA7BE240DC2350D00AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; | |||
4BA7BE270DC2352A00AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; }; | |||
4BA7FECA0D8E76650017FF73 /* control.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA7FEC80D8E76650017FF73 /* control.c */; }; | |||
4BAB95B80B9E20B800A0C723 /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; | |||
4BAB95B90B9E20B800A0C723 /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; | |||
@@ -527,6 +525,10 @@ | |||
4BB9D4B30E2610B300351653 /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; | |||
4BB9D4B40E2610B400351653 /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; | |||
4BB9D4E40E26112900351653 /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; }; | |||
4BBAE4100F42FA6100B8BD3F /* JackEngineProfiling.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBAE40E0F42FA6100B8BD3F /* JackEngineProfiling.h */; }; | |||
4BBAE4110F42FA6100B8BD3F /* JackEngineProfiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAE40F0F42FA6100B8BD3F /* JackEngineProfiling.cpp */; }; | |||
4BBAE4120F42FA6100B8BD3F /* JackEngineProfiling.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBAE40E0F42FA6100B8BD3F /* JackEngineProfiling.h */; }; | |||
4BBAE4130F42FA6100B8BD3F /* JackEngineProfiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAE40F0F42FA6100B8BD3F /* JackEngineProfiling.cpp */; }; | |||
4BBB00D30E72614F0018AB1B /* JackPortAudioDevices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB00CF0E72614F0018AB1B /* JackPortAudioDevices.cpp */; }; | |||
4BBB00D40E72614F0018AB1B /* JackPortAudioDevices.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBB00D00E72614F0018AB1B /* JackPortAudioDevices.h */; }; | |||
4BBB00D50E72614F0018AB1B /* JackPortAudioDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB00D10E72614F0018AB1B /* JackPortAudioDriver.cpp */; }; | |||
@@ -1127,8 +1129,6 @@ | |||
4B05A05D0DF72BC000840F4C /* JackAlsaDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackAlsaDriver.cpp; path = ../linux/alsa/JackAlsaDriver.cpp; sourceTree = SOURCE_ROOT; }; | |||
4B05A05E0DF72BC000840F4C /* JackAlsaDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackAlsaDriver.h; path = ../linux/alsa/JackAlsaDriver.h; sourceTree = SOURCE_ROOT; }; | |||
4B05A05F0DF72BC000840F4C /* jslist.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jslist.h; path = ../linux/alsa/jslist.h; sourceTree = SOURCE_ROOT; }; | |||
4B05A0600DF72BC000840F4C /* memops.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = memops.c; path = ../linux/alsa/memops.c; sourceTree = SOURCE_ROOT; }; | |||
4B05A0610DF72BC000840F4C /* memops.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = memops.h; path = ../linux/alsa/memops.h; sourceTree = SOURCE_ROOT; }; | |||
4B05A0620DF72BC000840F4C /* midi_pack.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = midi_pack.h; path = ../linux/alsa/midi_pack.h; sourceTree = SOURCE_ROOT; }; | |||
4B05A0630DF72BC000840F4C /* midi_unpack.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = midi_unpack.h; path = ../linux/alsa/midi_unpack.h; sourceTree = SOURCE_ROOT; }; | |||
4B05A0640DF72BC000840F4C /* usx2y.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = usx2y.c; path = ../linux/alsa/usx2y.c; sourceTree = SOURCE_ROOT; }; | |||
@@ -1161,7 +1161,7 @@ | |||
4B0A28E60D52073D002EFF74 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B0A28EC0D520852002EFF74 /* tw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tw.c; path = "../example-clients/tw.c"; sourceTree = SOURCE_ROOT; }; | |||
4B0A292D0D52108E002EFF74 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B19B3000E23620F00DD4A82 /* audioadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = audioadapter.so; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B19B3000E23620F00DD4A82 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapter.cpp; path = ../common/JackAudioAdapter.cpp; sourceTree = SOURCE_ROOT; }; | |||
4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapter.h; path = ../common/JackAudioAdapter.h; sourceTree = SOURCE_ROOT; }; | |||
4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; | |||
@@ -1173,7 +1173,7 @@ | |||
4B2C28F908DAD01E00249230 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; | |||
4B35C4250D4731D1000DE7AE /* jackdmp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jackdmp; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B35C4830D4731D1000DE7AE /* Jackmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackservermp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackdmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B35C5140D4731D1000DE7AE /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B35C5200D4731D1000DE7AE /* jack_midisine */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midisine; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B35C52C0D4731D1000DE7AE /* jack_metro */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_metro; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
@@ -1197,19 +1197,19 @@ | |||
4B35C6290D4731D2000DE7AE /* jack_portaudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_portaudio.so; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B35C6340D4731D2000DE7AE /* jack_dummy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_dummy.so; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B35C63E0D4731D3000DE7AE /* inprocess.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = inprocess.so; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363DD80DEB02F6001F72D9 /* jack_alias */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_alias; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363DD80DEB02F6001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363DDE0DEB034E001F72D9 /* alias.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = alias.c; path = "../example-clients/alias.c"; sourceTree = SOURCE_ROOT; }; | |||
4B363E1A0DEB03C5001F72D9 /* jack_evmon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_evmon; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363E1A0DEB03C5001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363E200DEB0401001F72D9 /* evmon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = evmon.c; path = "../example-clients/evmon.c"; sourceTree = SOURCE_ROOT; }; | |||
4B363E4E0DEB0775001F72D9 /* jack_bufsize */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_bufsize; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363E4E0DEB0775001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363E710DEB0808001F72D9 /* bufsize.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bufsize.c; path = "../example-clients/bufsize.c"; sourceTree = SOURCE_ROOT; }; | |||
4B363EE90DEB091C001F72D9 /* jack_rec */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_rec; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363EE90DEB091C001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363EED0DEB094B001F72D9 /* capture_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = capture_client.c; path = "../example-clients/capture_client.c"; sourceTree = SOURCE_ROOT; }; | |||
4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_monitor_client; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363F1E0DEB0A6A001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363F220DEB0AB0001F72D9 /* monitor_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = monitor_client.c; path = "../example-clients/monitor_client.c"; sourceTree = SOURCE_ROOT; }; | |||
4B363F350DEB0BD1001F72D9 /* jack_showtime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_showtime; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363F350DEB0BD1001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363F3D0DEB0C31001F72D9 /* showtime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = showtime.c; path = "../example-clients/showtime.c"; sourceTree = SOURCE_ROOT; }; | |||
4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_impulse_grabber; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363F720DEB0D4E001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = impulse_grabber.c; path = "../example-clients/impulse_grabber.c"; sourceTree = SOURCE_ROOT; }; | |||
4B37C20306DF1FBE0016E567 /* CALatencyLog.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CALatencyLog.cpp; path = /Developer/Examples/CoreAudio/PublicUtility/CALatencyLog.cpp; sourceTree = "<absolute>"; }; | |||
4B37C20406DF1FBE0016E567 /* CALatencyLog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CALatencyLog.h; path = /Developer/Examples/CoreAudio/PublicUtility/CALatencyLog.h; sourceTree = "<absolute>"; }; | |||
@@ -1228,7 +1228,7 @@ | |||
4B5A1BBD0CD1CC110005BF74 /* midiseq.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = midiseq.c; path = "../example-clients/midiseq.c"; sourceTree = SOURCE_ROOT; }; | |||
4B5A1BDA0CD1CCE10005BF74 /* jack_midisine */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midisine; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B5A1BDC0CD1CD420005BF74 /* midisine.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = midisine.c; path = "../example-clients/midisine.c"; sourceTree = SOURCE_ROOT; }; | |||
4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netadapter.so; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B5E08D50E5B66EE00BEE4E0 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4B5E08DF0E5B676C00BEE4E0 /* JackNetAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetAdapter.cpp; path = ../common/JackNetAdapter.cpp; sourceTree = SOURCE_ROOT; }; | |||
4B5E08E00E5B676C00BEE4E0 /* JackNetAdapter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackNetAdapter.h; path = ../common/JackNetAdapter.h; sourceTree = SOURCE_ROOT; }; | |||
4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLockedEngine.h; path = ../common/JackLockedEngine.h; sourceTree = SOURCE_ROOT; }; | |||
@@ -1272,8 +1272,6 @@ | |||
4B869D7F08C9CB00001CF041 /* JackDriverLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackDriverLoader.cpp; path = ../common/JackDriverLoader.cpp; sourceTree = SOURCE_ROOT; }; | |||
4B89B759076B731100D170DE /* JackRPCClientUser.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = JackRPCClientUser.c; path = RPC/JackRPCClientUser.c; sourceTree = SOURCE_ROOT; }; | |||
4B89B769076B74D200D170DE /* JackRPCEngineUser.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = JackRPCEngineUser.c; path = RPC/JackRPCEngineUser.c; sourceTree = SOURCE_ROOT; }; | |||
4B8F3D490E06C4A10096D19C /* JackEngineTiming.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackEngineTiming.cpp; path = ../common/JackEngineTiming.cpp; sourceTree = SOURCE_ROOT; }; | |||
4B8F3D4A0E06C4A10096D19C /* JackEngineTiming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackEngineTiming.h; path = ../common/JackEngineTiming.h; sourceTree = SOURCE_ROOT; }; | |||
4B940B9B06DDDE5B00D77F60 /* AudioHardware.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AudioHardware.h; path = /System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/AudioHardware.h; sourceTree = "<absolute>"; }; | |||
4B95BCAD0D913073000F7695 /* control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = control.h; path = ../common/jack/control.h; sourceTree = SOURCE_ROOT; }; | |||
4B978DBB0A31CF4A009E2DD1 /* jack_portaudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_portaudio.so; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
@@ -1288,12 +1286,14 @@ | |||
4BA692D40CBE4C9000EAD520 /* jack_unload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_unload; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BA692D60CBE4CC600EAD520 /* ipunload.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ipunload.c; path = "../example-clients/ipunload.c"; sourceTree = SOURCE_ROOT; }; | |||
4BA7BDCB0DC22F4500AA3457 /* Jackservermp.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Jackservermp.framework; path = build/Development/Jackservermp.framework; sourceTree = SOURCE_ROOT; }; | |||
4BA7FEC30D8E76270017FF73 /* jack_server_control */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_server_control; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BA7FEC30D8E76270017FF73 /* jack_lsp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_lsp; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BA7FEC80D8E76650017FF73 /* control.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = control.c; path = "../example-clients/control.c"; sourceTree = SOURCE_ROOT; }; | |||
4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackPortType.cpp; path = ../common/JackPortType.cpp; sourceTree = SOURCE_ROOT; }; | |||
4BAB95B70B9E20B800A0C723 /* JackPortType.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackPortType.h; path = ../common/JackPortType.h; sourceTree = SOURCE_ROOT; }; | |||
4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioPort.cpp; path = ../common/JackAudioPort.cpp; sourceTree = SOURCE_ROOT; }; | |||
4BB371D40C1AD85A0050C1E4 /* JackNotification.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackNotification.h; path = ../common/JackNotification.h; sourceTree = SOURCE_ROOT; }; | |||
4BBAE40E0F42FA6100B8BD3F /* JackEngineProfiling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackEngineProfiling.h; path = ../common/JackEngineProfiling.h; sourceTree = SOURCE_ROOT; }; | |||
4BBAE40F0F42FA6100B8BD3F /* JackEngineProfiling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackEngineProfiling.cpp; path = ../common/JackEngineProfiling.cpp; sourceTree = SOURCE_ROOT; }; | |||
4BBB00CF0E72614F0018AB1B /* JackPortAudioDevices.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackPortAudioDevices.cpp; path = ../windows/portaudio/JackPortAudioDevices.cpp; sourceTree = SOURCE_ROOT; }; | |||
4BBB00D00E72614F0018AB1B /* JackPortAudioDevices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackPortAudioDevices.h; path = ../windows/portaudio/JackPortAudioDevices.h; sourceTree = SOURCE_ROOT; }; | |||
4BBB00D10E72614F0018AB1B /* JackPortAudioDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackPortAudioDriver.cpp; path = ../windows/portaudio/JackPortAudioDriver.cpp; sourceTree = SOURCE_ROOT; }; | |||
@@ -1405,14 +1405,14 @@ | |||
4BF8D2470834F20600C94B91 /* testSem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSem.cpp; path = ../tests/testSem.cpp; sourceTree = SOURCE_ROOT; }; | |||
4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackFrameTimer.cpp; path = ../common/JackFrameTimer.cpp; sourceTree = SOURCE_ROOT; }; | |||
4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFrameTimer.h; path = ../common/JackFrameTimer.h; sourceTree = SOURCE_ROOT; }; | |||
4BFA5E980DEC4D9C00FA4CDB /* testMutex */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testMutex; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA5E980DEC4D9C00FA4CDB /* testSem */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testSem; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA5E9E0DEC4DD900FA4CDB /* testMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testMutex.cpp; path = ../tests/testMutex.cpp; sourceTree = SOURCE_ROOT; }; | |||
4BFA828C0DF6A9E40087B4E1 /* jack_evmon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_evmon; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_bufsize; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA82AB0DF6A9E40087B4E1 /* jack_rec */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_rec; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_monitor_client; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA82C30DF6A9E40087B4E1 /* jack_showtime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_showtime; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_impulse_grabber; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA828C0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA829F0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA82AB0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA82B70DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA82C30DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA82CF0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA99A20AAAF3B0009E916C /* jdelay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jdelay; sourceTree = BUILT_PRODUCTS_DIR; }; | |||
4BFA99A90AAAF40C009E916C /* jdelay.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = jdelay.cpp; path = ../tests/jdelay.cpp; sourceTree = SOURCE_ROOT; }; | |||
4BFB297708AF44ED00D450D4 /* JackMachServerNotifyChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachServerNotifyChannel.cpp; sourceTree = "<group>"; }; | |||
@@ -1550,7 +1550,7 @@ | |||
isa = PBXFrameworksBuildPhase; | |||
buildActionMask = 2147483647; | |||
files = ( | |||
4BA7BE0F0DC232A400AA3457 /* Jackservermp.framework in Frameworks */, | |||
4BA7BE0F0DC232A400AA3457 /* Jackdmp.framework in Frameworks */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -1558,7 +1558,7 @@ | |||
isa = PBXFrameworksBuildPhase; | |||
buildActionMask = 2147483647; | |||
files = ( | |||
4BA7BE1A0DC2347500AA3457 /* Jackservermp.framework in Frameworks */, | |||
4BA7BE1A0DC2347500AA3457 /* Jackdmp.framework in Frameworks */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -1601,7 +1601,7 @@ | |||
isa = PBXFrameworksBuildPhase; | |||
buildActionMask = 2147483647; | |||
files = ( | |||
4BA7BE200DC234FB00AA3457 /* Jackservermp.framework in Frameworks */, | |||
4BA7BE200DC234FB00AA3457 /* Jackdmp.framework in Frameworks */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -1609,7 +1609,7 @@ | |||
isa = PBXFrameworksBuildPhase; | |||
buildActionMask = 2147483647; | |||
files = ( | |||
4BA7BE240DC2350D00AA3457 /* Jackservermp.framework in Frameworks */, | |||
4BA7BE240DC2350D00AA3457 /* Jackdmp.framework in Frameworks */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -1617,7 +1617,7 @@ | |||
isa = PBXFrameworksBuildPhase; | |||
buildActionMask = 2147483647; | |||
files = ( | |||
4BA7BE270DC2352A00AA3457 /* Jackservermp.framework in Frameworks */, | |||
4BA7BE270DC2352A00AA3457 /* Jackdmp.framework in Frameworks */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -2042,7 +2042,7 @@ | |||
4B5A1BDA0CD1CCE10005BF74 /* jack_midisine */, | |||
4B35C4250D4731D1000DE7AE /* jackdmp */, | |||
4B35C4830D4731D1000DE7AE /* Jackmp.framework */, | |||
4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */, | |||
4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */, | |||
4B35C5140D4731D1000DE7AE /* jack_midiseq */, | |||
4B35C5200D4731D1000DE7AE /* jack_midisine */, | |||
4B35C52C0D4731D1000DE7AE /* jack_metro */, | |||
@@ -2069,26 +2069,26 @@ | |||
4B0A28E60D52073D002EFF74 /* jack_thread_wait */, | |||
4B0A292D0D52108E002EFF74 /* jack_thread_wait */, | |||
4B57F5950D72C27900B4E719 /* jack_thread_wait */, | |||
4BA7FEC30D8E76270017FF73 /* jack_server_control */, | |||
4BA7FEC30D8E76270017FF73 /* jack_lsp */, | |||
BA222ACF0DC88132001A17F4 /* jack_net.so */, | |||
BA222AE90DC882DB001A17F4 /* netmanager.so */, | |||
4BA7FEC30D8E76270017FF73 /* jack_server_control */, | |||
4B363DD80DEB02F6001F72D9 /* jack_alias */, | |||
4B363E1A0DEB03C5001F72D9 /* jack_evmon */, | |||
4B363E4E0DEB0775001F72D9 /* jack_bufsize */, | |||
4B363EE90DEB091C001F72D9 /* jack_rec */, | |||
4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */, | |||
4B363F350DEB0BD1001F72D9 /* jack_showtime */, | |||
4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */, | |||
4BFA5E980DEC4D9C00FA4CDB /* testMutex */, | |||
4BFA828C0DF6A9E40087B4E1 /* jack_evmon */, | |||
4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */, | |||
4BFA82AB0DF6A9E40087B4E1 /* jack_rec */, | |||
4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */, | |||
4BFA82C30DF6A9E40087B4E1 /* jack_showtime */, | |||
4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */, | |||
4B19B3000E23620F00DD4A82 /* audioadapter.so */, | |||
4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */, | |||
4BA7FEC30D8E76270017FF73 /* jack_lsp */, | |||
4B363DD80DEB02F6001F72D9 /* jack_midiseq */, | |||
4B363E1A0DEB03C5001F72D9 /* jack_midiseq */, | |||
4B363E4E0DEB0775001F72D9 /* jack_midiseq */, | |||
4B363EE90DEB091C001F72D9 /* jack_midiseq */, | |||
4B363F1E0DEB0A6A001F72D9 /* jack_midiseq */, | |||
4B363F350DEB0BD1001F72D9 /* jack_midiseq */, | |||
4B363F720DEB0D4E001F72D9 /* jack_midiseq */, | |||
4BFA5E980DEC4D9C00FA4CDB /* testSem */, | |||
4BFA828C0DF6A9E40087B4E1 /* jack_midiseq */, | |||
4BFA829F0DF6A9E40087B4E1 /* jack_midiseq */, | |||
4BFA82AB0DF6A9E40087B4E1 /* jack_midiseq */, | |||
4BFA82B70DF6A9E40087B4E1 /* jack_midiseq */, | |||
4BFA82C30DF6A9E40087B4E1 /* jack_midiseq */, | |||
4BFA82CF0DF6A9E40087B4E1 /* jack_midiseq */, | |||
4B19B3000E23620F00DD4A82 /* netmanager.so */, | |||
4B5E08D50E5B66EE00BEE4E0 /* netmanager.so */, | |||
); | |||
name = Products; | |||
sourceTree = "<group>"; | |||
@@ -2152,8 +2152,6 @@ | |||
4B05A05D0DF72BC000840F4C /* JackAlsaDriver.cpp */, | |||
4B05A05E0DF72BC000840F4C /* JackAlsaDriver.h */, | |||
4B05A05F0DF72BC000840F4C /* jslist.h */, | |||
4B05A0600DF72BC000840F4C /* memops.c */, | |||
4B05A0610DF72BC000840F4C /* memops.h */, | |||
4B05A0620DF72BC000840F4C /* midi_pack.h */, | |||
4B05A0630DF72BC000840F4C /* midi_unpack.h */, | |||
4B05A0640DF72BC000840F4C /* usx2y.c */, | |||
@@ -2328,8 +2326,8 @@ | |||
4B2C28F908DAD01E00249230 /* JackGlobals.cpp */, | |||
4BF8D2190834F03D00C94B91 /* JackEngineControl.h */, | |||
4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */, | |||
4B8F3D4A0E06C4A10096D19C /* JackEngineTiming.h */, | |||
4B8F3D490E06C4A10096D19C /* JackEngineTiming.cpp */, | |||
4BBAE40E0F42FA6100B8BD3F /* JackEngineProfiling.h */, | |||
4BBAE40F0F42FA6100B8BD3F /* JackEngineProfiling.cpp */, | |||
4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */, | |||
4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */, | |||
4BF8D2220834F05C00C94B91 /* JackServer.h */, | |||
@@ -2741,6 +2739,7 @@ | |||
4B4CA9770E02CF9600F4BFDA /* JackRestartThreadedDriver.h in Headers */, | |||
4B4E9AFD0E5F1090000A3278 /* JackControlAPI.h in Headers */, | |||
4B93F19A0E87992200E4ECCD /* JackPosixThread.h in Headers */, | |||
4BBAE4120F42FA6100B8BD3F /* JackEngineProfiling.h in Headers */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -3103,10 +3102,10 @@ | |||
4B5F253E0DEE9B8F0041E486 /* JackLockedEngine.h in Headers */, | |||
4BBC93BB0DF9736C002DF220 /* JackWaitThreadedDriver.h in Headers */, | |||
4B4CA9750E02CF9600F4BFDA /* JackRestartThreadedDriver.h in Headers */, | |||
4B8F3D4C0E06C4A10096D19C /* JackEngineTiming.h in Headers */, | |||
4B4E9AFB0E5F1090000A3278 /* JackControlAPI.h in Headers */, | |||
4BC3B6A70E703B2E0066E42F /* JackPosixThread.h in Headers */, | |||
4BF2841B0F31B4BC00B05BE3 /* JackArgParser.h in Headers */, | |||
4BBAE4100F42FA6100B8BD3F /* JackEngineProfiling.h in Headers */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -3393,7 +3392,7 @@ | |||
); | |||
name = audioadapter; | |||
productName = jack_coreaudio; | |||
productReference = 4B19B3000E23620F00DD4A82 /* audioadapter.so */; | |||
productReference = 4B19B3000E23620F00DD4A82 /* netmanager.so */; | |||
productType = "com.apple.product-type.library.dynamic"; | |||
}; | |||
4B35C41B0D4731D1000DE7AE /* jackdmp framework 64bits */ = { | |||
@@ -3450,7 +3449,7 @@ | |||
); | |||
name = "Jackservermp.framework 64 bits"; | |||
productName = Jack; | |||
productReference = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; | |||
productReference = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; | |||
productType = "com.apple.product-type.framework"; | |||
}; | |||
4B35C50A0D4731D1000DE7AE /* jack_midiseq 64 bits */ = { | |||
@@ -3899,7 +3898,7 @@ | |||
name = "jack_alias Universal"; | |||
productInstallPath = /usr/local/bin; | |||
productName = jack_metro; | |||
productReference = 4B363DD80DEB02F6001F72D9 /* jack_alias */; | |||
productReference = 4B363DD80DEB02F6001F72D9 /* jack_midiseq */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4B363E100DEB03C5001F72D9 /* jack_evmon Universal */ = { | |||
@@ -3918,7 +3917,7 @@ | |||
name = "jack_evmon Universal"; | |||
productInstallPath = /usr/local/bin; | |||
productName = jack_metro; | |||
productReference = 4B363E1A0DEB03C5001F72D9 /* jack_evmon */; | |||
productReference = 4B363E1A0DEB03C5001F72D9 /* jack_midiseq */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4B363E440DEB0775001F72D9 /* jack_bufsize Universal */ = { | |||
@@ -3937,7 +3936,7 @@ | |||
name = "jack_bufsize Universal"; | |||
productInstallPath = /usr/local/bin; | |||
productName = jack_metro; | |||
productReference = 4B363E4E0DEB0775001F72D9 /* jack_bufsize */; | |||
productReference = 4B363E4E0DEB0775001F72D9 /* jack_midiseq */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4B363EDF0DEB091C001F72D9 /* jack_rec Universal */ = { | |||
@@ -3956,7 +3955,7 @@ | |||
name = "jack_rec Universal"; | |||
productInstallPath = /usr/local/bin; | |||
productName = jack_metro; | |||
productReference = 4B363EE90DEB091C001F72D9 /* jack_rec */; | |||
productReference = 4B363EE90DEB091C001F72D9 /* jack_midiseq */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4B363F140DEB0A6A001F72D9 /* jack_monitor_client Universal */ = { | |||
@@ -3975,7 +3974,7 @@ | |||
name = "jack_monitor_client Universal"; | |||
productInstallPath = /usr/local/bin; | |||
productName = jack_metro; | |||
productReference = 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */; | |||
productReference = 4B363F1E0DEB0A6A001F72D9 /* jack_midiseq */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4B363F2B0DEB0BD1001F72D9 /* jack_showtime Universal */ = { | |||
@@ -3994,7 +3993,7 @@ | |||
name = "jack_showtime Universal"; | |||
productInstallPath = /usr/local/bin; | |||
productName = jack_metro; | |||
productReference = 4B363F350DEB0BD1001F72D9 /* jack_showtime */; | |||
productReference = 4B363F350DEB0BD1001F72D9 /* jack_midiseq */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4B363F680DEB0D4E001F72D9 /* jack_impulse_grabber Universal */ = { | |||
@@ -4013,7 +4012,7 @@ | |||
name = "jack_impulse_grabber Universal"; | |||
productInstallPath = /usr/local/bin; | |||
productName = jack_metro; | |||
productReference = 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */; | |||
productReference = 4B363F720DEB0D4E001F72D9 /* jack_midiseq */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4B5A1BB10CD1CB9E0005BF74 /* jack_midiseq Universal */ = { | |||
@@ -4068,7 +4067,7 @@ | |||
); | |||
name = netadapter; | |||
productName = jack_coreaudio; | |||
productReference = 4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */; | |||
productReference = 4B5E08D50E5B66EE00BEE4E0 /* netmanager.so */; | |||
productType = "com.apple.product-type.library.dynamic"; | |||
}; | |||
4B699BA7097D421600A18468 /* jackdmp framework Universal */ = { | |||
@@ -4462,7 +4461,7 @@ | |||
name = "jack_server_control Universal"; | |||
productInstallPath = /usr/local/bin; | |||
productName = jack_lsp; | |||
productReference = 4BA7FEC30D8E76270017FF73 /* jack_server_control */; | |||
productReference = 4BA7FEC30D8E76270017FF73 /* jack_lsp */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4BD623ED0CBCF0F000DE782F /* inprocess */ = { | |||
@@ -4536,7 +4535,7 @@ | |||
name = "testMutex Universal"; | |||
productInstallPath = /usr/local/bin; | |||
productName = testSem; | |||
productReference = 4BFA5E980DEC4D9C00FA4CDB /* testMutex */; | |||
productReference = 4BFA5E980DEC4D9C00FA4CDB /* testSem */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4BFA82820DF6A9E40087B4E1 /* jack_evmon 64 bits */ = { | |||
@@ -4555,7 +4554,7 @@ | |||
name = "jack_evmon 64 bits"; | |||
productInstallPath = /usr/local/bin; | |||
productName = jack_metro; | |||
productReference = 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */; | |||
productReference = 4BFA828C0DF6A9E40087B4E1 /* jack_midiseq */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4BFA82950DF6A9E40087B4E1 /* jack_bufsize 64 bits */ = { | |||
@@ -4574,7 +4573,7 @@ | |||
name = "jack_bufsize 64 bits"; | |||
productInstallPath = /usr/local/bin; | |||
productName = jack_metro; | |||
productReference = 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */; | |||
productReference = 4BFA829F0DF6A9E40087B4E1 /* jack_midiseq */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4BFA82A10DF6A9E40087B4E1 /* jack_rec 64 bits */ = { | |||
@@ -4593,7 +4592,7 @@ | |||
name = "jack_rec 64 bits"; | |||
productInstallPath = /usr/local/bin; | |||
productName = jack_metro; | |||
productReference = 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */; | |||
productReference = 4BFA82AB0DF6A9E40087B4E1 /* jack_midiseq */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4BFA82AD0DF6A9E40087B4E1 /* jack_monitor_client 64 bits */ = { | |||
@@ -4612,7 +4611,7 @@ | |||
name = "jack_monitor_client 64 bits"; | |||
productInstallPath = /usr/local/bin; | |||
productName = jack_metro; | |||
productReference = 4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */; | |||
productReference = 4BFA82B70DF6A9E40087B4E1 /* jack_midiseq */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4BFA82B90DF6A9E40087B4E1 /* jack_showtime 64 bits */ = { | |||
@@ -4631,7 +4630,7 @@ | |||
name = "jack_showtime 64 bits"; | |||
productInstallPath = /usr/local/bin; | |||
productName = jack_metro; | |||
productReference = 4BFA82C30DF6A9E40087B4E1 /* jack_showtime */; | |||
productReference = 4BFA82C30DF6A9E40087B4E1 /* jack_midiseq */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4BFA82C50DF6A9E40087B4E1 /* jack_impulse_grabber 64 bits */ = { | |||
@@ -4650,7 +4649,7 @@ | |||
name = "jack_impulse_grabber 64 bits"; | |||
productInstallPath = /usr/local/bin; | |||
productName = jack_metro; | |||
productReference = 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */; | |||
productReference = 4BFA82CF0DF6A9E40087B4E1 /* jack_midiseq */; | |||
productType = "com.apple.product-type.tool"; | |||
}; | |||
4BFA99980AAAF3B0009E916C /* jdelay Universal */ = { | |||
@@ -5389,6 +5388,7 @@ | |||
4B93F1990E87992100E4ECCD /* JackPosixThread.cpp in Sources */, | |||
4B93F19B0E87992300E4ECCD /* JackProcessSync.cpp in Sources */, | |||
4B93F22B0E87A72500E4ECCD /* JackMachTime.c in Sources */, | |||
4BBAE4130F42FA6100B8BD3F /* JackEngineProfiling.cpp in Sources */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -5762,12 +5762,12 @@ | |||
4B4F9C8C0DC20C0400706CB0 /* JackMessageBuffer.cpp in Sources */, | |||
4BBC93BA0DF9736C002DF220 /* JackWaitThreadedDriver.cpp in Sources */, | |||
4B4CA9760E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp in Sources */, | |||
4B8F3D4B0E06C4A10096D19C /* JackEngineTiming.cpp in Sources */, | |||
4B4E9AFA0E5F1090000A3278 /* JackControlAPI.cpp in Sources */, | |||
4BC3B6A60E703B2E0066E42F /* JackPosixThread.cpp in Sources */, | |||
4BC3B6AC0E703B690066E42F /* JackProcessSync.cpp in Sources */, | |||
4BF5FBCA0E878D24003D2374 /* JackMachTime.c in Sources */, | |||
4BF2841A0F31B4BC00B05BE3 /* JackArgParser.cpp in Sources */, | |||
4BBAE4110F42FA6100B8BD3F /* JackEngineProfiling.cpp in Sources */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -21,17 +21,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
#define __JackCompilerDeps_POSIX__ | |||
#if __GNUC__ | |||
#define MEM_ALIGN(x,y) x __attribute__((aligned(y))) | |||
#define EXPORT __attribute__((visibility("default"))) | |||
#define MEM_ALIGN(x,y) x __attribute__((aligned(y))) | |||
#define EXPORT __attribute__((visibility("default"))) | |||
#ifdef SERVER_SIDE | |||
#define SERVER_EXPORT __attribute__((visibility("default"))) | |||
#if (__GNUC__< 4) | |||
#define SERVER_EXPORT | |||
#else | |||
#define SERVER_EXPORT __attribute__((visibility("default"))) | |||
#endif | |||
#else | |||
#define SERVER_EXPORT | |||
#endif | |||
#else | |||
#define MEM_ALIGN(x,y) x | |||
#define EXPORT | |||
#define SERVER_EXPORT | |||
#define MEM_ALIGN(x,y) x | |||
#define EXPORT | |||
#define SERVER_EXPORT | |||
#endif | |||
#endif | |||
@@ -121,28 +121,27 @@ bool JackFifo::Allocate(const char* name, const char* server_name, int value) | |||
{ | |||
struct stat statbuf; | |||
BuildName(name, server_name, fName); | |||
jack_log("JackFifo::Allocate name = %s", fName); | |||
if (stat(fName, &statbuf)) { | |||
if (errno == ENOENT) { | |||
if (stat(fName, &statbuf) < 0) { | |||
if (errno == ENOENT || errno == EPERM) { | |||
if (mkfifo(fName, 0666) < 0) { | |||
jack_error("Cannot create inter-client FIFO [%s] (%s)\n", name, strerror(errno)); | |||
jack_error("Cannot create inter-client FIFO name = %s err = %s", name, strerror(errno)); | |||
return false; | |||
} | |||
} else { | |||
jack_error("Cannot check on FIFO %s\n", name); | |||
jack_error("Cannot check on FIFO %s", name); | |||
return false; | |||
} | |||
} else { | |||
if (!S_ISFIFO(statbuf.st_mode)) { | |||
jack_error("FIFO (%s) already exists, but is not a FIFO!\n", name); | |||
jack_error("FIFO name = %s already exists, but is not a FIFO", name); | |||
return false; | |||
} | |||
} | |||
if ((fFifo = open(fName, O_RDWR | O_CREAT, 0666)) < 0) { | |||
jack_error("Cannot open fifo [%s] (%s)", name, strerror(errno)); | |||
jack_error("Cannot open FIFO name = %s err = %s", name, strerror(errno)); | |||
return false; | |||
} else { | |||
fPoll.fd = fFifo; | |||
@@ -18,6 +18,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
*/ | |||
#include "JackNetUnixSocket.h" | |||
#include <unistd.h> | |||
#include <fcntl.h> | |||
namespace Jack | |||
{ | |||
@@ -38,6 +40,7 @@ namespace Jack | |||
{ | |||
fSockfd = 0; | |||
fPort = 0; | |||
fTimeOut = 0; | |||
fSendAddr.sin_family = AF_INET; | |||
fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); | |||
memset ( &fSendAddr.sin_zero, 0, 8 ); | |||
@@ -50,6 +53,7 @@ namespace Jack | |||
{ | |||
fSockfd = 0; | |||
fPort = port; | |||
fTimeOut = 0; | |||
fSendAddr.sin_family = AF_INET; | |||
fSendAddr.sin_port = htons ( port ); | |||
inet_aton ( ip, &fSendAddr.sin_addr ); | |||
@@ -63,6 +67,7 @@ namespace Jack | |||
JackNetUnixSocket::JackNetUnixSocket ( const JackNetUnixSocket& socket ) | |||
{ | |||
fSockfd = 0; | |||
fTimeOut = 0; | |||
fPort = socket.fPort; | |||
fSendAddr = socket.fSendAddr; | |||
fRecvAddr = socket.fRecvAddr; | |||
@@ -212,6 +217,86 @@ namespace Jack | |||
} | |||
//timeout************************************************************************************************************ | |||
#if defined(__sun__) || defined(sun) | |||
int JackNetUnixSocket::SetTimeOut ( int us ) | |||
{ | |||
int flags; | |||
fTimeOut = us; | |||
if ((flags = fcntl(fSockfd, F_GETFL, 0)) < 0) { | |||
jack_error("JackNetUnixSocket::SetTimeOut error in fcntl F_GETFL"); | |||
return -1; | |||
} | |||
flags |= O_NONBLOCK; | |||
if (fcntl(fSockfd, F_SETFL, flags) < 0) { | |||
jack_error("JackNetUnixSocket::SetTimeOut error in fcntl F_SETFL"); | |||
return 1; | |||
} | |||
return 0; | |||
} | |||
int JackNetUnixSocket::WaitRead() | |||
{ | |||
if (fTimeOut > 0) { | |||
struct timeval tv; | |||
fd_set fdset; | |||
ssize_t res; | |||
tv.tv_sec = fTimeOut / 1000000; | |||
tv.tv_usec = fTimeOut % 1000000; | |||
FD_ZERO(&fdset); | |||
FD_SET(fSockfd, &fdset); | |||
do { | |||
res = select(fSockfd + 1, &fdset, NULL, NULL, &tv); | |||
} while (res < 0 && errno == EINTR); | |||
if (res < 0) { | |||
return res; | |||
} else if (res == 0) { | |||
errno = ETIMEDOUT; | |||
return -1; | |||
} | |||
} | |||
return 0; | |||
} | |||
int JackNetUnixSocket::WaitWrite() | |||
{ | |||
if (fTimeOut > 0) { | |||
struct timeval tv; | |||
fd_set fdset; | |||
ssize_t res; | |||
tv.tv_sec = fTimeOut / 1000000; | |||
tv.tv_usec = fTimeOut % 1000000; | |||
FD_ZERO(&fdset); | |||
FD_SET(fSockfd, &fdset); | |||
do { | |||
res = select(fSockfd + 1, NULL, &fdset, NULL, &tv); | |||
} while (res < 0 && errno == EINTR); | |||
if (res < 0) { | |||
return res; | |||
} else if (res == 0) { | |||
errno = ETIMEDOUT; | |||
return -1; | |||
} | |||
} | |||
return 0; | |||
} | |||
#else | |||
int JackNetUnixSocket::SetTimeOut ( int us ) | |||
{ | |||
jack_log ( "JackNetUnixSocket::SetTimeout %d usecs", us ); | |||
@@ -237,6 +322,7 @@ namespace Jack | |||
} | |||
return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof ( timeout ) ); | |||
} | |||
#endif | |||
//local loop********************************************************************************************************** | |||
int JackNetUnixSocket::SetLocalLoop() | |||
@@ -248,6 +334,10 @@ namespace Jack | |||
//network operations************************************************************************************************** | |||
int JackNetUnixSocket::SendTo ( const void* buffer, size_t nbytes, int flags ) | |||
{ | |||
#if defined(__sun__) || defined(sun) | |||
if (WaitWrite() < 0) | |||
return -1; | |||
#endif | |||
return sendto ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), sizeof ( socket_address_t ) ); | |||
} | |||
@@ -256,28 +346,48 @@ namespace Jack | |||
int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr ); | |||
if ( addr_conv < 1 ) | |||
return addr_conv; | |||
#if defined(__sun__) || defined(sun) | |||
if (WaitWrite() < 0) | |||
return -1; | |||
#endif | |||
return SendTo ( buffer, nbytes, flags ); | |||
} | |||
int JackNetUnixSocket::Send ( const void* buffer, size_t nbytes, int flags ) | |||
{ | |||
#if defined(__sun__) || defined(sun) | |||
if (WaitWrite() < 0) | |||
return -1; | |||
#endif | |||
return send ( fSockfd, buffer, nbytes, flags ); | |||
} | |||
int JackNetUnixSocket::RecvFrom ( void* buffer, size_t nbytes, int flags ) | |||
{ | |||
socklen_t addr_len = sizeof ( socket_address_t ); | |||
#if defined(__sun__) || defined(sun) | |||
if (WaitRead() < 0) | |||
return -1; | |||
#endif | |||
return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fRecvAddr ), &addr_len ); | |||
} | |||
int JackNetUnixSocket::Recv ( void* buffer, size_t nbytes, int flags ) | |||
{ | |||
#if defined(__sun__) || defined(sun) | |||
if (WaitRead() < 0) | |||
return -1; | |||
#endif | |||
return recv ( fSockfd, buffer, nbytes, flags ); | |||
} | |||
int JackNetUnixSocket::CatchHost ( void* buffer, size_t nbytes, int flags ) | |||
{ | |||
socklen_t addr_len = sizeof ( socket_address_t ); | |||
#if defined(__sun__) || defined(sun) | |||
if (WaitRead() < 0) | |||
return -1; | |||
#endif | |||
return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), &addr_len ); | |||
} | |||
@@ -286,6 +396,7 @@ namespace Jack | |||
switch ( errno ) | |||
{ | |||
case EAGAIN: | |||
case ETIMEDOUT: | |||
return NET_NO_DATA; | |||
case ECONNABORTED: | |||
@@ -42,9 +42,14 @@ namespace Jack | |||
private: | |||
int fSockfd; | |||
int fPort; | |||
int fTimeOut; | |||
struct sockaddr_in fSendAddr; | |||
struct sockaddr_in fRecvAddr; | |||
#if defined(__sun__) || defined(sun) | |||
int WaitRead(); | |||
int WaitWrite(); | |||
#endif | |||
public: | |||
JackNetUnixSocket(); | |||
JackNetUnixSocket ( const char* ip, int port ); | |||
@@ -18,18 +18,58 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
*/ | |||
#include "JackSocket.h" | |||
#include "JackConstants.h" | |||
#include "JackTools.h" | |||
#include "JackError.h" | |||
#include <string.h> | |||
#include <stdio.h> | |||
#include <pthread.h> | |||
#include <fcntl.h> | |||
namespace Jack | |||
{ | |||
JackClientSocket::JackClientSocket(int socket): fSocket(socket) | |||
JackClientSocket::JackClientSocket(int socket): fSocket(socket),fTimeOut(0) | |||
{} | |||
#if defined(__sun__) || defined(sun) | |||
void JackClientSocket::SetReadTimeOut(long sec) | |||
{ | |||
int flags; | |||
fTimeOut = sec; | |||
if ((flags = fcntl(fSocket, F_GETFL, 0)) < 0) { | |||
jack_error("JackClientSocket::SetReadTimeOut error in fcntl F_GETFL"); | |||
return; | |||
} | |||
flags |= O_NONBLOCK; | |||
if (fcntl(fSocket, F_SETFL, flags) < 0) { | |||
jack_error("JackClientSocket::SetReadTimeOut error in fcntl F_SETFL"); | |||
return; | |||
} | |||
} | |||
void JackClientSocket::SetWriteTimeOut(long sec) | |||
{ | |||
int flags; | |||
fTimeOut = sec; | |||
if ((flags = fcntl(fSocket, F_GETFL, 0)) < 0) { | |||
jack_error("JackClientSocket::SetWriteTimeOut error in fcntl F_GETFL"); | |||
return; | |||
} | |||
flags |= O_NONBLOCK; | |||
if (fcntl(fSocket, F_SETFL, flags) < 0) { | |||
jack_error("JackClientSocket::SetWriteTimeOut error in fcntl F_SETFL"); | |||
return; | |||
} | |||
} | |||
#else | |||
void JackClientSocket::SetReadTimeOut(long sec) | |||
{ | |||
struct timeval timout; | |||
@@ -50,11 +90,15 @@ void JackClientSocket::SetWriteTimeOut(long sec) | |||
} | |||
} | |||
#endif | |||
void JackClientSocket::SetNonBlocking(bool onoff) | |||
{ | |||
int flag = (onoff) ? 1 : 0; | |||
if (ioctl(fSocket, FIONBIO, &flag) < 0) { | |||
jack_error("SetNonBlocking fd = %ld err = %s", fSocket, strerror(errno)); | |||
if (onoff) { | |||
long flags = 0; | |||
if (fcntl(fSocket, F_SETFL, flags | O_NONBLOCK) < 0) { | |||
jack_error("SetNonBlocking fd = %ld err = %s", fSocket, strerror(errno)); | |||
} | |||
} | |||
} | |||
@@ -131,11 +175,40 @@ int JackClientSocket::Close() | |||
int JackClientSocket::Read(void* data, int len) | |||
{ | |||
if (read(fSocket, data, len) != len) { | |||
jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno)); | |||
int res; | |||
#if defined(__sun__) || defined(sun) | |||
if (fTimeOut > 0) { | |||
struct timeval tv; | |||
fd_set fdset; | |||
ssize_t res; | |||
tv.tv_sec = fTimeOut; | |||
tv.tv_usec = 0; | |||
FD_ZERO(&fdset); | |||
FD_SET(fSocket, &fdset); | |||
do { | |||
res = select(fSocket + 1, &fdset, NULL, NULL, &tv); | |||
} while (res < 0 && errno == EINTR); | |||
if (res < 0) { | |||
return res; | |||
} else if (res == 0) { | |||
return -1; | |||
} | |||
} | |||
#endif | |||
if ((res = read(fSocket, data, len)) != len) { | |||
if (errno == EWOULDBLOCK) { | |||
jack_error("JackClientSocket::Read time out"); | |||
return 0; // For a non blocking socket, a read failure is not considered as an error | |||
} else if (res != 0) { | |||
jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno)); | |||
return 0; | |||
} else { | |||
return -1; | |||
} | |||
@@ -146,11 +219,40 @@ int JackClientSocket::Read(void* data, int len) | |||
int JackClientSocket::Write(void* data, int len) | |||
{ | |||
if (write(fSocket, data, len) != len) { | |||
jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno)); | |||
int res; | |||
#if defined(__sun__) || defined(sun) | |||
if (fTimeOut > 0) { | |||
struct timeval tv; | |||
fd_set fdset; | |||
ssize_t res; | |||
tv.tv_sec = fTimeOut; | |||
tv.tv_usec = 0; | |||
FD_ZERO(&fdset); | |||
FD_SET(fSocket, &fdset); | |||
do { | |||
res = select(fSocket + 1, NULL, &fdset, NULL, &tv); | |||
} while (res < 0 && errno == EINTR); | |||
if (res < 0) { | |||
return res; | |||
} else if (res == 0) { | |||
return -1; | |||
} | |||
} | |||
#endif | |||
if ((res = write(fSocket, data, len)) != len) { | |||
if (errno == EWOULDBLOCK) { | |||
jack_log("JackClientSocket::Write time out"); | |||
return 0; // For a non blocking socket, a write failure is not considered as an error | |||
} else if (res != 0) { | |||
jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno)); | |||
return 0; | |||
} else { | |||
return -1; | |||
} | |||
@@ -42,10 +42,11 @@ class JackClientSocket | |||
private: | |||
int fSocket; | |||
int fTimeOut; | |||
public: | |||
JackClientSocket(): fSocket( -1) | |||
JackClientSocket(): fSocket( -1),fTimeOut(0) | |||
{} | |||
JackClientSocket(int socket); | |||
@@ -154,7 +154,8 @@ bool JackSocketServerChannel::HandleRequest(int fd) | |||
// Read header | |||
JackRequest header; | |||
if (header.Read(socket) < 0) { | |||
jack_error("HandleRequest: cannot read header"); | |||
jack_log("HandleRequest: cannot read header"); | |||
ClientKill(fd); // TO CHECK SOLARIS | |||
return false; | |||
} | |||
@@ -391,7 +392,7 @@ bool JackSocketServerChannel::HandleRequest(int fd) | |||
} | |||
default: | |||
jack_log("Unknown request %ld", header.fType); | |||
jack_error("Unknown request %ld", header.fType); | |||
break; | |||
} | |||
@@ -449,7 +450,7 @@ bool JackSocketServerChannel::Execute() | |||
ClientKill(fd); | |||
} else if (fPollTable[i].revents & POLLIN) { | |||
if (!HandleRequest(fd)) | |||
jack_error("Could not handle external client request"); | |||
jack_log("Could not handle external client request"); | |||
} | |||
} | |||
@@ -0,0 +1,32 @@ | |||
/* | |||
Copyright (C) 2004-2008 Grame | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU Lesser General Public License as published by | |||
the Free Software Foundation; either version 2.1 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU Lesser General Public License for more details. | |||
You should have received a copy of the GNU Lesser General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
*/ | |||
#ifndef __JackAtomic_sun__ | |||
#define __JackAtomic_sun__ | |||
#include "JackTypes.h" | |||
#include <atomic.h> | |||
static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr) | |||
{ | |||
return (atomic_cas_32((uint32_t*)addr, value, newvalue) == value); | |||
} | |||
#endif | |||
@@ -0,0 +1,80 @@ | |||
/* | |||
Copyright (C) 2004-2008 Grame | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU Lesser General Public License as published by | |||
the Free Software Foundation; either version 2.1 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU Lesser General Public License for more details. | |||
You should have received a copy of the GNU Lesser General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
*/ | |||
#ifndef __JackPlatformPlug_sun__ | |||
#define __JackPlatformPlug_sun__ | |||
namespace Jack | |||
{ | |||
struct JackRequest; | |||
struct JackResult; | |||
class JackPosixMutex; | |||
class JackPosixThread; | |||
class JackFifo; | |||
class JackSocketServerChannel; | |||
class JackSocketClientChannel; | |||
class JackSocketServerNotifyChannel; | |||
class JackSocketNotifyChannel; | |||
class JackClientSocket; | |||
class JackNetUnixSocket; | |||
} | |||
/* __JackPlatformMutex__ */ | |||
#include "JackPosixMutex.h" | |||
namespace Jack {typedef JackPosixMutex JackMutex; } | |||
/* __JackPlatformThread__ */ | |||
#include "JackPosixThread.h" | |||
namespace Jack { typedef JackPosixThread JackThread; } | |||
/* __JackPlatformSynchro__ client activation */ | |||
#include "JackFifo.h" | |||
namespace Jack { typedef JackFifo JackSynchro; } | |||
/* __JackPlatformChannelTransaction__ */ | |||
#include "JackSocket.h" | |||
namespace Jack { typedef JackClientSocket JackChannelTransaction; } | |||
#include "JackProcessSync.h" | |||
/* __JackPlatformProcessSync__ */ | |||
/* Only on windows a special JackProcessSync is used. It is directly defined by including JackProcessSync.h here */ | |||
/* __JackPlatformServerChannel__ */ | |||
#include "JackSocketServerChannel.h" | |||
namespace Jack { typedef JackSocketServerChannel JackServerChannel; } | |||
/* __JackPlatformClientChannel__ */ | |||
#include "JackSocketClientChannel.h" | |||
namespace Jack { typedef JackSocketClientChannel JackClientChannel; } | |||
/* __JackPlatformServerNotifyChannel__ */ | |||
#include "JackSocketServerNotifyChannel.h" | |||
namespace Jack { typedef JackSocketServerNotifyChannel JackServerNotifyChannel; } | |||
/* __JackPlatformNotifyChannel__ */ | |||
#include "JackSocketNotifyChannel.h" | |||
namespace Jack { typedef JackSocketNotifyChannel JackNotifyChannel; } | |||
/* __JackPlatformNetSocket__ */ | |||
#include "JackNetUnixSocket.h" | |||
namespace Jack { typedef JackNetUnixSocket JackNetSocket; } | |||
#endif |
@@ -0,0 +1,37 @@ | |||
/* | |||
Copyright (C) 2001-2003 Paul Davis | |||
Copyright (C) 2004-2008 Grame | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU Lesser General Public License as published by | |||
the Free Software Foundation; either version 2.1 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU Lesser General Public License for more details. | |||
You should have received a copy of the GNU Lesser General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
*/ | |||
#include "JackTime.h" | |||
#include <unistd.h> | |||
#include <time.h> | |||
SERVER_EXPORT void JackSleep(long usec) | |||
{ | |||
usleep(usec); | |||
} | |||
SERVER_EXPORT void InitTime() | |||
{} | |||
SERVER_EXPORT jack_time_t GetMicroSeconds(void) | |||
{ | |||
return (jack_time_t)(gethrtime() / 1000); | |||
} | |||
@@ -0,0 +1,766 @@ | |||
/* | |||
Copyright (C) 2008 Grame & RTL 2008 | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation; either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
*/ | |||
#include "JackOSSAdapter.h" | |||
#include "JackServerGlobals.h" | |||
#include "JackEngineControl.h" | |||
#include "memops.h" | |||
#include <sys/ioctl.h> | |||
#include <sys/soundcard.h> | |||
#include <fcntl.h> | |||
#include <iostream> | |||
#include <assert.h> | |||
namespace Jack | |||
{ | |||
inline int int2pow2(int x) { int r = 0; while ((1 << r) < x) r++; return r; } | |||
static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframes, int channel, int chcount, int bits) | |||
{ | |||
switch (bits) { | |||
case 16: { | |||
signed short *s16src = (signed short*)src; | |||
s16src += channel; | |||
sample_move_dS_s16(dst, (char*)s16src, nframes, chcount<<1); | |||
break; | |||
} | |||
case 24: { | |||
signed short *s32src = (signed short*)src; | |||
s32src += channel; | |||
sample_move_dS_s24(dst, (char*)s32src, nframes, chcount<<2); | |||
break; | |||
} | |||
case 32: { | |||
signed short *s32src = (signed short*)src; | |||
s32src += channel; | |||
sample_move_dS_s32u24(dst, (char*)s32src, nframes, chcount<<2); | |||
break; | |||
} | |||
} | |||
} | |||
static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nframes, int channel, int chcount, int bits) | |||
{ | |||
switch (bits) { | |||
case 16: { | |||
signed short *s16dst = (signed short*)dst; | |||
s16dst += channel; | |||
sample_move_d16_sS((char*)s16dst, src, nframes, chcount<<1, NULL); // No dithering for now... | |||
break; | |||
} | |||
case 24: { | |||
signed int *s32dst = (signed int*)dst; | |||
s32dst += channel; | |||
sample_move_d24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); // No dithering for now... | |||
break; | |||
} | |||
case 32: { | |||
signed int *s32dst = (signed int*)dst; | |||
s32dst += channel; | |||
sample_move_d32u24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); | |||
break; | |||
} | |||
} | |||
} | |||
void JackOSSAdapter::SetSampleFormat() | |||
{ | |||
switch (fBits) { | |||
case 24: /* native-endian LSB aligned 24-bits in 32-bits integer */ | |||
fSampleFormat = AFMT_S24_NE; | |||
fSampleSize = sizeof(int); | |||
break; | |||
case 32: /* native-endian 32-bit integer */ | |||
fSampleFormat = AFMT_S32_NE; | |||
fSampleSize = sizeof(int); | |||
break; | |||
case 16: /* native-endian 16-bit integer */ | |||
default: | |||
fSampleFormat = AFMT_S16_NE; | |||
fSampleSize = sizeof(short); | |||
break; | |||
} | |||
} | |||
JackOSSAdapter::JackOSSAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) | |||
:JackAudioAdapterInterface(buffer_size, sample_rate) | |||
,fThread(this), | |||
fInFD(-1), fOutFD(-1), fBits(OSS_DRIVER_DEF_BITS), | |||
fSampleFormat(0), fNperiods(OSS_DRIVER_DEF_NPERIODS), fRWMode(0), fIgnoreHW(true), fExcl(false), | |||
fInputBufferSize(0), fOutputBufferSize(0), | |||
fInputBuffer(NULL), fOutputBuffer(NULL), fFirstCycle(true) | |||
{ | |||
const JSList* node; | |||
const jack_driver_param_t* param; | |||
fCaptureChannels = 2; | |||
fPlaybackChannels = 2; | |||
strcpy(fCaptureDriverName, OSS_DRIVER_DEF_DEV); | |||
strcpy(fPlaybackDriverName, OSS_DRIVER_DEF_DEV); | |||
for (node = params; node; node = jack_slist_next(node)) { | |||
param = (const jack_driver_param_t*) node->data; | |||
switch (param->character) { | |||
case 'r': | |||
SetAdaptedSampleRate(param->value.ui); | |||
break; | |||
case 'p': | |||
SetAdaptedBufferSize(param->value.ui); | |||
break; | |||
case 'n': | |||
fNperiods = param->value.ui; | |||
break; | |||
case 'w': | |||
fBits = param->value.i; | |||
break; | |||
case 'i': | |||
fCaptureChannels = param->value.ui; | |||
break; | |||
case 'o': | |||
fPlaybackChannels = param->value.ui; | |||
break; | |||
case 'e': | |||
fExcl = true; | |||
break; | |||
case 'C': | |||
fRWMode |= kRead; | |||
if (strcmp(param->value.str, "none") != 0) { | |||
strcpy(fCaptureDriverName, param->value.str); | |||
} | |||
break; | |||
case 'P': | |||
fRWMode |= kWrite; | |||
if (strcmp(param->value.str, "none") != 0) { | |||
strcpy(fPlaybackDriverName, param->value.str); | |||
} | |||
break; | |||
case 'd': | |||
fRWMode |= kRead; | |||
fRWMode |= kWrite; | |||
strcpy(fCaptureDriverName, param->value.str); | |||
strcpy(fPlaybackDriverName, param->value.str); | |||
break; | |||
case 'b': | |||
fIgnoreHW = true; | |||
break; | |||
case 'q': | |||
fQuality = param->value.ui; | |||
break; | |||
} | |||
} | |||
fRWMode |= kRead; | |||
fRWMode |= kWrite; | |||
} | |||
void JackOSSAdapter::DisplayDeviceInfo() | |||
{ | |||
audio_buf_info info; | |||
oss_audioinfo ai_in, ai_out; | |||
memset(&info, 0, sizeof(audio_buf_info)); | |||
int cap = 0; | |||
// Duplex cards : http://manuals.opensound.com/developer/full_duplex.html | |||
jack_info("Audio Interface Description :"); | |||
jack_info("Sampling Frequency : %d, Sample Format : %d, Mode : %d", fAdaptedSampleRate, fSampleFormat, fRWMode); | |||
if (fRWMode & kWrite) { | |||
oss_sysinfo si; | |||
if (ioctl(fOutFD, OSS_SYSINFO, &si) == -1) { | |||
jack_error("JackOSSAdapter::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
} else { | |||
jack_info("OSS product %s", si.product); | |||
jack_info("OSS version %s", si.version); | |||
jack_info("OSS version num %d", si.versionnum); | |||
jack_info("OSS numaudios %d", si.numaudios); | |||
jack_info("OSS numaudioengines %d", si.numaudioengines); | |||
jack_info("OSS numcards %d", si.numcards); | |||
} | |||
jack_info("Output capabilities - %d channels : ", fPlaybackChannels); | |||
jack_info("Output block size = %d", fOutputBufferSize); | |||
if (ioctl(fOutFD, SNDCTL_DSP_GETOSPACE, &info) == -1) { | |||
jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
} else { | |||
jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", | |||
info.fragments, info.fragstotal, info.fragsize, info.bytes); | |||
} | |||
if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { | |||
jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
} else { | |||
if (cap & DSP_CAP_DUPLEX) jack_info(" DSP_CAP_DUPLEX"); | |||
if (cap & DSP_CAP_REALTIME) jack_info(" DSP_CAP_REALTIME"); | |||
if (cap & DSP_CAP_BATCH) jack_info(" DSP_CAP_BATCH"); | |||
if (cap & DSP_CAP_COPROC) jack_info(" DSP_CAP_COPROC"); | |||
if (cap & DSP_CAP_TRIGGER) jack_info(" DSP_CAP_TRIGGER"); | |||
if (cap & DSP_CAP_MMAP) jack_info(" DSP_CAP_MMAP"); | |||
if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); | |||
if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); | |||
} | |||
} | |||
if (fRWMode & kRead) { | |||
oss_sysinfo si; | |||
if (ioctl(fInFD, OSS_SYSINFO, &si) == -1) { | |||
jack_error("JackOSSAdapter::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
} else { | |||
jack_info("OSS product %s", si.product); | |||
jack_info("OSS version %s", si.version); | |||
jack_info("OSS version num %d", si.versionnum); | |||
jack_info("OSS numaudios %d", si.numaudios); | |||
jack_info("OSS numaudioengines %d", si.numaudioengines); | |||
jack_info("OSS numcards %d", si.numcards); | |||
} | |||
jack_info("Input capabilities - %d channels : ", fCaptureChannels); | |||
jack_info("Input block size = %d", fInputBufferSize); | |||
if (ioctl(fInFD, SNDCTL_DSP_GETOSPACE, &info) == -1) { | |||
jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
} else { | |||
jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", | |||
info.fragments, info.fragstotal, info.fragsize, info.bytes); | |||
} | |||
if (ioctl(fInFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { | |||
jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
} else { | |||
if (cap & DSP_CAP_DUPLEX) jack_info(" DSP_CAP_DUPLEX"); | |||
if (cap & DSP_CAP_REALTIME) jack_info(" DSP_CAP_REALTIME"); | |||
if (cap & DSP_CAP_BATCH) jack_info(" DSP_CAP_BATCH"); | |||
if (cap & DSP_CAP_COPROC) jack_info(" DSP_CAP_COPROC"); | |||
if (cap & DSP_CAP_TRIGGER) jack_info(" DSP_CAP_TRIGGER"); | |||
if (cap & DSP_CAP_MMAP) jack_info(" DSP_CAP_MMAP"); | |||
if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); | |||
if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); | |||
} | |||
} | |||
if (ioctl(fInFD, SNDCTL_AUDIOINFO, &ai_in) != -1) { | |||
jack_info("Using audio engine %d = %s for input", ai_in.dev, ai_in.name); | |||
} | |||
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_in.rate_source != ai_out.rate_source) { | |||
jack_info("Warning : input and output are not necessarily driven by the same clock!"); | |||
} | |||
} | |||
int JackOSSAdapter::OpenInput() | |||
{ | |||
int flags = 0; | |||
int gFragFormat; | |||
int cur_sample_format, cur_capture_channels; | |||
jack_nframes_t cur_sample_rate; | |||
if (fCaptureChannels == 0) fCaptureChannels = 2; | |||
if ((fInFD = open(fCaptureDriverName, O_RDONLY | ((fExcl) ? O_EXCL : 0))) < 0) { | |||
jack_error("JackOSSAdapter::OpenInput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
return -1; | |||
} | |||
jack_log("JackOSSAdapter::OpenInput input fInFD = %d", fInFD); | |||
if (fExcl) { | |||
if (ioctl(fInFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { | |||
jack_error("JackOSSAdapter::OpenInput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
goto error; | |||
} | |||
} | |||
printf("fAdaptedBufferSize %d %d %d %d %s\n", fExcl, fAdaptedBufferSize, fSampleSize, fCaptureChannels, fCaptureDriverName); | |||
gFragFormat = (2 << 16) + int2pow2(fAdaptedBufferSize * fSampleSize * fCaptureChannels); | |||
if (ioctl(fInFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { | |||
jack_error("JackOSSAdapter::OpenInput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
goto error; | |||
} | |||
cur_sample_format = fSampleFormat; | |||
if (ioctl(fInFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { | |||
jack_error("JackOSSAdapter::OpenInput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
goto error; | |||
} | |||
if (cur_sample_format != fSampleFormat) { | |||
jack_info("JackOSSAdapter::OpenInput driver forced the sample format %ld", fSampleFormat); | |||
} | |||
cur_capture_channels = fCaptureChannels; | |||
if (ioctl(fInFD, SNDCTL_DSP_CHANNELS, &fCaptureChannels) == -1) { | |||
jack_error("JackOSSAdapter::OpenInput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
goto error; | |||
} | |||
if (cur_capture_channels != fCaptureChannels) { | |||
jack_info("JackOSSAdapter::OpenInput driver forced the number of capture channels %ld", fCaptureChannels); | |||
} | |||
cur_sample_rate = fAdaptedSampleRate; | |||
if (ioctl(fInFD, SNDCTL_DSP_SPEED, &fAdaptedSampleRate) == -1) { | |||
jack_error("JackOSSAdapter::OpenInput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
goto error; | |||
} | |||
if (cur_sample_rate != fAdaptedSampleRate) { | |||
jack_info("JackOSSAdapter::OpenInput driver forced the sample rate %ld", fAdaptedSampleRate); | |||
} | |||
fInputBufferSize = 0; | |||
if (ioctl(fInFD, SNDCTL_DSP_GETBLKSIZE, &fInputBufferSize) == -1) { | |||
jack_error("JackOSSAdapter::OpenInput failed to get fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
goto error; | |||
} | |||
if (fInputBufferSize != fAdaptedBufferSize * fSampleSize * fCaptureChannels) { | |||
if (fIgnoreHW) { | |||
jack_info("JackOSSAdapter::OpenInput driver forced buffer size %ld", fOutputBufferSize); | |||
} else { | |||
jack_error("JackOSSAdapter::OpenInput wanted buffer size cannot be obtained"); | |||
goto error; | |||
} | |||
} | |||
fInputBuffer = (void*)calloc(fInputBufferSize, 1); | |||
assert(fInputBuffer); | |||
fInputSampleBuffer = (float**)malloc(fCaptureChannels * sizeof(float*)); | |||
assert(fInputSampleBuffer); | |||
for (int i = 0; i < fCaptureChannels; i++) { | |||
fInputSampleBuffer[i] = (float*)malloc(fAdaptedBufferSize * sizeof(float)); | |||
assert(fInputSampleBuffer[i]); | |||
} | |||
return 0; | |||
error: | |||
::close(fInFD); | |||
return -1; | |||
} | |||
int JackOSSAdapter::OpenOutput() | |||
{ | |||
int flags = 0; | |||
int gFragFormat; | |||
int cur_sample_format, cur_playback_channels; | |||
jack_nframes_t cur_sample_rate; | |||
if (fPlaybackChannels == 0) fPlaybackChannels = 2; | |||
if ((fOutFD = open(fPlaybackDriverName, O_WRONLY | ((fExcl) ? O_EXCL : 0))) < 0) { | |||
jack_error("JackOSSAdapter::OpenOutput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
return -1; | |||
} | |||
if (fExcl) { | |||
if (ioctl(fOutFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { | |||
jack_error("JackOSSAdapter::OpenOutput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
goto error; | |||
} | |||
} | |||
printf("fAdaptedBufferSize %d %d %d %d %s\n", fExcl, fAdaptedBufferSize, fSampleSize, fPlaybackChannels, fPlaybackDriverName); | |||
gFragFormat = (2 << 16) + int2pow2(fAdaptedBufferSize * fSampleSize * fPlaybackChannels); | |||
if (ioctl(fOutFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { | |||
jack_error("JackOSSAdapter::OpenOutput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
goto error; | |||
} | |||
cur_sample_format = fSampleFormat; | |||
if (ioctl(fOutFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { | |||
jack_error("JackOSSAdapter::OpenOutput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
goto error; | |||
} | |||
if (cur_sample_format != fSampleFormat) { | |||
jack_info("JackOSSAdapter::OpenOutput driver forced the sample format %ld", fSampleFormat); | |||
} | |||
cur_playback_channels = fPlaybackChannels; | |||
if (ioctl(fOutFD, SNDCTL_DSP_CHANNELS, &fPlaybackChannels) == -1) { | |||
jack_error("JackOSSAdapter::OpenOutput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
goto error; | |||
} | |||
if (cur_playback_channels != fPlaybackChannels) { | |||
jack_info("JackOSSAdapter::OpenOutput driver forced the number of playback channels %ld", fPlaybackChannels); | |||
} | |||
cur_sample_rate = fAdaptedSampleRate; | |||
if (ioctl(fOutFD, SNDCTL_DSP_SPEED, &fAdaptedSampleRate) == -1) { | |||
jack_error("JackOSSAdapter::OpenOutput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
goto error; | |||
} | |||
if (cur_sample_rate != fAdaptedSampleRate) { | |||
jack_info("JackOSSAdapter::OpenInput driver forced the sample rate %ld", fAdaptedSampleRate); | |||
} | |||
fOutputBufferSize = 0; | |||
if (ioctl(fOutFD, SNDCTL_DSP_GETBLKSIZE, &fOutputBufferSize) == -1) { | |||
jack_error("JackOSSAdapter::OpenOutput failed to get fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | |||
goto error; | |||
} | |||
if (fOutputBufferSize != fAdaptedBufferSize * fSampleSize * fPlaybackChannels) { | |||
if (fIgnoreHW) { | |||
jack_info("JackOSSAdapter::OpenOutput driver forced buffer size %ld", fOutputBufferSize); | |||
} else { | |||
jack_error("JackOSSAdapter::OpenInput wanted buffer size cannot be obtained"); | |||
goto error; | |||
} | |||
} | |||
fOutputBuffer = (void*)calloc(fOutputBufferSize, 1); | |||
assert(fOutputBuffer); | |||
fOutputSampleBuffer = (float**)malloc(fPlaybackChannels * sizeof(float*)); | |||
assert(fOutputSampleBuffer); | |||
for (int i = 0; i < fPlaybackChannels; i++) { | |||
fOutputSampleBuffer[i] = (float*)malloc(fAdaptedBufferSize * sizeof(float)); | |||
assert(fOutputSampleBuffer[i]); | |||
} | |||
fFirstCycle = true; | |||
return 0; | |||
error: | |||
::close(fOutFD); | |||
return -1; | |||
} | |||
int JackOSSAdapter::Open() | |||
{ | |||
SetSampleFormat(); | |||
if ((fRWMode & kRead) && (OpenInput() < 0)) { | |||
return -1; | |||
} | |||
if ((fRWMode & kWrite) && (OpenOutput() < 0)) { | |||
return -1; | |||
} | |||
// In duplex mode, check that input and output use the same buffer size | |||
if ((fRWMode & kRead) && (fRWMode & kWrite) && (fInputBufferSize != fOutputBufferSize)) { | |||
jack_error("JackOSSAdapter::OpenAux input and output buffer size are not the same!!"); | |||
goto error; | |||
} | |||
DisplayDeviceInfo(); | |||
fThread.AcquireRealTime(JackServerGlobals::fInstance->GetEngineControl()->fClientPriority); | |||
return fThread.StartSync(); | |||
error: | |||
CloseAux(); | |||
return -1; | |||
} | |||
int JackOSSAdapter::Close() | |||
{ | |||
#ifdef DEBUG | |||
fTable.Save(); | |||
#endif | |||
fThread.Stop(); | |||
CloseAux(); | |||
return 0; | |||
} | |||
void JackOSSAdapter::CloseAux() | |||
{ | |||
if (fRWMode & kRead) { | |||
close(fInFD); | |||
fInFD = -1; | |||
} | |||
if (fRWMode & kWrite) { | |||
close(fOutFD); | |||
fOutFD = -1; | |||
} | |||
free(fInputBuffer); | |||
fInputBuffer = NULL; | |||
free(fOutputBuffer); | |||
fOutputBuffer = NULL; | |||
for (int i = 0; i < fCaptureChannels; i++) { | |||
free(fInputSampleBuffer[i]); | |||
} | |||
free(fInputSampleBuffer); | |||
for (int i = 0; i < fPlaybackChannels; i++) { | |||
free(fOutputSampleBuffer[i]); | |||
} | |||
free(fOutputSampleBuffer); | |||
} | |||
int JackOSSAdapter::Read() | |||
{ | |||
ssize_t count = ::read(fInFD, fInputBuffer, fInputBufferSize); | |||
if (count < fInputBufferSize) { | |||
jack_error("JackOSSAdapter::Read error bytes read = %ld", count); | |||
return -1; | |||
} else { | |||
for (int i = 0; i < fCaptureChannels; i++) { | |||
CopyAndConvertIn(fInputSampleBuffer[i], fInputBuffer, fAdaptedBufferSize, i, fCaptureChannels, fBits); | |||
} | |||
return 0; | |||
} | |||
} | |||
int JackOSSAdapter::Write() | |||
{ | |||
ssize_t count; | |||
// Maybe necessay 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); | |||
} | |||
for (int i = 0; i < fPlaybackChannels; i++) { | |||
CopyAndConvertOut(fOutputBuffer, fOutputSampleBuffer[i], fAdaptedBufferSize, i, fCaptureChannels, fBits); | |||
} | |||
count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize); | |||
if (count < fOutputBufferSize) { | |||
jack_error("JackOSSAdapter::Write error bytes written = %ld", count); | |||
return -1; | |||
} else { | |||
return 0; | |||
} | |||
} | |||
bool JackOSSAdapter::Execute() | |||
{ | |||
if (Read() < 0) | |||
return false; | |||
bool failure = false; | |||
jack_nframes_t time1, time2; | |||
ResampleFactor(time1, time2); | |||
for (int i = 0; i < fCaptureChannels; i++) { | |||
fCaptureRingBuffer[i]->SetRatio(time1, time2); | |||
if (fCaptureRingBuffer[i]->WriteResample(fInputSampleBuffer[i], fAdaptedBufferSize) < fAdaptedBufferSize) | |||
failure = true; | |||
} | |||
for (int i = 0; i < fPlaybackChannels; i++) { | |||
fPlaybackRingBuffer[i]->SetRatio(time2, time1); | |||
if (fPlaybackRingBuffer[i]->ReadResample(fOutputSampleBuffer[i], fAdaptedBufferSize) < fAdaptedBufferSize) | |||
failure = true; | |||
} | |||
#ifdef DEBUG | |||
fTable.Write(time1, time2, double(time1) / double(time2), double(time2) / double(time1), | |||
fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace()); | |||
#endif | |||
if (Write() < 0) | |||
return false; | |||
// Reset all ringbuffers in case of failure | |||
if (failure) { | |||
jack_error("JackOSSAdapter::Execute ringbuffer failure... reset"); | |||
ResetRingBuffers(); | |||
} | |||
return true; | |||
} | |||
int JackOSSAdapter::SetBufferSize(jack_nframes_t buffer_size) | |||
{ | |||
JackAudioAdapterInterface::SetBufferSize(buffer_size); | |||
Close(); | |||
return Open(); | |||
} | |||
} // namespace | |||
#ifdef __cplusplus | |||
extern "C" | |||
{ | |||
#endif | |||
SERVER_EXPORT jack_driver_desc_t* jack_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, "audioadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 | |||
strcpy(desc->desc, "netjack audio <==> net backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 | |||
desc->nparams = OSS_DRIVER_N_PARAMS; | |||
desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); | |||
i = 0; | |||
strcpy(desc->params[i].name, "rate"); | |||
desc->params[i].character = 'r'; | |||
desc->params[i].type = JackDriverParamUInt; | |||
desc->params[i].value.ui = OSS_DRIVER_DEF_FS; | |||
strcpy(desc->params[i].short_desc, "Sample rate"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
i++; | |||
strcpy(desc->params[i].name, "period"); | |||
desc->params[i].character = 'p'; | |||
desc->params[i].type = JackDriverParamUInt; | |||
desc->params[i].value.ui = OSS_DRIVER_DEF_BLKSIZE; | |||
strcpy(desc->params[i].short_desc, "Frames per period"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
i++; | |||
strcpy(desc->params[i].name, "nperiods"); | |||
desc->params[i].character = 'n'; | |||
desc->params[i].type = JackDriverParamUInt; | |||
desc->params[i].value.ui = OSS_DRIVER_DEF_NPERIODS; | |||
strcpy(desc->params[i].short_desc, "Number of periods to prefill output buffer"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
i++; | |||
strcpy(desc->params[i].name, "wordlength"); | |||
desc->params[i].character = 'w'; | |||
desc->params[i].type = JackDriverParamInt; | |||
desc->params[i].value.i = OSS_DRIVER_DEF_BITS; | |||
strcpy(desc->params[i].short_desc, "Word length"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
i++; | |||
strcpy(desc->params[i].name, "inchannels"); | |||
desc->params[i].character = 'i'; | |||
desc->params[i].type = JackDriverParamUInt; | |||
desc->params[i].value.ui = OSS_DRIVER_DEF_INS; | |||
strcpy(desc->params[i].short_desc, "Capture channels"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
i++; | |||
strcpy(desc->params[i].name, "outchannels"); | |||
desc->params[i].character = 'o'; | |||
desc->params[i].type = JackDriverParamUInt; | |||
desc->params[i].value.ui = OSS_DRIVER_DEF_OUTS; | |||
strcpy(desc->params[i].short_desc, "Playback channels"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
i++; | |||
strcpy(desc->params[i].name, "excl"); | |||
desc->params[i].character = 'e'; | |||
desc->params[i].type = JackDriverParamBool; | |||
desc->params[i].value.i = false; | |||
strcpy(desc->params[i].short_desc, "Exclusif (O_EXCL) access mode"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
i++; | |||
strcpy(desc->params[i].name, "capture"); | |||
desc->params[i].character = 'C'; | |||
desc->params[i].type = JackDriverParamString; | |||
strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); | |||
strcpy(desc->params[i].short_desc, "Input device"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
i++; | |||
strcpy(desc->params[i].name, "playback"); | |||
desc->params[i].character = 'P'; | |||
desc->params[i].type = JackDriverParamString; | |||
strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); | |||
strcpy(desc->params[i].short_desc, "Output device"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
i++; | |||
strcpy (desc->params[i].name, "device"); | |||
desc->params[i].character = 'd'; | |||
desc->params[i].type = JackDriverParamString; | |||
strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); | |||
strcpy(desc->params[i].short_desc, "OSS device name"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
i++; | |||
strcpy(desc->params[i].name, "ignorehwbuf"); | |||
desc->params[i].character = 'b'; | |||
desc->params[i].type = JackDriverParamBool; | |||
desc->params[i].value.i = true; | |||
strcpy(desc->params[i].short_desc, "Ignore hardware period size"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
i++; | |||
strcpy(desc->params[i].name, "quality"); | |||
desc->params[i].character = 'q'; | |||
desc->params[i].type = JackDriverParamInt; | |||
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); | |||
return desc; | |||
} | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
@@ -0,0 +1,123 @@ | |||
/* | |||
Copyright (C) 2008 Grame & RTL 2008 | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation; either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
*/ | |||
#ifndef __JackOSSAdapter__ | |||
#define __JackOSSAdapter__ | |||
#include <math.h> | |||
#include <limits.h> | |||
#include <assert.h> | |||
#include "JackAudioAdapterInterface.h" | |||
#include "JackPlatformPlug.h" | |||
#include "JackError.h" | |||
#include "jack.h" | |||
#include "jslist.h" | |||
namespace Jack | |||
{ | |||
typedef jack_default_audio_sample_t jack_sample_t; | |||
#define OSS_DRIVER_N_PARAMS 12 | |||
#define OSS_DRIVER_DEF_DEV "/dev/dsp" | |||
#define OSS_DRIVER_DEF_FS 48000 | |||
#define OSS_DRIVER_DEF_BLKSIZE 1024 | |||
#define OSS_DRIVER_DEF_NPERIODS 2 | |||
#define OSS_DRIVER_DEF_BITS 16 | |||
#define OSS_DRIVER_DEF_INS 2 | |||
#define OSS_DRIVER_DEF_OUTS 2 | |||
/*! | |||
\brief The OSS adapter. | |||
*/ | |||
class JackOSSAdapter : public JackAudioAdapterInterface, public JackRunnableInterface | |||
{ | |||
enum { kRead = 1, kWrite = 2, kReadWrite = 3 }; | |||
private: | |||
JackThread fThread; | |||
char fCaptureDriverName[JACK_CLIENT_NAME_SIZE + 1]; | |||
char fPlaybackDriverName[JACK_CLIENT_NAME_SIZE + 1]; | |||
int fInFD; | |||
int fOutFD; | |||
int fBits; | |||
int fSampleFormat; | |||
int fNperiods; | |||
unsigned int fSampleSize; | |||
int fRWMode; | |||
bool fIgnoreHW; | |||
bool fExcl; | |||
unsigned int fInputBufferSize; | |||
unsigned int fOutputBufferSize; | |||
void* fInputBuffer; | |||
void* fOutputBuffer; | |||
float** fInputSampleBuffer; | |||
float** fOutputSampleBuffer; | |||
bool fFirstCycle; | |||
int OpenInput(); | |||
int OpenOutput(); | |||
void CloseAux(); | |||
void SetSampleFormat(); | |||
void DisplayDeviceInfo(); | |||
public: | |||
JackOSSAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); | |||
~JackOSSAdapter() | |||
{} | |||
int Open(); | |||
int Close(); | |||
int Read(); | |||
int Write(); | |||
int SetBufferSize(jack_nframes_t buffer_size); | |||
bool Execute(); | |||
}; | |||
} | |||
#ifdef __cplusplus | |||
extern "C" | |||
{ | |||
#endif | |||
#include "JackCompilerDeps.h" | |||
#include "driver_interface.h" | |||
EXPORT jack_driver_desc_t* jack_get_descriptor(); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif |
@@ -0,0 +1,126 @@ | |||
/* | |||
Copyright (C) 2003-2007 Jussi Laako <jussi@sonarnerd.net> | |||
Copyright (C) 2008 Grame & RTL 2008 | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation; either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
*/ | |||
#ifndef __JackOSSDriver__ | |||
#define __JackOSSDriver__ | |||
#include "JackAudioDriver.h" | |||
namespace Jack | |||
{ | |||
typedef jack_default_audio_sample_t jack_sample_t; | |||
#define OSS_DRIVER_N_PARAMS 13 | |||
#define OSS_DRIVER_DEF_DEV "/dev/dsp" | |||
#define OSS_DRIVER_DEF_FS 48000 | |||
#define OSS_DRIVER_DEF_BLKSIZE 1024 | |||
#define OSS_DRIVER_DEF_NPERIODS 1 | |||
#define OSS_DRIVER_DEF_BITS 16 | |||
#define OSS_DRIVER_DEF_INS 2 | |||
#define OSS_DRIVER_DEF_OUTS 2 | |||
/*! | |||
\brief The OSS driver. | |||
*/ | |||
class JackOSSDriver : public JackAudioDriver | |||
{ | |||
enum { kRead = 1, kWrite = 2, kReadWrite = 3 }; | |||
private: | |||
int fInFD; | |||
int fOutFD; | |||
int fBits; | |||
int fSampleFormat; | |||
int fNperiods; | |||
unsigned int fSampleSize; | |||
int fRWMode; | |||
bool fExcl; | |||
bool fIgnoreHW; | |||
unsigned int fInputBufferSize; | |||
unsigned int fOutputBufferSize; | |||
void* fInputBuffer; | |||
void* fOutputBuffer; | |||
bool fFirstCycle; | |||
int OpenInput(); | |||
int OpenOutput(); | |||
int OpenAux(); | |||
void CloseAux(); | |||
void SetSampleFormat(); | |||
void DisplayDeviceInfo(); | |||
// Redefining since timing for CPU load is specific | |||
int ProcessSync(); | |||
public: | |||
JackOSSDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) | |||
: JackAudioDriver(name, alias, engine, table), | |||
fInFD(-1), fOutFD(-1), fBits(0), | |||
fSampleFormat(0), fNperiods(0), fRWMode(0), fExcl(false), fIgnoreHW(true), | |||
fInputBufferSize(0), fOutputBufferSize(0), | |||
fInputBuffer(NULL), fOutputBuffer(NULL), fFirstCycle(true) | |||
{} | |||
virtual ~JackOSSDriver() | |||
{} | |||
int Open(jack_nframes_t frames_per_cycle, | |||
int user_nperiods, | |||
jack_nframes_t rate, | |||
bool capturing, | |||
bool playing, | |||
int chan_in, | |||
int chan_out, | |||
bool vmix, | |||
bool monitor, | |||
const char* capture_driver_name, | |||
const char* playback_driver_name, | |||
jack_nframes_t capture_latency, | |||
jack_nframes_t playback_latency, | |||
int bits, | |||
bool ignorehwbuf); | |||
int Close(); | |||
int Read(); | |||
int Write(); | |||
// BufferSize can be changed | |||
bool IsFixedBufferSize() | |||
{ | |||
return false; | |||
} | |||
int SetBufferSize(jack_nframes_t buffer_size); | |||
}; | |||
} // end of namespace | |||
#endif |
@@ -0,0 +1,34 @@ | |||
#! /usr/bin/env python | |||
# encoding: utf-8 | |||
def create_jack_driver_obj(bld, target, sources, uselib = None): | |||
driver = bld.new_task_gen('cxx', 'shlib') | |||
driver.features.append('cc') | |||
driver.env['shlib_PATTERN'] = 'jack_%s.so' | |||
#driver.env.append_unique('CXXFLAGS', '-march=i686 -msse3 -ffast-math') | |||
#driver.env.append_unique('CCFLAGS', '-march=i686 -msse3 -ffast-math') | |||
driver.defines = 'HAVE_CONFIG_H' | |||
driver.includes = ['.', '..','../posix', '../common', '../common/jack'] | |||
driver.target = target | |||
driver.source = sources | |||
driver.install_path = '${ADDON_DIR}/' | |||
driver.uselib_local = 'serverlib' | |||
if uselib: | |||
driver.uselib = uselib | |||
return driver | |||
def build(bld): | |||
jackd = bld.new_task_gen('cxx', 'program') | |||
jackd.includes = ['.','..', '../posix', '../common/jack', '../common'] | |||
jackd.defines = 'HAVE_CONFIG_H' | |||
jackd.source = ['../common/Jackdmp.cpp'] | |||
jackd.uselib = 'PTHREAD DL' | |||
jackd.uselib_local = 'serverlib' | |||
jackd.target = 'jackd' | |||
create_jack_driver_obj(bld, 'oss', ['oss/JackOSSDriver.cpp', '../common/memops.c']) | |||
create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') | |||
create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') | |||
@@ -1,4 +1,4 @@ | |||
#!/bin/sh | |||
#!/bin/bash | |||
#set -x | |||
@@ -17,10 +17,12 @@ def build(bld): | |||
for test_program, test_program_sources in test_programs.items(): | |||
prog = bld.new_task_gen('cxx', 'program') | |||
prog.features.append('cc') | |||
if bld.env['IS_MACOSX']: | |||
prog.includes = ['../macosx', '../posix', '../common/jack', '../common'] | |||
if bld.env['IS_LINUX']: | |||
prog.includes = ['../linux', '../posix', '../common/jack', '../common'] | |||
if bld.env['IS_MACOSX']: | |||
prog.includes = ['..','../macosx', '../posix', '../common/jack', '../common'] | |||
if bld.env['IS_LINUX']: | |||
prog.includes = ['..','../linux', '../posix', '../common/jack', '../common'] | |||
if bld.env['IS_SUN']: | |||
prog.includes = ['..','../solaris', '../posix', '../common/jack', '../common'] | |||
prog.source = test_program_sources | |||
if bld.env['IS_LINUX']: | |||
prog.uselib = 'RT' | |||
@@ -180,10 +180,10 @@ error: | |||
int JackPortAudioDriver::Close() | |||
{ | |||
JackAudioDriver::Close(); | |||
int res = JackAudioDriver::Close(); | |||
jack_log("JackPortAudioDriver::Close"); | |||
Pa_CloseStream(fStream); | |||
return 0; | |||
return res; | |||
} | |||
int JackPortAudioDriver::Start() | |||
@@ -348,7 +348,6 @@ extern "C" | |||
strcpy(desc->params[i].name, "device"); | |||
desc->params[i].character = 'd'; | |||
desc->params[i].type = JackDriverParamString; | |||
desc->params[i].value.ui = 128U; | |||
strcpy(desc->params[i].value.str, "will take default PortAudio device name"); | |||
strcpy(desc->params[i].short_desc, "PortAudio device name"); | |||
strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | |||
@@ -386,8 +385,8 @@ extern "C" | |||
jack_nframes_t frames_per_interrupt = 512; | |||
const char* capture_pcm_name = ""; | |||
const char* playback_pcm_name = ""; | |||
int capture = FALSE; | |||
int playback = FALSE; | |||
bool capture = false; | |||
bool playback = false; | |||
int chan_in = 0; | |||
int chan_out = 0; | |||
bool monitor = false; | |||
@@ -410,26 +409,25 @@ extern "C" | |||
break; | |||
case 'D': | |||
capture = TRUE; | |||
playback = TRUE; | |||
capture = true; | |||
playback = true; | |||
break; | |||
case 'c': | |||
chan_in = chan_out = (int) param->value.ui; | |||
chan_in = chan_out = (int)param->value.ui; | |||
break; | |||
case 'i': | |||
chan_in = (int) param->value.ui; | |||
chan_in = (int)param->value.ui; | |||
break; | |||
case 'o': | |||
chan_out = (int) param->value.ui; | |||
chan_out = (int)param->value.ui; | |||
break; | |||
case 'C': | |||
capture = TRUE; | |||
if (strcmp(param->value.str, "none") != 0) | |||
{ | |||
capture = true; | |||
if (strcmp(param->value.str, "none") != 0) { | |||
capture_pcm_name = strdup(param->value.str); | |||
} | |||
break; | |||
@@ -450,7 +448,7 @@ extern "C" | |||
break; | |||
case 'p': | |||
frames_per_interrupt = (unsigned int) param->value.ui; | |||
frames_per_interrupt = (unsigned int)param->value.ui; | |||
break; | |||
case 'I': | |||
@@ -469,8 +467,8 @@ extern "C" | |||
// duplex is the default | |||
if (!capture && !playback) { | |||
capture = TRUE; | |||
playback = TRUE; | |||
capture = true; | |||
playback = true; | |||
} | |||
Jack::JackDriverClientInterface* driver = new Jack::JackPortAudioDriver("system", "portaudio", engine, table, pa_devices); | |||
@@ -63,7 +63,9 @@ def set_options(opt): | |||
opt.add_option('--libdir', type='string', help="Library directory [Default: <prefix>/lib]") | |||
opt.add_option('--dbus', action='store_true', default=False, help='Enable D-Bus JACK (jackdbus)') | |||
opt.add_option('--doxygen', action='store_true', default=False, help='Enable build of doxygen documentation') | |||
opt.add_option('--monitor', action='store_true', default=False, help='Build with monitoring records') | |||
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('--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.sub_options('dbus') | |||
@@ -72,6 +74,7 @@ def configure(conf): | |||
platform = Utils.detect_platform() | |||
conf.env['IS_MACOSX'] = platform == 'darwin' | |||
conf.env['IS_LINUX'] = platform == 'linux' | |||
conf.env['IS_SUN'] = platform == 'sunos' | |||
if conf.env['IS_LINUX']: | |||
Utils.pprint('CYAN', "Linux detected") | |||
@@ -79,9 +82,26 @@ def configure(conf): | |||
if conf.env['IS_MACOSX']: | |||
Utils.pprint('CYAN', "MacOS X detected") | |||
conf.check_tool('compiler_cxx') | |||
conf.check_tool('compiler_cc') | |||
if conf.env['IS_SUN']: | |||
Utils.pprint('CYAN', "SunOS detected") | |||
if conf.env['IS_LINUX']: | |||
conf.check_tool('compiler_cxx') | |||
conf.check_tool('compiler_cc') | |||
if conf.env['IS_MACOSX']: | |||
conf.check_tool('compiler_cxx') | |||
conf.check_tool('compiler_cc') | |||
# waf 1.5 : check_tool('compiler_cxx') and check_tool('compiler_cc') do not work correctly, so explicit use of gcc and g++ | |||
if conf.env['IS_SUN']: | |||
conf.check_tool('g++') | |||
conf.check_tool('gcc') | |||
#if conf.env['IS_SUN']: | |||
# conf.check_tool('compiler_cxx') | |||
# conf.check_tool('compiler_cc') | |||
conf.env.append_unique('CXXFLAGS', '-O3 -Wall') | |||
conf.env.append_unique('CCFLAGS', '-O3 -Wall') | |||
@@ -99,7 +119,7 @@ def configure(conf): | |||
conf.env['JACK_VERSION'] = VERSION | |||
conf.env['BUILD_DOXYGEN_DOCS'] = Options.options.doxygen | |||
conf.env['BUILD_WITH_MONITOR'] = Options.options.monitor | |||
conf.env['BUILD_WITH_PROFILE'] = Options.options.profile | |||
if Options.options.libdir: | |||
conf.env['LIBDIR'] = Options.options.libdir | |||
@@ -115,7 +135,7 @@ def configure(conf): | |||
conf.define('JACKMP', 1) | |||
if conf.env['BUILD_JACKDBUS'] == True: | |||
conf.define('JACK_DBUS', 1) | |||
if conf.env['BUILD_WITH_MONITOR'] == True: | |||
if conf.env['BUILD_WITH_PROFILE'] == True: | |||
conf.define('JACK_MONITOR', 1) | |||
conf.write_config_header('config.h') | |||
@@ -142,7 +162,8 @@ def configure(conf): | |||
display_msg("Library directory", conf.env['LIBDIR'], 'CYAN') | |||
display_msg("Drivers directory", conf.env['ADDON_DIR'], 'CYAN') | |||
display_feature('Build doxygen documentation', conf.env['BUILD_DOXYGEN_DOCS']) | |||
display_feature('Build with monitoring records', conf.env['BUILD_WITH_MONITOR']) | |||
display_feature('Build with engine profiling', conf.env['BUILD_WITH_PROFILE']) | |||
if conf.env['IS_LINUX']: | |||
display_feature('Build with ALSA support', conf.env['BUILD_DRIVER_ALSA'] == True) | |||
@@ -171,14 +192,15 @@ def build(bld): | |||
if not os.access('svnversion.h', os.R_OK): | |||
create_svnversion_task(bld) | |||
# process subfolders from here | |||
# process subfolders from here | |||
bld.add_subdirs('common') | |||
if bld.env['IS_LINUX']: | |||
bld.add_subdirs('linux') | |||
if bld.env['BUILD_JACKDBUS'] == True: | |||
bld.add_subdirs('dbus') | |||
bld.add_subdirs('example-clients') | |||
bld.add_subdirs('tests') | |||
if bld.env['BUILD_JACKDBUS'] == True: | |||
bld.add_subdirs('dbus') | |||
if bld.env['IS_MACOSX']: | |||
bld.add_subdirs('macosx') | |||
bld.add_subdirs('example-clients') | |||
@@ -186,6 +208,13 @@ def build(bld): | |||
if bld.env['BUILD_JACKDBUS'] == True: | |||
bld.add_subdirs('dbus') | |||
if bld.env['IS_SUN']: | |||
bld.add_subdirs('solaris') | |||
bld.add_subdirs('example-clients') | |||
bld.add_subdirs('tests') | |||
if bld.env['BUILD_JACKDBUS'] == True: | |||
bld.add_subdirs('dbus') | |||
if bld.env['BUILD_DOXYGEN_DOCS'] == True: | |||
share_dir = bld.env.get_destdir() + bld.env['PREFIX'] + '/share/jack-audio-connection-kit' | |||
html_docs_source_dir = "build/default/html" | |||