git-svn-id: svn+ssh://jackaudio.org/trunk/jack@355 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=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) | |||
@@ -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 */ | |||
@@ -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); | |||
@@ -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 | |||
@@ -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; | |||
@@ -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 | |||
} | |||
@@ -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; | |||
@@ -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 | |||