Browse Source

expanded transport/time information

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@355 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.109.0
pbd 22 years ago
parent
commit
020cf581b2
8 changed files with 99 additions and 92 deletions
  1. +2
    -2
      configure.in
  2. +11
    -2
      drivers/alsa/hdsp.c
  3. +4
    -4
      example-clients/metro.c
  4. +6
    -1
      example-clients/showtime.c
  5. +2
    -28
      jack/internal.h
  6. +36
    -16
      jack/transport.h
  7. +33
    -4
      jackd/engine.c
  8. +5
    -35
      libjack/client.c

+ 2
- 2
configure.in View File

@@ -13,7 +13,7 @@ dnl micro version = incremented when implementation-only
dnl changes are made dnl changes are made
dnl --- dnl ---
JACK_MAJOR_VERSION=0 JACK_MAJOR_VERSION=0
JACK_MINOR_VERSION=64
JACK_MINOR_VERSION=65
JACK_MICRO_VERSION=0 JACK_MICRO_VERSION=0


dnl --- dnl ---
@@ -41,7 +41,7 @@ dnl slacker than this, and closer to those for the JACK version
dnl number. dnl number.
dnl --- dnl ---
JACK_API_CURRENT=0 JACK_API_CURRENT=0
JACK_API_REVISION=12
JACK_API_REVISION=13
JACK_API_AGE=0 JACK_API_AGE=0


AC_SUBST(JACK_MAJOR_VERSION) AC_SUBST(JACK_MAJOR_VERSION)


+ 11
- 2
drivers/alsa/hdsp.c View File

@@ -74,7 +74,7 @@ set_control_id (snd_ctl_elem_id_t *ctl, const char *name)
{ {
snd_ctl_elem_id_set_name (ctl, name); snd_ctl_elem_id_set_name (ctl, name);
snd_ctl_elem_id_set_numid (ctl, 0); snd_ctl_elem_id_set_numid (ctl, 0);
snd_ctl_elem_id_set_interface (ctl, SND_CTL_ELEM_IFACE_PCM);
snd_ctl_elem_id_set_interface (ctl, SND_CTL_ELEM_IFACE_HWDEP);
snd_ctl_elem_id_set_device (ctl, 0); snd_ctl_elem_id_set_device (ctl, 0);
snd_ctl_elem_id_set_subdevice (ctl, 0); snd_ctl_elem_id_set_subdevice (ctl, 0);
snd_ctl_elem_id_set_index (ctl, 0); snd_ctl_elem_id_set_index (ctl, 0);
@@ -86,7 +86,8 @@ set_control_id (snd_ctl_elem_id_t *ctl, const char *name)
/* input_channel to output_channel (see hdsp_physical_input_index */ /* input_channel to output_channel (see hdsp_physical_input_index */
/* etc. above. */ /* etc. above. */
/* gain is an int from 0 to 65535, with 0 being -inf gain, and */ /* gain is an int from 0 to 65535, with 0 being -inf gain, and */
/* 65535 being about 2dB. */
/* 65535 being about +2dB. */

static int hdsp_set_mixer_gain(jack_hardware_t *hw, int input_channel, static int hdsp_set_mixer_gain(jack_hardware_t *hw, int input_channel,
int output_channel, int gain) int output_channel, int gain)
{ {
@@ -133,11 +134,14 @@ static int hdsp_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask)
/* Monitoring requested for this channel? */ /* Monitoring requested for this channel? */
if(mask & (1<<i)) { if(mask & (1<<i)) {
/* Yes. Connect physical input to output */ /* Yes. Connect physical input to output */

if(hdsp_set_mixer_gain (hw, hdsp_physical_input_index[i], if(hdsp_set_mixer_gain (hw, hdsp_physical_input_index[i],
hdsp_physical_output_index[i], hdsp_physical_output_index[i],
HDSP_UNITY_GAIN) != 0) { HDSP_UNITY_GAIN) != 0) {
return -1; return -1;
} }

#ifdef CANNOT_HEAR_SOFTWARE_STREAM_WHEN_MONITORING
/* ...and disconnect the corresponding software */ /* ...and disconnect the corresponding software */
/* channel */ /* channel */
if(hdsp_set_mixer_gain (hw, hdsp_audio_stream_index[i], if(hdsp_set_mixer_gain (hw, hdsp_audio_stream_index[i],
@@ -145,6 +149,8 @@ static int hdsp_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask)
HDSP_MINUS_INFINITY_GAIN) != 0) { HDSP_MINUS_INFINITY_GAIN) != 0) {
return -1; return -1;
} }
#endif

} else { } else {
/* No. Disconnect physical input from output */ /* No. Disconnect physical input from output */
if(hdsp_set_mixer_gain (hw, hdsp_physical_input_index[i], if(hdsp_set_mixer_gain (hw, hdsp_physical_input_index[i],
@@ -152,6 +158,8 @@ static int hdsp_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask)
HDSP_MINUS_INFINITY_GAIN) != 0) { HDSP_MINUS_INFINITY_GAIN) != 0) {
return -1; return -1;
} }

#ifdef CANNOT_HEAR_SOFTWARE_STREAM_WHEN_MONITORING
/* ...and connect the corresponding software */ /* ...and connect the corresponding software */
/* channel */ /* channel */
if(hdsp_set_mixer_gain (hw, hdsp_audio_stream_index[i], if(hdsp_set_mixer_gain (hw, hdsp_audio_stream_index[i],
@@ -159,6 +167,7 @@ static int hdsp_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask)
HDSP_UNITY_GAIN) != 0) { HDSP_UNITY_GAIN) != 0) {
return -1; return -1;
} }
#endif
} }
} }
/* Cache the monitor mask */ /* Cache the monitor mask */


