git-svn-id: svn+ssh://jackaudio.org/trunk/jack@246 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.109.0
@@ -5,15 +5,22 @@ AC_CONFIG_AUX_DIR(.) | |||||
JACK_MAJOR_VERSION=0 | JACK_MAJOR_VERSION=0 | ||||
JACK_MINOR_VERSION=38 | JACK_MINOR_VERSION=38 | ||||
JACK_MICRO_VERSION=0 | |||||
JACK_MICRO_VERSION=1 | |||||
BETA= | |||||
JACK_API_CURRENT=0 | |||||
JACK_API_REVISION=4 | |||||
JACK_API_AGE=0 | |||||
AC_SUBST(JACK_MAJOR_VERSION) | AC_SUBST(JACK_MAJOR_VERSION) | ||||
AC_SUBST(JACK_MINOR_VERSION) | AC_SUBST(JACK_MINOR_VERSION) | ||||
AC_SUBST(JACK_MICRO_VERSION) | AC_SUBST(JACK_MICRO_VERSION) | ||||
JACK_SO_VERSION=${JACK_MAJOR_VERSION}:${JACK_MINOR_VERSION}:${JACK_MICRO_VERSION}${BETA} | |||||
AC_SUBST(JACK_API_MAJOR_VERSION) | |||||
AC_SUBST(JACK_API_MINOR_VERSION) | |||||
AC_SUBST(JACK_API_MICRO_VERSION) | |||||
JACK_SO_VERSION=${JACK_API_CURRENT}:${JACK_API_REVISION}:${JACK_API_AGE} | |||||
JACK_VERSION=$JACK_MAJOR_VERSION.$JACK_MINOR_VERSION.${JACK_MICRO_VERSION}${BETA} | JACK_VERSION=$JACK_MAJOR_VERSION.$JACK_MINOR_VERSION.${JACK_MICRO_VERSION}${BETA} | ||||
JACK_RELEASE=$JACK_MAJOR_VERSION-$JACK_MINOR_VERSION-${JACK_MICRO_VERSION}${BETA} | JACK_RELEASE=$JACK_MAJOR_VERSION-$JACK_MINOR_VERSION-${JACK_MICRO_VERSION}${BETA} | ||||
@@ -22,6 +22,7 @@ | |||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <math.h> | #include <math.h> | ||||
#include <jack/jack.h> | #include <jack/jack.h> | ||||
#include <jack/transport.h> | |||||
#include <glib.h> | #include <glib.h> | ||||
#include <getopt.h> | #include <getopt.h> | ||||
#include <string.h> | #include <string.h> | ||||
@@ -37,7 +38,9 @@ int freq = 880; | |||||
int bpm; | int bpm; | ||||
jack_nframes_t tone_length, wave_length; | jack_nframes_t tone_length, wave_length; | ||||
sample_t *wave; | sample_t *wave; | ||||
long pos = 0; | |||||
long offset = 0; | |||||
int transport_aware = 0; | |||||
jack_transport_state_t transport_state; | |||||
void | void | ||||
usage () | usage () | ||||
@@ -51,25 +54,55 @@ usage: jack_metro | |||||
[ --attack OR -a attack (in percent of duration) ] | [ --attack OR -a attack (in percent of duration) ] | ||||
[ --decay OR -d decay (in percent of duration) ] | [ --decay OR -d decay (in percent of duration) ] | ||||
[ --name OR -n jack name for metronome client ] | [ --name OR -n jack name for metronome client ] | ||||
[ --transport OR -t transport aware ] | |||||
--bpm OR -b beats per minute | --bpm OR -b beats per minute | ||||
"); | "); | ||||
} | } | ||||
int | |||||
process (jack_nframes_t nframes, void *arg) | |||||
void | |||||
process_silence (jack_nframes_t nframes) | |||||
{ | |||||
sample_t *buffer = (sample_t *) jack_port_get_buffer (output_port, nframes); | |||||
memset (buffer, 0, sizeof (jack_default_audio_sample_t) * nframes); | |||||
} | |||||
void | |||||
process_audio (jack_nframes_t nframes) | |||||
{ | { | ||||
sample_t *buffer = (sample_t *) jack_port_get_buffer(output_port, nframes); | |||||
sample_t *buffer = (sample_t *) jack_port_get_buffer (output_port, nframes); | |||||
jack_nframes_t frames_left = nframes; | jack_nframes_t frames_left = nframes; | ||||
while (wave_length - pos < frames_left) { | |||||
memcpy (buffer + (nframes - frames_left), wave + pos, sizeof (sample_t) * (wave_length - pos)); | |||||
frames_left -= wave_length - pos; | |||||
pos = 0; | |||||
while (wave_length - offset < frames_left) { | |||||
memcpy (buffer + (nframes - frames_left), wave + offset, sizeof (sample_t) * (wave_length - offset)); | |||||
frames_left -= wave_length - offset; | |||||
offset = 0; | |||||
} | } | ||||
if (frames_left > 0) { | if (frames_left > 0) { | ||||
memcpy (buffer + (nframes - frames_left), wave + pos, sizeof (sample_t) * frames_left); | |||||
pos += frames_left; | |||||
memcpy (buffer + (nframes - frames_left), wave + offset, sizeof (sample_t) * frames_left); | |||||
offset += frames_left; | |||||
} | } | ||||
} | |||||
int | |||||
process (jack_nframes_t nframes, void *arg) | |||||
{ | |||||
jack_transport_info_t ti; | |||||
if (transport_aware) { | |||||
ti.valid = JackTransportPosition | JackTransportState; | |||||
jack_get_transport_info (client, &ti); | |||||
// not rolling, bail out | |||||
if (ti.state == JackTransportStopped) { | |||||
process_silence (nframes); | |||||
return 0; | |||||
} | |||||
offset = ti.position % wave_length; | |||||
} | |||||
process_audio (nframes); | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -101,7 +134,7 @@ main (int argc, char *argv[]) | |||||
char *bpm_string = "bpm"; | char *bpm_string = "bpm"; | ||||
int verbose = 0; | int verbose = 0; | ||||
const char *options = "f:A:D:a:d:b:n:hv"; | |||||
const char *options = "f:A:D:a:d:b:n:thv"; | |||||
struct option long_options[] = | struct option long_options[] = | ||||
{ | { | ||||
{"frequency", 1, 0, 'f'}, | {"frequency", 1, 0, 'f'}, | ||||
@@ -111,6 +144,7 @@ main (int argc, char *argv[]) | |||||
{"decay", 1, 0, 'd'}, | {"decay", 1, 0, 'd'}, | ||||
{"bpm", 1, 0, 'b'}, | {"bpm", 1, 0, 'b'}, | ||||
{"name", 1, 0, 'n'}, | {"name", 1, 0, 'n'}, | ||||
{"transport", 0, 0, 't'}, | |||||
{"help", 0, 0, 'h'}, | {"help", 0, 0, 'h'}, | ||||
{"verbose", 0, 0, 'v'}, | {"verbose", 0, 0, 'v'}, | ||||
{0, 0, 0, 0} | {0, 0, 0, 0} | ||||
@@ -132,7 +166,7 @@ main (int argc, char *argv[]) | |||||
break; | break; | ||||
case 'D': | case 'D': | ||||
dur_arg = atoi (optarg); | dur_arg = atoi (optarg); | ||||
fprintf (stderr, "durarg = %lu\n", dur_arg); | |||||
fprintf (stderr, "durarg = %u\n", dur_arg); | |||||
break; | break; | ||||
case 'a': | case 'a': | ||||
if (((attack_percent = atoi (optarg)) < 0) || (attack_percent > 100)) { | if (((attack_percent = atoi (optarg)) < 0) || (attack_percent > 100)) { | ||||
@@ -155,7 +189,6 @@ main (int argc, char *argv[]) | |||||
bpm_string = (char *) malloc ((strlen (optarg) + 4) * sizeof (char)); | bpm_string = (char *) malloc ((strlen (optarg) + 4) * sizeof (char)); | ||||
strcpy (bpm_string, optarg); | strcpy (bpm_string, optarg); | ||||
strcat (bpm_string, "_bpm"); | strcat (bpm_string, "_bpm"); | ||||
fprintf (stderr, "bpm = %lu\n", bpm); | |||||
break; | break; | ||||
case 'n': | case 'n': | ||||
client_name = (char *) malloc (strlen (optarg) * sizeof (char)); | client_name = (char *) malloc (strlen (optarg) * sizeof (char)); | ||||
@@ -164,6 +197,9 @@ main (int argc, char *argv[]) | |||||
case 'v': | case 'v': | ||||
verbose = 1; | verbose = 1; | ||||
break; | break; | ||||
case 't': | |||||
transport_aware = 1; | |||||
break; | |||||
default: | default: | ||||
fprintf (stderr, "unknown option %c\n", opt); | fprintf (stderr, "unknown option %c\n", opt); | ||||
case 'h': | case 'h': | ||||
@@ -232,9 +268,6 @@ main (int argc, char *argv[]) | |||||
return 1; | return 1; | ||||
} | } | ||||
if (verbose) { | |||||
} | |||||
while (1) { | while (1) { | ||||
sleep(1); | sleep(1); | ||||
}; | }; | ||||
@@ -59,22 +59,23 @@ typedef struct _jack_port_type_info { | |||||
*/ | */ | ||||
typedef struct _jack_port_shared { | typedef struct _jack_port_shared { | ||||
int shm_key; | |||||
size_t offset; | |||||
int shm_key; | |||||
size_t offset; | |||||
unsigned long flags; | |||||
unsigned long buffer_size; | |||||
jack_port_id_t id; | |||||
char name[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE+2]; | |||||
jack_port_type_info_t type_info; | |||||
jack_client_id_t client_id; | |||||
unsigned long flags; | |||||
unsigned long buffer_size; | |||||
jack_port_id_t id; | |||||
char name[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE+2]; | |||||
jack_port_type_info_t type_info; | |||||
jack_client_id_t client_id; | |||||
volatile jack_nframes_t latency; | |||||
volatile jack_nframes_t total_latency; | |||||
volatile unsigned char monitor_requests; | |||||
volatile jack_nframes_t latency; | |||||
volatile jack_nframes_t total_latency; | |||||
volatile unsigned char monitor_requests; | |||||
char in_use : 1; | |||||
char locked : 1; | |||||
char in_use : 1; | |||||
char locked : 1; | |||||
struct _jack_port *tied; | |||||
} jack_port_shared_t; | } jack_port_shared_t; | ||||
@@ -88,7 +89,6 @@ struct _jack_port { | |||||
struct _jack_port_shared *shared; | struct _jack_port_shared *shared; | ||||
pthread_mutex_t connection_lock; | pthread_mutex_t connection_lock; | ||||
GSList *connections; | GSList *connections; | ||||
struct _jack_port *tied; | |||||
}; | }; | ||||
/* inline would be cleaner, but it needs to be fast even in non-optimized | /* inline would be cleaner, but it needs to be fast even in non-optimized | ||||
@@ -7,5 +7,5 @@ lib_LTLIBRARIES = libjack.la | |||||
libjack_la_SOURCES = client.c pool.c driver.c | libjack_la_SOURCES = client.c pool.c driver.c | ||||
libjack_la_LIBADD = $(GLIB_LIBS) -lm -lpthread | libjack_la_LIBADD = $(GLIB_LIBS) -lm -lpthread | ||||
libjack_la_LDFLAGS = -export-dynamic -release @VERSION@ -version-info 0:0:0 | |||||
libjack_la_LDFLAGS = -export-dynamic -version-info @JACK_SO_VERSION@ | |||||
@@ -1120,7 +1120,7 @@ jack_port_new (jack_client_t *client, jack_port_id_t port_id, jack_control_t *co | |||||
port->shared = shared; | port->shared = shared; | ||||
pthread_mutex_init (&port->connection_lock, NULL); | pthread_mutex_init (&port->connection_lock, NULL); | ||||
port->connections = 0; | port->connections = 0; | ||||
port->tied = NULL; | |||||
port->shared->tied = NULL; | |||||
si = NULL; | si = NULL; | ||||
@@ -1374,8 +1374,8 @@ jack_port_get_buffer (jack_port_t *port, jack_nframes_t nframes) | |||||
*/ | */ | ||||
if (port->shared->flags & JackPortIsOutput) { | if (port->shared->flags & JackPortIsOutput) { | ||||
if (port->tied) { | |||||
return jack_port_get_buffer (port->tied, nframes); | |||||
if (port->shared->tied) { | |||||
return jack_port_get_buffer (port->shared->tied, nframes); | |||||
} | } | ||||
return jack_port_buffer (port); | return jack_port_buffer (port); | ||||
} | } | ||||
@@ -1402,7 +1402,7 @@ jack_port_get_buffer (jack_port_t *port, jack_nframes_t nframes) | |||||
the buffer of the connected (output) port. | the buffer of the connected (output) port. | ||||
*/ | */ | ||||
return jack_port_buffer (((jack_port_t *) node->data)); | |||||
return jack_port_get_buffer (((jack_port_t *) node->data), nframes); | |||||
} | } | ||||
/* multiple connections. use a local buffer and mixdown | /* multiple connections. use a local buffer and mixdown | ||||
@@ -1441,7 +1441,7 @@ jack_port_tie (jack_port_t *src, jack_port_t *dst) | |||||
return -1; | return -1; | ||||
} | } | ||||
dst->tied = src; | |||||
dst->shared->tied = src; | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -1449,11 +1449,11 @@ int | |||||
jack_port_untie (jack_port_t *port) | jack_port_untie (jack_port_t *port) | ||||
{ | { | ||||
if (port->tied == NULL) { | |||||
if (port->shared->tied == NULL) { | |||||
jack_error ("port \"%s\" is not tied", port->shared->name); | jack_error ("port \"%s\" is not tied", port->shared->name); | ||||
return -1; | return -1; | ||||
} | } | ||||
port->tied = NULL; | |||||
port->shared->tied = NULL; | |||||
return 0; | return 0; | ||||
} | } | ||||