Browse Source

fix configure for libsndfile, add 3 new sample clients, fix problems with removing dead clients, change timebase to use pending model

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@245 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.109.0
pbd 23 years ago
parent
commit
f139113e3e
11 changed files with 422 additions and 34 deletions
  1. +1
    -1
      Makefile.am
  2. +6
    -11
      configure.in
  3. +1
    -1
      drivers/alsa/alsa_driver.c
  4. +16
    -0
      example-clients/Makefile.am
  5. +30
    -0
      example-clients/lsp.c
  6. +242
    -0
      example-clients/metro.c
  7. +85
    -0
      example-clients/showtime.c
  8. +5
    -3
      jack/internal.h
  9. +24
    -10
      jackd/engine.c
  10. +4
    -0
      jackd/jackd.c
  11. +8
    -8
      libjack/client.c

+ 1
- 1
Makefile.am View File

@@ -2,7 +2,7 @@ MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure config.h.in \
stamp-h.in config.log config.cache \
config.guess mkinstalldirs config.status \
missing install-sh config.sub ltconfig \
ltmain.sh acinclude.m4
ltmain.sh

if HAVE_DOXYGEN
DOC_DIR = doc


+ 6
- 11
configure.in View File

@@ -4,8 +4,8 @@ AC_INIT(jackd/jackd.c)
AC_CONFIG_AUX_DIR(.)

JACK_MAJOR_VERSION=0
JACK_MINOR_VERSION=37
JACK_MICRO_VERSION=2
JACK_MINOR_VERSION=38
JACK_MICRO_VERSION=0

BETA=

@@ -162,15 +162,10 @@ if test $HAVE_FLTK = "false"; then
AC_MSG_WARN([*** no fltk found, the fltk example client will not be built])
fi

AC_CHECK_LIB(sndfile,main,
[AC_CHECK_HEADER(sndfile.h,
[HAVE_SNDFILE=true],
[HAVE_SNDFILE=false]
)],
[HAVE_SNDFILE=false]
)
if test $HAVE_SNDFILE = "false"; then
AC_MSG_WARN([*** no libsndfile found, the jackrec example client will not be built])
HAVE_SNDFILE=
PKG_CHECK_MODULES(SNDFILE, sndfile >= 1.0,[HAVE_SNDFILE=true], [true])
if test x$HAVE_SNDFILE = x; then
AC_MSG_WARN([*** the jackrec example client will not be built])
fi

# you need doxygen to make dist.


+ 1
- 1
drivers/alsa/alsa_driver.c View File

@@ -867,7 +867,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->time.cycles = get_cycles();
driver->engine->control->current_time.cycles = get_cycles();
}

/* check to see if it was the extra FD that caused us to return from poll


+ 16
- 0
example-clients/Makefile.am View File

@@ -30,6 +30,9 @@ bin_PROGRAMS = jack_simple_client \
jack_cache_killer \
jack_connect \
jack_disconnect \
jack_metro \
jack_showtime \
jack_lsp \
$(FLTK_CLIENT) $(JACKREC)

AM_CFLAGS = -I.. $(JACK_CFLAGS) $(GLIB_CFLAGS)
@@ -55,6 +58,19 @@ jack_cache_killer_SOURCES = cache_killer.c
jack_cache_killer_LDFLAGS = -ldl -lpthread
jack_cache_killer_LDADD = ../libjack/libjack.la

jack_metro_SOURCES = metro.c
jack_metro_LDFLAGS = -ldl -lpthread
jack_metro_LDADD = ../libjack/libjack.la

jack_lsp_SOURCES = lsp.c
jack_lsp_LDFLAGS = -ldl -lpthread
jack_lsp_LDADD = ../libjack/libjack.la

jack_showtime_SOURCES = showtime.c
jack_showtime_LDFLAGS = -ldl -lpthread
jack_showtime_LDADD = ../libjack/libjack.la


if HAVE_FLTK
jack_fltk_client_SOURCES = fltk_client.cc
jack_fltk_client_LDFLAGS = -L/usr/X11R6/lib -lfltk -lX11 -lXext -ldl -lpthread


+ 30
- 0
example-clients/lsp.c View File

@@ -0,0 +1,30 @@
#include <stdio.h>
#include <unistd.h>

#include <jack/jack.h>

int
main (int argc, char *argv[])

{
jack_client_t *client;
const char **ports;
int i;

/* try to become a client of the JACK server */