+ 4
- 4
example-clients/metro.c View File

@@ -89,15 +89,15 @@ process (jack_nframes_t nframes, void *arg)
jack_transport_info_t ti; jack_transport_info_t ti;
if (transport_aware) { if (transport_aware) {
ti.valid = JackTransportPosition | JackTransportState;
int mask = JackTransportPosition | JackTransportState;
jack_get_transport_info (client, &ti); jack_get_transport_info (client, &ti);


// not rolling, bail out
if (ti.state == JackTransportStopped) {
if (((ti.valid & mask) != mask) || ti.transport_state == JackTransportStopped) {
// no valid information, or not rolling, bail out
process_silence (nframes); process_silence (nframes);
return 0; return 0;
} }
offset = ti.position % wave_length;
offset = ti.frame % wave_length;
} }


process_audio (nframes); process_audio (nframes);


+ 6
- 1
example-clients/showtime.c View File

@@ -14,7 +14,12 @@ void
showtime () showtime ()
{ {
jack_transport_info_t current = now; jack_transport_info_t current = now;
printf ("frame: %lu state: %d loop: %lu-%lu\n", current.position, current.state, current.loop_start, current.loop_end);
printf ("frame: %lu state: %d loop: %lu-%lu "
"BBT: %d|%d|%d\n",
current.frame, current.transport_state, current.loop_start, current.loop_end,
current.bar,
current.beat,
current.tick);
} }


int int


+ 2
- 28
jack/internal.h View File

@@ -66,32 +66,6 @@ typedef struct {
size_t size; size_t size;
} jack_port_segment_info_t; } jack_port_segment_info_t;


typedef struct _time_info
{
jack_nframes_t frame;
jack_nframes_t frame_rate;
jack_time_t usecs;
jack_transport_state_t transport_state;
jack_nframes_t loop_start;
jack_nframes_t loop_end;

#if 0
double ppqPos; // 1 ppq
double tempo; // in bpm
double barStartPos; // last bar start, in 1 ppq
double cycleStartPos; // 1 ppq
double cycleEndPos; // 1 ppq

float timeSigNumerator; // time signature
float timeSigDenominator;
long smpteOffset;
long smpteFrameRate; // 0:24, 1:25, 2:29.97, 3:30, 4:29.97 df, 5:30 df
long samplesToNextClock; // midi clock resolution (24 ppq), can be negative
long flags; // see below
#endif
} jack_time_info_t;

