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 ---
JACK_MAJOR_VERSION=0
JACK_MINOR_VERSION=64
JACK_MINOR_VERSION=65
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=12
JACK_API_REVISION=13
JACK_API_AGE=0

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_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_subdevice (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 */
/* etc. above. */
/* 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,
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? */
if(mask & (1<<i)) {
/* Yes. Connect physical input to output */

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

#ifdef CANNOT_HEAR_SOFTWARE_STREAM_WHEN_MONITORING
/* ...and disconnect the corresponding software */
/* channel */
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) {
return -1;
}
#endif

} else {
/* No. Disconnect physical input from output */
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) {
return -1;
}

#ifdef CANNOT_HEAR_SOFTWARE_STREAM_WHEN_MONITORING
/* ...and connect the corresponding software */
/* channel */
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) {
return -1;
}
#endif
}
}
/* 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;
if (transport_aware) {
ti.valid = JackTransportPosition | JackTransportState;
int mask = JackTransportPosition | JackTransportState;
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);
return 0;
}
offset = ti.position % wave_length;
offset = ti.frame % wave_length;
}

process_audio (nframes);


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

@@ -14,7 +14,12 @@ void
showtime ()
{
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


+ 2
- 28
jack/internal.h View File

@@ -66,32 +66,6 @@ typedef struct {
size_t size;
} 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 {
volatile unsigned long long guard1;
volatile jack_nframes_t frames;
@@ -101,8 +75,8 @@ 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;
int internal;
jack_nframes_t frames_at_cycle_start;


+ 36
- 16
jack/transport.h View File

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

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

} jack_transport_bits_t;

#define EXTENDED_TIME_INFO \

/**
* Struct for transport status information.
*/
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_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;

/**
@@ -70,27 +92,25 @@ typedef struct {
* cycle.
*
* 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.
*
* @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.
*
* 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
}


+ 33
- 4
jackd/engine.c View File

@@ -288,7 +288,7 @@ static void
jack_register_shm (char *shm_name)
{
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;
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.frame_rate = engine->control->current_time.frame_rate;
engine->control->current_time = engine->control->pending_time;

/* find any clients that need removal due to timeouts, etc. */
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->current_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)) {
@@ -2150,6 +2157,8 @@ jack_zombify_client (jack_engine_t *engine, jack_client_internal_t *client)
engine->control->pending_time.frame = 0;
engine->control->current_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);
@@ -2819,6 +2828,7 @@ jack_port_do_connect (jack_engine_t *engine,
jack_connection_internal_t *connection;
jack_port_internal_t *srcport, *dstport;
jack_port_id_t src_id, dst_id;
jack_client_internal_t *client;

if ((srcport = jack_get_port_by_name (engine, source_port)) == NULL) {
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;
}

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");
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->source = srcport;


+ 5
- 35
libjack/client.c View File

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

/* TRANSPORT CONTROL */

int
void
jack_get_transport_info (jack_client_t *client,
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_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


Loading…
Cancel
Save