git-svn-id: svn+ssh://jackaudio.org/trunk/jack@350 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.109.0
@@ -13,7 +13,7 @@ dnl micro version = incremented when implementation-only | |||
dnl changes are made | |||
dnl --- | |||
JACK_MAJOR_VERSION=0 | |||
JACK_MINOR_VERSION=62 | |||
JACK_MINOR_VERSION=63 | |||
JACK_MICRO_VERSION=0 | |||
dnl --- | |||
@@ -41,7 +41,7 @@ dnl slacker than this, and closer to those for the JACK version | |||
dnl number. | |||
dnl --- | |||
JACK_API_CURRENT=0 | |||
JACK_API_REVISION=10 | |||
JACK_API_REVISION=11 | |||
JACK_API_AGE=0 | |||
AC_SUBST(JACK_MAJOR_VERSION) | |||
@@ -35,7 +35,7 @@ | |||
#include <jack/hdsp.h> | |||
#include <jack/ice1712.h> | |||
#include <jack/generic.h> | |||
#include <jack/cycles.h> | |||
#include <jack/time.h> | |||
extern void store_work_time (int); | |||
extern void store_wait_time (int); | |||
@@ -134,7 +134,7 @@ alsa_driver_generic_hardware (alsa_driver_t *driver) | |||
} | |||
static int | |||
alsa_driver_hw_specific (alsa_driver_t *driver, int hw_monitoring) | |||
alsa_driver_hw_specific (alsa_driver_t *driver, int hw_monitoring, int hw_metering) | |||
{ | |||
int err; | |||
@@ -172,6 +172,14 @@ alsa_driver_hw_specific (alsa_driver_t *driver, int hw_monitoring) | |||
driver->has_clock_sync_reporting = FALSE; | |||
} | |||
if (driver->hw->capabilities & Cap_HardwareMetering) { | |||
driver->has_hw_metering = TRUE; | |||
driver->hw_metering = hw_metering; | |||
} else { | |||
driver->has_hw_metering = FALSE; | |||
driver->hw_metering = FALSE; | |||
} | |||
return 0; | |||
} | |||
@@ -860,7 +868,7 @@ alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float *delay | |||
nfds++; | |||
} | |||
poll_enter = get_cycles (); | |||
poll_enter = jack_get_microseconds (); | |||
if (poll (driver->pfd, nfds, (int) floor ((1.5f * driver->period_usecs) / 1000.0f)) < 0) { | |||
if (errno == EINTR) { | |||
@@ -880,7 +888,7 @@ alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float *delay | |||
} | |||
poll_ret = get_cycles (); | |||
poll_ret = jack_get_microseconds (); | |||
if (extra_fd < 0) { | |||
if (driver->poll_next && poll_ret > driver->poll_next) { | |||
@@ -888,7 +896,7 @@ alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float *delay | |||
} | |||
driver->poll_last = poll_ret; | |||
driver->poll_next = poll_ret + (unsigned long long) floor ((driver->period_usecs * driver->cpu_mhz)); | |||
driver->engine->control->current_time.cycles = poll_ret; | |||
driver->engine->control->current_time.usecs = poll_ret; | |||
} | |||
#ifdef DEBUG_WAKEUP | |||
@@ -1228,6 +1236,11 @@ alsa_driver_attach (alsa_driver_t *driver, jack_engine_t *engine) | |||
break; | |||
} | |||
if (driver->hw_metering) { | |||
jack_port_set_peak_function(port, driver->hw->get_hardware_peak); | |||
jack_port_set_power_function(port, driver->hw->get_hardware_power); | |||
} | |||
/* XXX fix this so that it can handle: systemic (external) latency | |||
*/ | |||
@@ -1246,6 +1259,11 @@ alsa_driver_attach (alsa_driver_t *driver, jack_engine_t *engine) | |||
break; | |||
} | |||
if (driver->hw_metering) { | |||
jack_port_set_peak_function(port, driver->hw->get_hardware_peak); | |||
jack_port_set_power_function(port, driver->hw->get_hardware_power); | |||
} | |||
/* XXX fix this so that it can handle: systemic (external) latency | |||
*/ | |||
@@ -1397,6 +1415,7 @@ alsa_driver_new (char *name, char *alsa_device, | |||
jack_nframes_t user_nperiods, | |||
jack_nframes_t rate, | |||
int hw_monitoring, | |||
int hw_metering, | |||
int capturing, | |||
int playing, | |||
DitherAlgorithm dither, | |||
@@ -1406,9 +1425,9 @@ alsa_driver_new (char *name, char *alsa_device, | |||
alsa_driver_t *driver; | |||
printf ("creating alsa driver ... %s|%lu|%lu|%lu|%s|%s\n", | |||
printf ("creating alsa driver ... %s|%lu|%lu|%lu|%s|%s|%s\n", | |||
alsa_device, frames_per_cycle, user_nperiods, rate, | |||
hw_monitoring ? "hwmon":"swmon", soft_mode ? "soft-mode":"rt"); | |||
hw_monitoring ? "hwmon":"swmon", hw_metering ? "hwmeter":"swmeter", soft_mode ? "soft-mode":"rt"); | |||
driver = (alsa_driver_t *) calloc (1, sizeof (alsa_driver_t)); | |||
@@ -1560,7 +1579,7 @@ alsa_driver_new (char *name, char *alsa_device, | |||
} | |||
} | |||
alsa_driver_hw_specific (driver, hw_monitoring); | |||
alsa_driver_hw_specific (driver, hw_monitoring, hw_metering); | |||
driver->client = client; | |||
@@ -1630,6 +1649,7 @@ alsa_usage () | |||
" -p,--period <n> \tframes per period (default: 1024)\n" | |||
" -n,--nperiods <n> \tnumber of periods in hardware buffer (default: 2)\n" | |||
" -H,--hwmon \tuse hardware monitoring, if available (default: no)\n" | |||
" -M,--hwmeter \tuse hardware metering, if available (default: no)\n" | |||
" -D,--duplex \tduplex I/O (default: yes)\n" | |||
" -C,--capture \tcapture input (default: duplex)\n" | |||
" -P,--playback\tplayback output (default: duplex)\n" | |||
@@ -1649,6 +1669,34 @@ alsa_error (char *type, char *value) | |||
alsa_usage(); | |||
} | |||
static int | |||
dither_opt (char c, DitherAlgorithm* dither) | |||
{ | |||
switch (*optarg) { | |||
case '-': | |||
*dither = None; | |||
break; | |||
case 'r': | |||
*dither = Rectangular; | |||
break; | |||
case 's': | |||
*dither = Shaped; | |||
break; | |||
case 't': | |||
*dither = Triangular; | |||
break; | |||
default: | |||
alsa_error ("illegal dithering mode", ""); | |||
return -1; | |||
} | |||
return 0; | |||
} | |||
/* DRIVER "PLUGIN" INTERFACE */ | |||
const char driver_client_name[] = "alsa_pcm"; | |||
@@ -1661,11 +1709,13 @@ driver_initialize (jack_client_t *client, int argc, char **argv) | |||
unsigned long user_nperiods = 2; | |||
char *pcm_name = "default"; | |||
int hw_monitoring = FALSE; | |||
int hw_metering = FALSE; | |||
int capture = FALSE; | |||
int playback = FALSE; | |||
int soft_mode = FALSE; | |||
DitherAlgorithm dither = None; | |||
int opt; | |||
char *envvar; | |||
char optstring[2]; /* string made from opt char */ | |||
struct option long_options[] = | |||
{ | |||
@@ -1673,6 +1723,7 @@ driver_initialize (jack_client_t *client, int argc, char **argv) | |||
{ "duplex", 0, NULL, 'D' }, | |||
{ "device", 1, NULL, 'd' }, | |||
{ "hwmon", 0, NULL, 'H' }, | |||
{ "hwmeter", 0, NULL, 'M' }, | |||
{ "help", 0, NULL, 'h' }, | |||
{ "playback", 0, NULL, 'P' }, | |||
{ "period", 1, NULL, 'p' }, | |||
@@ -1683,13 +1734,57 @@ driver_initialize (jack_client_t *client, int argc, char **argv) | |||
{ 0, 0, 0, 0 } | |||
}; | |||
/* before we do anything else, see if there are environment variables | |||
for each parameter. | |||
*/ | |||
if ((envvar = getenv ("JACK_ALSA_DEVICE")) != NULL) { | |||
pcm_name = envvar; | |||
} | |||
if ((envvar = getenv ("JACK_ALSA_HWMON")) != NULL) { | |||
hw_monitoring = TRUE; | |||
} | |||
if ((envvar = getenv ("JACK_ALSA_SOFTMODE")) != NULL) { | |||
soft_mode = TRUE; | |||
} | |||
if ((envvar = getenv ("JACK_ALSA_PERIOD_FRAMES")) != NULL) { | |||
frames_per_interrupt = atoi (envvar); | |||
} | |||
if ((envvar = getenv ("JACK_ALSA_PERIODS")) != NULL) { | |||
user_nperiods = atoi (envvar); | |||
} | |||
if ((envvar = getenv ("JACK_ALSA_SRATE")) != NULL) { | |||
srate = atoi (envvar); | |||
} | |||
if ((envvar = getenv ("JACK_ALSA_DITHER")) != NULL) { | |||
if (dither_opt (*envvar, &dither)) { | |||
return NULL; | |||
} | |||
} | |||
if ((envvar = getenv ("JACK_ALSA_CAPTURE")) != NULL) { | |||
capture = atoi (envvar); | |||
} | |||
if ((envvar = getenv ("JACK_ALSA_PLAYBACK")) != NULL) { | |||
playback = atoi (envvar); | |||
} | |||
/* | |||
* Setting optind back to zero is a hack to reinitialize a new | |||
* getopts() loop. See declaration in <getopt.h>. | |||
*/ | |||
optind = 0; | |||
opterr = 0; | |||
while ((opt = getopt_long(argc, argv, "-CDd:HPp:r:n:sz::", | |||
while ((opt = getopt_long(argc, argv, "-CDd:HMPp:r:n:sz::", | |||
long_options, NULL)) | |||
!= EOF) { | |||
switch (opt) { | |||
@@ -1715,6 +1810,10 @@ driver_initialize (jack_client_t *client, int argc, char **argv) | |||
alsa_usage(); | |||
return NULL; | |||
case 'M': | |||
hw_metering = TRUE; | |||
break; | |||
case 'P': | |||
playback = TRUE; | |||
break; | |||
@@ -1739,26 +1838,7 @@ driver_initialize (jack_client_t *client, int argc, char **argv) | |||
if (optarg == NULL) { | |||
dither = None; | |||
} else { | |||
switch (*optarg) { | |||
case '-': | |||
dither = None; | |||
break; | |||
case 'r': | |||
dither = Rectangular; | |||
break; | |||
case 's': | |||
dither = Shaped; | |||
break; | |||
case 't': | |||
dither = Triangular; | |||
break; | |||
default: | |||
alsa_error("dithering mode", optarg); | |||
if (dither_opt (*optarg, &dither)) { | |||
return NULL; | |||
} | |||
} | |||
@@ -1784,7 +1864,7 @@ driver_initialize (jack_client_t *client, int argc, char **argv) | |||
} | |||
return alsa_driver_new ("alsa_pcm", pcm_name, client, frames_per_interrupt, | |||
user_nperiods, srate, hw_monitoring, capture, | |||
user_nperiods, srate, hw_monitoring, hw_metering, capture, | |||
playback, dither, soft_mode); | |||
} | |||
@@ -174,6 +174,16 @@ static int hdsp_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) | |||
return -1; | |||
} | |||
static double hdsp_get_hardware_peak (jack_port_t *port, jack_nframes_t frame) | |||
{ | |||
return 0; | |||
} | |||
static double hdsp_get_hardware_power (jack_port_t *port, jack_nframes_t frame) | |||
{ | |||
return 0; | |||
} | |||
void | |||
jack_alsa_hdsp_release (jack_hardware_t *hw) | |||
@@ -198,14 +208,16 @@ jack_alsa_hdsp_hw_new (alsa_driver_t *driver) | |||
/* Not using clock lock-sync-whatever in home hardware setup */ | |||
/* yet. Will write this code when can test it. */ | |||
/* hw->capabilities = Cap_HardwareMonitoring|Cap_AutoSync|Cap_WordClock|Cap_ClockMaster|Cap_ClockLockReporting; */ | |||
hw->capabilities = Cap_HardwareMonitoring; | |||
hw->capabilities = Cap_HardwareMonitoring | Cap_HardwareMetering; | |||
hw->input_monitor_mask = 0; | |||
hw->private = 0; | |||
hw->set_input_monitor_mask = hdsp_set_input_monitor_mask; | |||
hw->change_sample_clock = hdsp_change_sample_clock; | |||
hw->release = jack_alsa_hdsp_release; | |||
hw->get_hardware_peak = hdsp_get_hardware_peak; | |||
hw->get_hardware_power = hdsp_get_hardware_power; | |||
h = (hdsp_t *) malloc (sizeof (hdsp_t)); | |||
h->driver = driver; | |||
hw->private = h; | |||
@@ -98,6 +98,7 @@ typedef struct { | |||
char soft_mode : 1; | |||
char hw_monitoring : 1; | |||
char hw_metering : 1; | |||
char all_monitor_in : 1; | |||
char capture_and_playback_not_synced : 1; | |||
char interleaved : 1; | |||
@@ -115,7 +116,7 @@ typedef struct { | |||
unsigned long next_clock_sync_listener_id; | |||
char has_clock_sync_reporting : 1; | |||
char has_hw_monitoring : 1; | |||
char has_hw_metering : 1; | |||
} alsa_driver_t; | |||
static __inline__ void alsa_driver_mark_channel_done (alsa_driver_t *driver, channel_t chn) { | |||
@@ -87,7 +87,6 @@ struct _jack_engine { | |||
char asio_mode; | |||
int reordered; | |||
int watchdog_check; | |||
float cpu_mhz; | |||
struct _jack_client_internal *current_client; | |||
@@ -34,7 +34,8 @@ typedef enum { | |||
Cap_AutoSync = 0x2, | |||
Cap_WordClock = 0x4, | |||
Cap_ClockMaster = 0x8, | |||
Cap_ClockLockReporting = 0x10 | |||
Cap_ClockLockReporting = 0x10, | |||
Cap_HardwareMetering = 0x20 | |||
} Capabilities; | |||
struct _jack_hardware; | |||
@@ -42,6 +43,9 @@ struct _jack_hardware; | |||
typedef void (*JackHardwareReleaseFunction)(struct _jack_hardware *); | |||
typedef int (*JackHardwareSetInputMonitorMaskFunction)(struct _jack_hardware *, unsigned long); | |||
typedef int (*JackHardwareChangeSampleClockFunction)(struct _jack_hardware *, SampleClockMode); | |||
typedef double (*JackHardwareGetHardwarePeak)(jack_port_t *port, jack_nframes_t frames); | |||
typedef double (*JackHardwareGetHardwarePower)(jack_port_t *port, jack_nframes_t frames); | |||
typedef struct _jack_hardware { | |||
@@ -51,7 +55,8 @@ typedef struct _jack_hardware { | |||
JackHardwareChangeSampleClockFunction change_sample_clock; | |||
JackHardwareSetInputMonitorMaskFunction set_input_monitor_mask; | |||
JackHardwareReleaseFunction release; | |||
JackHardwareGetHardwarePeak get_hardware_peak; | |||
JackHardwareGetHardwarePower get_hardware_power; | |||
void *private; | |||
} jack_hardware_t; | |||
@@ -33,11 +33,11 @@ | |||
#include <jack/types.h> | |||
#include <jack/port.h> | |||
#include <jack/transport.h> | |||
#include <jack/cycles.h> | |||
#include <jack/time.h> | |||
#ifdef DEBUG_ENABLED | |||
#define DEBUG(format,args...) \ | |||
printf ("jack:%5d:%Lu %s:%s:%d: " format "\n", getpid(), get_cycles(), __FILE__, __FUNCTION__, __LINE__ , ## args) | |||
printf ("jack:%5d:%Lu %s:%s:%d: " format "\n", getpid(), jack_get_microseconds(), __FILE__, __FUNCTION__, __LINE__ , ## args) | |||
#else | |||
#define DEBUG(format,args...) | |||
#endif | |||
@@ -69,7 +69,7 @@ typedef struct _time_info | |||
{ | |||
jack_nframes_t frame; | |||
jack_nframes_t frame_rate; | |||
cycles_t cycles; | |||
jack_time_t usecs; | |||
jack_transport_state_t transport_state; | |||
jack_nframes_t loop_start; | |||
jack_nframes_t loop_end; | |||
@@ -94,7 +94,7 @@ typedef struct _time_info | |||
typedef struct { | |||
volatile unsigned long long guard1; | |||
volatile jack_nframes_t frames; | |||
volatile cycles_t stamp; | |||
volatile jack_time_t stamp; | |||
volatile unsigned long long guard2; | |||
} jack_frame_timer_t; | |||
@@ -302,8 +302,6 @@ void handle_internal_client_request (jack_control_t*, jack_request_t*); | |||
extern char *jack_server_dir; | |||
extern int jack_get_mhz (void); | |||
extern void jack_error (const char *fmt, ...); | |||
#endif /* __jack_internal_h__ */ | |||
@@ -550,8 +550,8 @@ jack_nframes_t jack_frame_time (const jack_client_t *); | |||
/** | |||
* This returns the current CPU load estimated by JACK | |||
* as a percentage. The load is computed by measuring | |||
* the number of cycles it took to execute all clients | |||
* as a fraction of the total number of cycles | |||
* the amount of time it took to execute all clients | |||
* as a fraction of the total amount of time | |||
* represented by the data that was processed. | |||
*/ | |||
float jack_cpu_load (jack_client_t *client); | |||
@@ -33,6 +33,13 @@ typedef unsigned long jack_nframes_t; | |||
*/ | |||
#define JACK_MAX_FRAMES ULONG_MAX; | |||
/** | |||
* Type used to represent the value of free running | |||
* monotonic clock with units of microseconds. | |||
*/ | |||
typedef unsigned long long jack_time_t; | |||
/** | |||
* jack_port_t is an opaque type. You may only access it using the API provided. | |||
*/ | |||
@@ -43,7 +43,7 @@ | |||
#include <jack/internal.h> | |||
#include <jack/engine.h> | |||
#include <jack/driver.h> | |||
#include <jack/cycles.h> | |||
#include <jack/time.h> | |||
#include <jack/version.h> | |||
#ifdef USE_CAPABILITIES | |||
@@ -458,13 +458,11 @@ jack_process (jack_engine_t *engine, jack_nframes_t nframes) | |||
jack_client_internal_t *client; | |||
jack_client_control_t *ctl; | |||
JSList *node; | |||
char c; | |||
int status; | |||
char c; | |||
float delayed_usecs; | |||
unsigned long long now, then; | |||
c = get_cycles(); | |||
engine->process_errors = 0; | |||
for (node = engine->clients; node; node = jack_slist_next (node)) { | |||
@@ -522,7 +520,7 @@ jack_process (jack_engine_t *engine, jack_nframes_t nframes) | |||
/* external subgraph */ | |||
ctl->state = Triggered; // a race exists if we do this after the write(2) | |||
ctl->signalled_at = get_cycles(); | |||
ctl->signalled_at = jack_get_microseconds(); | |||
ctl->awake_at = 0; | |||
ctl->finished_at = 0; | |||
@@ -536,7 +534,7 @@ jack_process (jack_engine_t *engine, jack_nframes_t nframes) | |||
break; | |||
} | |||
then = get_cycles (); | |||
then = jack_get_microseconds (); | |||
if (engine->asio_mode) { | |||
engine->driver->wait (engine->driver, client->subgraph_wait_fd, &status, &delayed_usecs); | |||
@@ -569,19 +567,19 @@ jack_process (jack_engine_t *engine, jack_nframes_t nframes) | |||
} | |||
} | |||
now = get_cycles(); | |||
now = jack_get_microseconds (); | |||
if (status != 0) { | |||
if (engine->verbose) { | |||
fprintf (stderr, "at %Lu client waiting on %d took %.9f usecs, status = %d sig = %Lu awa = %Lu fin = %Lu dur=%.6f\n", | |||
fprintf (stderr, "at %Lu client waiting on %d took %Lu usecs, status = %d sig = %Lu awa = %Lu fin = %Lu dur=%Lu\n", | |||
now, | |||
client->subgraph_wait_fd, | |||
(float) (now - then) / engine->cpu_mhz, | |||
now - then, | |||
status, | |||
ctl->signalled_at, | |||
ctl->awake_at, | |||
ctl->finished_at, | |||
((float) (ctl->finished_at - ctl->signalled_at)) / engine->cpu_mhz); | |||
ctl->finished_at - ctl->signalled_at); | |||
} | |||
/* we can only consider the timeout a client error if it actually woke up. | |||
@@ -628,7 +626,7 @@ jack_engine_post_process (jack_engine_t *engine) | |||
JSList *node; | |||
int need_remove = FALSE; | |||
engine->control->pending_time.cycles = engine->control->current_time.cycles; | |||
engine->control->pending_time.usecs = engine->control->current_time.usecs; | |||
engine->control->current_time = engine->control->pending_time; | |||
/* find any clients that need removal due to timeouts, etc. */ | |||
@@ -1590,6 +1588,7 @@ jack_engine_new (int realtime, int rtpriority, int verbose) | |||
uid_t uid = getuid (); | |||
uid_t euid = geteuid (); | |||
#endif | |||
jack_init_time (); | |||
engine = (jack_engine_t *) malloc (sizeof (jack_engine_t)); | |||
@@ -1608,7 +1607,6 @@ jack_engine_new (int realtime, int rtpriority, int verbose) | |||
engine->silent_buffer = 0; | |||
engine->verbose = verbose; | |||
engine->asio_mode = FALSE; | |||
engine->cpu_mhz = jack_get_mhz(); | |||
jack_engine_reset_rolling_usecs (engine); | |||
@@ -1843,7 +1841,7 @@ jack_inc_frame_time (jack_engine_t *engine, jack_nframes_t amount) | |||
time->guard1++; | |||
time->frames += amount; | |||
time->stamp = get_cycles (); | |||
time->stamp = jack_get_microseconds (); | |||
// atomic_inc (&time->guard2, 1); | |||
// might need a memory barrier here | |||
@@ -1960,12 +1958,12 @@ jack_main_thread (void *arg) | |||
break; | |||
} | |||
cycle_end = get_cycles (); | |||
cycle_end = jack_get_microseconds (); | |||
/* store the execution time for later averaging */ | |||
engine->rolling_client_usecs[engine->rolling_client_usecs_index++] = | |||
(float) (cycle_end - engine->control->current_time.cycles) / engine->cpu_mhz; | |||
cycle_end - engine->control->current_time.usecs; | |||
if (engine->rolling_client_usecs_index >= JACK_ENGINE_ROLLING_COUNT) { | |||
engine->rolling_client_usecs_index = 0; | |||
@@ -40,7 +40,7 @@ | |||
#include <jack/engine.h> | |||
#include <jack/pool.h> | |||
#include <jack/error.h> | |||
#include <jack/cycles.h> | |||
#include <jack/time.h> | |||
#include <jack/jslist.h> | |||
#include <jack/version.h> | |||
@@ -50,6 +50,8 @@ | |||
#include <jack/timestamps.h> | |||
#endif /* WITH_TIMESTAMPS */ | |||
jack_time_t __jack_cpu_mhz; | |||
char *jack_server_dir = "/tmp"; | |||
void | |||
@@ -139,7 +141,6 @@ jack_client_alloc () | |||
client->thread_ok = FALSE; | |||
client->first_active = TRUE; | |||
client->on_shutdown = NULL; | |||
client->cpu_mhz = (float) jack_get_mhz (); | |||
return client; | |||
} | |||
@@ -449,6 +450,12 @@ jack_client_new (const char *client_name) | |||
int control_shm_id; | |||
void *addr; | |||
/* external clients need this initialized; internal clients | |||
will use the setup in the server's address space. | |||
*/ | |||
jack_init_time (); | |||
if (jack_request_client (ClientExternal, client_name, "", "", &res, &req_fd)) { | |||
return NULL; | |||
} | |||
@@ -654,7 +661,7 @@ jack_client_thread (void *arg) | |||
*/ | |||
if (client->pollfd[1].revents & POLLIN) { | |||
control->awake_at = get_cycles(); | |||
control->awake_at = jack_get_microseconds(); | |||
} | |||
if (client->pollfd[0].revents & ~POLLIN || client->control->dead) { | |||
@@ -741,7 +748,7 @@ jack_client_thread (void *arg) | |||
getpid(), | |||
control->signalled_at, | |||
control->awake_at, | |||
((float) (control->awake_at - control->signalled_at))/client->cpu_mhz, | |||
control->awake_at - control->signalled_at, | |||
client->pollfd[1].fd); | |||
control->state = Running; | |||
@@ -754,7 +761,7 @@ jack_client_thread (void *arg) | |||
control->state = Finished; | |||
} | |||
control->finished_at = get_cycles(); | |||
control->finished_at = jack_get_microseconds(); | |||
#ifdef WITH_TIMESTAMPS | |||
jack_timestamp ("finished"); | |||
@@ -772,7 +779,8 @@ jack_client_thread (void *arg) | |||
break; | |||
} | |||
DEBUG ("client sent message to next stage by %Lu, client reading on graph_wait_fd==%d", get_cycles(), client->graph_wait_fd); | |||
DEBUG ("client sent message to next stage by %Lu, client reading on graph_wait_fd==%d", | |||
jack_get_microseconds(), client->graph_wait_fd); | |||
#ifdef WITH_TIMESTAMPS | |||
jack_timestamp ("read pending byte from wait"); | |||
@@ -1376,7 +1384,7 @@ jack_frames_since_cycle_start (const jack_client_t *client) | |||
{ | |||
float usecs; | |||
usecs = (float) (get_cycles() - client->engine->current_time.cycles) / client->cpu_mhz; | |||
usecs = jack_get_microseconds() - client->engine->current_time.usecs; | |||
return (jack_nframes_t) floor ((((float) client->engine->current_time.frame_rate) / 1000000.0f) * usecs); | |||
} | |||
@@ -1389,7 +1397,7 @@ jack_frame_time (const jack_client_t *client) | |||
jack_read_frame_time (client, ¤t); | |||
usecs = (float) (get_cycles() - current.stamp) / client->cpu_mhz; | |||
usecs = jack_get_microseconds() - current.stamp; | |||
elapsed = (jack_nframes_t) floor ((((float) client->engine->current_time.frame_rate) / 1000000.0f) * usecs); | |||
return current.frames + elapsed; | |||
@@ -1442,7 +1450,21 @@ jack_set_transport_info (jack_client_t *client, | |||
return 0; | |||
} | |||
int | |||
float | |||
jack_cpu_load (jack_client_t *client) | |||
{ | |||
return client->engine->cpu_load; | |||
} | |||
pthread_t | |||
jack_client_thread_id (jack_client_t *client) | |||
{ | |||
return client->thread_id; | |||
} | |||
#if defined(linux) | |||
jack_time_t | |||
jack_get_mhz (void) | |||
{ | |||
FILE *f = fopen("/proc/cpuinfo", "r"); | |||
@@ -1454,7 +1476,7 @@ jack_get_mhz (void) | |||
for ( ; ; ) | |||
{ | |||
int mhz; | |||
jack_time_t mhz; | |||
int ret; | |||
char buf[1000]; | |||
@@ -1465,9 +1487,9 @@ jack_get_mhz (void) | |||
} | |||
#ifdef __powerpc__ | |||
ret = sscanf(buf, "clock\t: %dMHz", &mhz); | |||
ret = sscanf(buf, "clock\t: %LuMHz", &mhz); | |||
#else | |||
ret = sscanf(buf, "cpu MHz : %d", &mhz); | |||
ret = sscanf(buf, "cpu MHz : %Lu", &mhz); | |||
#endif /* __powerpc__ */ | |||
if (ret == 1) | |||
@@ -1478,15 +1500,9 @@ jack_get_mhz (void) | |||
} | |||
} | |||
float | |||
jack_cpu_load (jack_client_t *client) | |||
{ | |||
return client->engine->cpu_load; | |||
} | |||
pthread_t | |||
jack_client_thread_id (jack_client_t *client) | |||
void jack_init_time () | |||
{ | |||
return client->thread_id; | |||
__jack_cpu_mhz = jack_get_mhz (); | |||
} | |||
#endif |
@@ -22,10 +22,10 @@ | |||
#include <string.h> | |||
#include <jack/timestamps.h> | |||
#include <jack/internal.h> | |||
#include <jack/cycles.h> | |||
#include <jack/time.h> | |||
typedef struct { | |||
cycles_t when; | |||
jack_time_t when; | |||
const char *what; | |||
} jack_timestamp_t; | |||
@@ -49,7 +49,7 @@ void | |||
jack_timestamp (const char *what) | |||
{ | |||
if (timestamp_index < timestamp_cnt) { | |||
timestamps[timestamp_index].when = get_cycles(); | |||
timestamps[timestamp_index].when = jack_get_microseconds(); | |||
timestamps[timestamp_index].what = what; | |||
++timestamp_index; | |||
} | |||