if ((client = jack_client_new ("lsp")) == 0) {
fprintf (stderr, "jack server not running?\n");
return 1;
}

ports = jack_get_ports (client, NULL, NULL, 0);

for (i = 0; ports[i]; ++i) {
printf ("%s\n", ports[i]);
}
jack_client_close (client);
exit (0);
}


+ 242
- 0
example-clients/metro.c View File

@@ -0,0 +1,242 @@
/*
Copyright (C) 2002 Anthony Van Groningen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <math.h>
#include <jack/jack.h>
#include <glib.h>
#include <getopt.h>
#include <string.h>

typedef jack_default_audio_sample_t sample_t;

const double PI = 3.14;

jack_client_t *client;
jack_port_t *output_port;
unsigned long sr;
int freq = 880;
int bpm;
jack_nframes_t tone_length, wave_length;
sample_t *wave;
long pos = 0;

void
usage ()

{
fprintf (stderr, "\
usage: jack_metro
[ --frequency OR -f frequency (in Hz) ]
[ --amplitude OR -A maximum amplitude (between 0 and 1) ]
[ --duration OR -D duration (in ms) ]
[ --attack OR -a attack (in percent of duration) ]
[ --decay OR -d decay (in percent of duration) ]
[ --name OR -n jack name for metronome client ]
--bpm OR -b beats per minute
");
}

int
process (jack_nframes_t nframes, void *arg)
{
sample_t *buffer = (sample_t *) jack_port_get_buffer(output_port, 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;
}
if (frames_left > 0) {
memcpy (buffer + (nframes - frames_left), wave + pos, sizeof (sample_t) * frames_left);
pos += frames_left;
}
return 0;
}

int
buffer_size_change () {
printf("Buffer size has changed! Exiting...\n");
exit(-1);
}

int
sample_rate_change () {
printf("Sample rate has changed! Exiting...\n");
exit(-1);
}

int
main (int argc, char *argv[])
{
sample_t scale;
int i, attack_length, decay_length;
double *amp;
double max_amp = 0.5;
int option_index;
int opt;
int got_bpm = 0;
int attack_percent = 1, decay_percent = 10, dur_arg = 100;
char *client_name = 0;
char *bpm_string = "bpm";
int verbose = 0;

const char *options = "f:A:D:a:d:b:n:hv";
struct option long_options[] =
{
{"frequency", 1, 0, 'f'},
{"amplitude", 1, 0, 'A'},
{"duration", 1, 0, 'D'},
{"attack", 1, 0, 'a'},
{"decay", 1, 0, 'd'},
{"bpm", 1, 0, 'b'},
{"name", 1, 0, 'n'},
{"help", 0, 0, 'h'},
{"verbose", 0, 0, 'v'},
{0, 0, 0, 0}
};
while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) {
switch (opt) {
case 'f':
if ((freq = atoi (optarg)) <= 0) {
fprintf (stderr, "invalid frequency\n");
return -1;
}
break;
case 'A':
if (((max_amp = atof (optarg)) <= 0)|| (max_amp > 1)) {
fprintf (stderr, "invalid amplitude\n");
return -1;
}
break;
case 'D':
dur_arg = atoi (optarg);
fprintf (stderr, "durarg = %lu\n", dur_arg);
break;
case 'a':
if (((attack_percent = atoi (optarg)) < 0) || (attack_percent > 100)) {
fprintf (stderr, "invalid attack percent\n");
return -1;
}
break;
case 'd':
if (((decay_percent = atoi (optarg)) < 0) || (decay_percent > 100)) {
fprintf (stderr, "invalid decay percent\n");
return -1;
}
break;
case 'b':
got_bpm = 1;
if ((bpm = atoi (optarg)) < 0) {
fprintf (stderr, "invalid bpm\n");
return -1;
}
bpm_string = (char *) malloc ((strlen (optarg) + 4) * sizeof (char));
strcpy (bpm_string, optarg);
strcat (bpm_string, "_bpm");
fprintf (stderr, "bpm = %lu\n", bpm);
break;
case 'n':
client_name = (char *) malloc (strlen (optarg) * sizeof (char));
strcpy (client_name, optarg);
break;
case 'v':
verbose = 1;
break;
default:
fprintf (stderr, "unknown option %c\n", opt);
case 'h':
usage ();
return -1;
}
}
if (!got_bpm) {
fprintf (stderr, "bpm not specified\n");
usage ();
return -1;
}

/* Initial Jack setup, get sample rate */
if (!client_name) {
client_name = (char *) malloc (9 * sizeof (char));
strcpy (client_name, "metro");
}
if ((client = jack_client_new (client_name)) == 0) {
fprintf (stderr, "jack server not running?\n");
return 1;
}
jack_set_process_callback (client, process, 0);
output_port = jack_port_register (client, bpm_string, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

sr = jack_get_sample_rate (client);

/* setup wave table parameters */
wave_length = 60 * sr / bpm;
tone_length = sr * dur_arg / 1000;
attack_length = tone_length * attack_percent / 100;
decay_length = tone_length * decay_percent / 100;
scale = 2 * PI * freq / sr;

if (tone_length >= wave_length) {
fprintf (stderr, "invalid duration (tone length = %lu, wave length = %lu\n", tone_length, wave_length);
return -1;
}
if (attack_length + decay_length > tone_length) {
fprintf (stderr, "invalid attack/decay\n");
return -1;
}

/* Build the wave table */
wave = (sample_t *) malloc (wave_length * sizeof(sample_t));
amp = (double *) malloc (tone_length * sizeof(double));

for (i = 0; i < attack_length; i++) {
amp[i] = max_amp * i / ((double) attack_length);
}
for (i = attack_length; i < tone_length - decay_length; i++) {
amp[i] = max_amp;
}
for (i = tone_length - decay_length; i < tone_length; i++) {
amp[i] = - max_amp * (i - (double) tone_length) / ((double) decay_length);
}
for (i = 0; i < tone_length; i++) {
wave[i] = amp[i] * sin (scale * i);
}
for (i = tone_length; i < wave_length; i++) {
wave[i] = 0;
}

if (jack_activate (client)) {
fprintf (stderr, "cannot activate client");
return 1;
}

if (verbose) {
}

while (1) {
sleep(1);
};
}