typedef struct { typedef struct {
volatile unsigned long long guard1; volatile unsigned long long guard1;
volatile jack_nframes_t frames; volatile jack_nframes_t frames;
@@ -101,8 +75,8 @@ typedef struct {


typedef struct { typedef struct {


jack_time_info_t current_time;
jack_time_info_t pending_time;
jack_transport_info_t current_time;
jack_transport_info_t pending_time;
jack_frame_timer_t frame_timer; jack_frame_timer_t frame_timer;
int internal; int internal;
jack_nframes_t frames_at_cycle_start; jack_nframes_t frames_at_cycle_start;


+ 36
- 16
jack/transport.h View File

@@ -48,21 +48,43 @@ typedef enum {


JackTransportState = 0x1, JackTransportState = 0x1,
JackTransportPosition = 0x2, JackTransportPosition = 0x2,
JackTransportLoop = 0x4
JackTransportLoop = 0x4,
JackTransportSMPTE = 0x8,
JackTransportBBT = 0x10,


} jack_transport_bits_t; } jack_transport_bits_t;


#define EXTENDED_TIME_INFO \

/** /**
* Struct for transport status information. * Struct for transport status information.
*/ */
typedef struct { typedef struct {
/* these two cannot be set from clients: the server sets them */


jack_transport_bits_t valid;
jack_transport_state_t state;
jack_nframes_t position;
jack_nframes_t frame_rate; // current frame rate (per second)
jack_time_t usecs; // monotonic, free-rolling

jack_transport_bits_t valid; // which fields are legal to read
jack_transport_state_t transport_state;
jack_nframes_t frame;
jack_nframes_t loop_start; jack_nframes_t loop_start;
jack_nframes_t loop_end; jack_nframes_t loop_end;


long smpte_offset; // SMPTE offset (SMPTE frame when frame = 0)
float smpte_frame_rate; // 29.97, 30, 24 etc.

int bar; // current bar
int beat; // current beat-within-bar
int tick; // current tick-within-beat
double bar_start_tick; //

float beats_per_bar;
float beat_type;
double ticks_per_beat;
double beats_per_minute;

} jack_transport_info_t; } jack_transport_info_t;


/** /**
@@ -70,27 +92,25 @@ typedef struct {
* cycle. * cycle.
* *
* The 'valid' field of the tinfo struct should contain * The 'valid' field of the tinfo struct should contain
* a bitmask of all transport info fields that should
* be set with this call.
* a bitmask of all transport info fields that are set
* in tinfo.
* *
* @pre Caller must be the current timebase master. * @pre Caller must be the current timebase master.
* *
* @return 0 on success, otherwise a non-zero error code
*/ */
int jack_set_transport_info (jack_client_t *client,
jack_transport_info_t *tinfo);
void jack_set_transport_info (jack_client_t *client,
jack_transport_info_t *tinfo);
/** /**
* Gets the current transport state. * Gets the current transport state.
* *
* The 'valid' field of the tinfo struct should contain
* a bitmask of all transport info fields that the
* client is interested in.
* On return, the 'valid' field of the tinfo struct will contain
* a bitmask of all transport info fields that are legal to
* use.
* *
* @return 0 on success, otherwise a non-zero error code
*/ */
int jack_get_transport_info (jack_client_t *client,
jack_transport_info_t *tinfo);
void jack_get_transport_info (jack_client_t *client,
jack_transport_info_t *tinfo);


#ifdef __cplusplus #ifdef __cplusplus
} }


+ 33
- 4
jackd/engine.c View File

@@ -288,7 +288,7 @@ static void
jack_register_shm (char *shm_name) jack_register_shm (char *shm_name)
{ {
if (jack_shm_id_cnt < MAX_SHM_ID) { if (jack_shm_id_cnt < MAX_SHM_ID) {
snprintf (jack_shm_registry[jack_shm_id_cnt++], sizeof (shm_name_t), shm_name);
snprintf (jack_shm_registry[jack_shm_id_cnt++], sizeof (shm_name_t), "%s", shm_name);
} }
} }


@@ -615,9 +615,14 @@ jack_engine_post_process (jack_engine_t *engine)
JSList *node; JSList *node;
int need_remove = FALSE; int need_remove = FALSE;
/* maintain the current_time.usecs and frame_rate values, since clients
are not permitted to set these.
*/

engine->control->pending_time.usecs = engine->control->current_time.usecs; engine->control->pending_time.usecs = engine->control->current_time.usecs;
engine->control->pending_time.frame_rate = engine->control->current_time.frame_rate;
engine->control->current_time = engine->control->pending_time; engine->control->current_time = engine->control->pending_time;

/* find any clients that need removal due to timeouts, etc. */ /* find any clients that need removal due to timeouts, etc. */
for (node = engine->clients; node; node = jack_slist_next (node) ) { for (node = engine->clients; node; node = jack_slist_next (node) ) {
@@ -1276,6 +1281,8 @@ jack_client_deactivate (jack_engine_t *engine, jack_client_id_t id)
engine->control->pending_time.frame = 0; engine->control->pending_time.frame = 0;
engine->control->current_time.transport_state = JackTransportStopped; engine->control->current_time.transport_state = JackTransportStopped;
engine->control->pending_time.transport_state = JackTransportStopped; engine->control->pending_time.transport_state = JackTransportStopped;
engine->control->current_time.valid = JackTransportState|JackTransportPosition;
engine->control->pending_time.valid = JackTransportState|JackTransportPosition;
} }
for (portnode = client->ports; portnode; portnode = jack_slist_next (portnode)) { for (portnode = client->ports; portnode; portnode = jack_slist_next (portnode)) {
@@ -2150,6 +2157,8 @@ jack_zombify_client (jack_engine_t *engine, jack_client_internal_t *client)
engine->control->pending_time.frame = 0; engine->control->pending_time.frame = 0;
engine->control->current_time.transport_state = JackTransportStopped; engine->control->current_time.transport_state = JackTransportStopped;
engine->control->pending_time.transport_state = JackTransportStopped; engine->control->pending_time.transport_state = JackTransportStopped;
engine->control->current_time.valid = JackTransportState|JackTransportPosition;
engine->control->pending_time.valid = JackTransportState|JackTransportPosition;
} }


jack_client_disconnect (engine, client); jack_client_disconnect (engine, client);
@@ -2819,6 +2828,7 @@ jack_port_do_connect (jack_engine_t *engine,
jack_connection_internal_t *connection; jack_connection_internal_t *connection;
jack_port_internal_t *srcport, *dstport; jack_port_internal_t *srcport, *dstport;
jack_port_id_t src_id, dst_id; jack_port_id_t src_id, dst_id;
jack_client_internal_t *client;


if ((srcport = jack_get_port_by_name (engine, source_port)) == NULL) { if ((srcport = jack_get_port_by_name (engine, source_port)) == NULL) {
jack_error ("unknown source port in attempted connection [%s]", source_port); jack_error ("unknown source port in attempted connection [%s]", source_port);
@@ -2852,12 +2862,31 @@ jack_port_do_connect (jack_engine_t *engine,
return -1; return -1;
} }


if (strcmp (srcport->shared->type_info.type_name,
dstport->shared->type_info.type_name) != 0) {
if (strcmp (srcport->shared->type_info.type_name, dstport->shared->type_info.type_name) != 0) {
jack_error ("ports used in attemped connection are not of the same data type"); jack_error ("ports used in attemped connection are not of the same data type");
return -1; return -1;
} }


if ((client = jack_client_internal_by_id (engine, srcport->shared->client_id)) == 0) {
jack_error ("unknown client set as owner of port - cannot connect");
return -1;
}
if (!client->control->active) {
jack_error ("cannot connect ports owned by inactive clients; \"%s\" is not active", client->control->name);
return -1;
}

if ((client = jack_client_internal_by_id (engine, dstport->shared->client_id)) == 0) {
jack_error ("unknown client set as owner of port - cannot connect");
return -1;
}
if (!client->control->active) {
jack_error ("cannot connect ports owned by inactive clients; \"%s\" is not active", client->control->name);
return -1;
}

connection = (jack_connection_internal_t *) malloc (sizeof (jack_connection_internal_t)); connection = (jack_connection_internal_t *) malloc (sizeof (jack_connection_internal_t));


connection->source = srcport; connection->source = srcport;


+ 5
- 35
libjack/client.c View File

@@ -529,7 +529,7 @@ jack_client_new (const char *client_name)
fail: fail:
if (client->engine) { if (client->engine) {
munmap ((char *) client->engine, sizeof (jack_control_t));
munmap ((char *) client->engine, res.control_size);
} }
if (client->control) { if (client->control) {
munmap ((char *) client->control, sizeof (jack_client_control_t)); munmap ((char *) client->control, sizeof (jack_client_control_t));
@@ -1411,48 +1411,18 @@ jack_frame_time (const jack_client_t *client)


/* TRANSPORT CONTROL */ /* TRANSPORT CONTROL */


int
void
jack_get_transport_info (jack_client_t *client, jack_get_transport_info (jack_client_t *client,
jack_transport_info_t *info) jack_transport_info_t *info)
{ {
jack_time_info_t *time_info = &client->engine->current_time;

if (info->valid & JackTransportState) {
info->state = time_info->transport_state;
}
if (info->valid & JackTransportPosition) {
info->position = time_info->frame;
}

if (info->valid & JackTransportLoop) {
info->loop_start = time_info->loop_start;
info->loop_end = time_info->loop_end;
}

return 0;
*info = client->engine->current_time;
} }


int
void
jack_set_transport_info (jack_client_t *client, jack_set_transport_info (jack_client_t *client,
jack_transport_info_t *info) jack_transport_info_t *info)
{ {
jack_time_info_t *time_info = &client->engine->pending_time;
if (info->valid & JackTransportState) {
time_info->transport_state = info->state;
}

if (info->valid & JackTransportPosition) {
time_info->frame = info->position;
}

if (info->valid & JackTransportLoop) {
time_info->loop_start = info->loop_start;
time_info->loop_end = info->loop_end;
}

return 0;
client->engine->pending_time = *info;
} }


float float


Loading…
Cancel
Save