+ 85
- 0
example-clients/showtime.c View File

@@ -0,0 +1,85 @@
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>

#include <jack/jack.h>
#include <jack/transport.h>

jack_client_t *client;
jack_transport_info_t now;

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);
}

int
process (jack_nframes_t nframes, void *arg)
{
now.valid = JackTransportState|JackTransportPosition|JackTransportLoop;
jack_get_transport_info (client, &now);
return 0;
}

void
jack_shutdown (void *arg)
{
exit (1);
}

void
signal_handler (int sig)
{
fprintf (stderr, "signal received, exiting ...\n");
jack_client_close (client);
exit (0);
}

int
main (int argc, char *argv[])

{
/* try to become a client of the JACK server */

if ((client = jack_client_new ("showtime")) == 0) {
fprintf (stderr, "jack server not running?\n");
return 1;
}

signal (SIGQUIT, signal_handler);
signal (SIGTERM, signal_handler);
signal (SIGHUP, signal_handler);
signal (SIGINT, signal_handler);

/* tell the JACK server to call `process()' whenever
there is work to be done.
*/

jack_set_process_callback (client, process, 0);

/* tell the JACK server to call `jack_shutdown()' if
it ever shuts down, either entirely, or if it
just decides to stop calling us.
*/

jack_on_shutdown (client, jack_shutdown, 0);

/* tell the JACK server that we are ready to roll */

if (jack_activate (client)) {
fprintf (stderr, "cannot activate client");
return 1;
}
while (1) {
usleep (100000);
showtime ();
}

jack_client_close (client);
exit (0);
}


+ 5
- 3
jack/internal.h View File

@@ -92,10 +92,11 @@ typedef struct {

typedef struct {

jack_time_info_t time;
jack_time_info_t current_time;
jack_time_info_t pending_time;
jack_frame_timer_t frame_timer;
int in_process;
jack_nframes_t frames_at_cycle_start;
jack_nframes_t frames_at_cycle_start;
pid_t engine_pid;
unsigned long buffer_size;
char real_time;
@@ -103,8 +104,9 @@ typedef struct {
int has_capabilities;
float cpu_load;
unsigned long port_max;
jack_port_shared_t ports[0];
int engine_ok;
jack_port_shared_t ports[0];

} jack_control_t;

typedef enum {


+ 24
- 10
jackd/engine.c View File

@@ -411,9 +411,9 @@ jack_set_buffer_size (jack_engine_t *engine, jack_nframes_t nframes)

static int
jack_set_sample_rate (jack_engine_t *engine, jack_nframes_t nframes)

{
engine->control->time.frame_rate = nframes;
engine->control->current_time.frame_rate = nframes;
engine->control->pending_time.frame_rate = nframes;
return 0;
}

@@ -593,6 +593,11 @@ jack_engine_post_process (jack_engine_t *engine)
jack_lock_graph (engine);
/* update timebase */

engine->control->pending_time.cycles = engine->control->current_time.cycles;
engine->control->current_time = engine->control->pending_time;

/* find any clients that need removal due to timeouts, etc. */
for (node = engine->clients; node; node = g_slist_next (node) ) {
@@ -600,7 +605,7 @@ jack_engine_post_process (jack_engine_t *engine)
client = (jack_client_internal_t *) node->data;
ctl = client->control;
if (ctl->timed_out || (ctl->state > NotTriggered && ctl->state != Finished)) {
if (ctl->state > NotTriggered && ctl->state != Finished && ctl->timed_out++) {
client->error = TRUE;
}

@@ -625,8 +630,9 @@ jack_engine_post_process (jack_engine_t *engine)
if (client->error) {
if (engine->verbose) {
fprintf (stderr, "removing failed client %s state = %s\n",
client->control->name, client_state_names[client->control->state]);
fprintf (stderr, "removing failed client %s state = %s errors = %d\n",
client->control->name, client_state_names[client->control->state],
client->error);
}
jack_remove_client (engine, (jack_client_internal_t *) node->data);
@@ -1039,7 +1045,10 @@ jack_client_deactivate (jack_engine_t *engine, jack_client_id_t id)

if (client == engine->timebase_client) {
engine->timebase_client = 0;
engine->control->time.frame = 0;
engine->control->current_time.frame = 0;
engine->control->pending_time.frame = 0;
engine->control->current_time.transport_state = JackTransportStopped;
engine->control->pending_time.transport_state = JackTransportStopped;
}
for (portnode = client->ports; portnode; portnode = g_slist_next (portnode)) {
@@ -1408,8 +1417,10 @@ jack_engine_new (int realtime, int rtpriority, int verbose)
engine->control->cpu_load = 0;
engine->control->buffer_size = 0;
engine->control->time.frame_rate = 0;
engine->control->time.frame = 0;
engine->control->current_time.frame_rate = 0;
engine->control->current_time.frame = 0;
engine->control->pending_time.frame_rate = 0;
engine->control->pending_time.frame = 0;
engine->control->in_process = 0;

engine->control->has_capabilities = 0;
@@ -1675,7 +1686,7 @@ jack_main_thread (void *arg)
/* store the execution time for later averaging */
engine->rolling_client_usecs[engine->rolling_client_usecs_index++] =
(float) (cycle_end - engine->control->time.cycles) / engine->cpu_mhz;
(float) (cycle_end - engine->control->current_time.cycles) / engine->cpu_mhz;
if (engine->rolling_client_usecs_index >= JACK_ENGINE_ROLLING_COUNT) {
engine->rolling_client_usecs_index = 0;
@@ -1882,7 +1893,10 @@ jack_remove_client (jack_engine_t *engine, jack_client_internal_t *client)

if (client == engine->timebase_client) {
engine->timebase_client = 0;
engine->control->time.frame = 0;
engine->control->current_time.frame = 0;
engine->control->pending_time.frame = 0;
engine->control->current_time.transport_state = JackTransportStopped;
engine->control->pending_time.transport_state = JackTransportStopped;
}

jack_client_disconnect (engine, client);


+ 4
- 0
jackd/jackd.c View File

@@ -214,6 +214,8 @@ jack_engine_waiter_thread (void *arg)
}

if (warg->argc) {

fprintf (stderr, "loading driver ..\n");
if ((driver = jack_driver_load (warg->argc, warg->argv)) == 0) {
fprintf (stderr, "cannot load driver module %s\n", warg->argv[0]);
@@ -228,6 +230,8 @@ jack_engine_waiter_thread (void *arg)
jack_set_asio_mode (engine, TRUE);
}

fprintf (stderr, "starting engine\n");

if (jack_run (engine)) {
fprintf (stderr, "cannot start main JACK thread\n");
kill (warg->pid, SIGTERM);


+ 8
- 8
libjack/client.c View File

@@ -1100,7 +1100,7 @@ unsigned long jack_get_buffer_size (jack_client_t *client)
unsigned long jack_get_sample_rate (jack_client_t *client)

{
return client->engine->time.frame_rate;
return client->engine->current_time.frame_rate;
}

static jack_port_t *
@@ -1513,7 +1513,7 @@ jack_set_sample_rate_callback (jack_client_t *client, JackSampleRateCallback cal

/* Now invoke it */

callback (client->engine->time.frame_rate, arg);
callback (client->engine->current_time.frame_rate, arg);

return 0;
}
@@ -1780,8 +1780,8 @@ jack_frames_since_cycle_start (const jack_client_t *client)
{
float usecs;

usecs = (float) (get_cycles() - client->engine->time.cycles) / client->cpu_mhz;
return (jack_nframes_t) floor ((((float) client->engine->time.frame_rate) / 1000000.0f) * usecs);
usecs = (float) (get_cycles() - client->engine->current_time.cycles) / client->cpu_mhz;
return (jack_nframes_t) floor ((((float) client->engine->current_time.frame_rate) / 1000000.0f) * usecs);
}

jack_nframes_t
@@ -1794,7 +1794,7 @@ jack_frame_time (const jack_client_t *client)
jack_read_frame_time (client, &current);
usecs = (float) (get_cycles() - current.stamp) / client->cpu_mhz;
elapsed = (jack_nframes_t) floor ((((float) client->engine->time.frame_rate) / 1000000.0f) * usecs);
elapsed = (jack_nframes_t) floor ((((float) client->engine->current_time.frame_rate) / 1000000.0f) * usecs);
return current.frames + elapsed;
}
@@ -1940,8 +1940,8 @@ int
jack_get_transport_info (jack_client_t *client,
jack_transport_info_t *info)
{
jack_time_info_t *time_info = &client->engine->time;
jack_time_info_t *time_info = &client->engine->current_time;
if (info->valid & JackTransportState) {
info->state = time_info->transport_state;
}
@@ -1962,7 +1962,7 @@ int
jack_set_transport_info (jack_client_t *client,
jack_transport_info_t *info)
{
jack_time_info_t *time_info = &client->engine->time;
jack_time_info_t *time_info = &client->engine->pending_time;
if (info->valid & JackTransportState) {
time_info->transport_state = info->state;


Loading…
Cancel
Save