Browse Source

directory reorganization

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@189 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.109.0
pbd 23 years ago
parent
commit
e1ad1100f7
18 changed files with 3 additions and 9046 deletions
  1. +3
    -0
      README
  2. +0
    -1664
      alsa_driver.c
  3. +0
    -176
      cache_killer.c
  4. +0
    -372
      capture_client.c
  5. +0
    -1847
      client.c
  6. +0
    -121
      connect.c
  7. +0
    -106
      driver.c
  8. +0
    -2840
      engine.c
  9. +0
    -99
      fltk_client.cc
  10. +0
    -57
      generic_hw.c
  11. +0
    -296
      hammerfall.c
  12. +0
    -152
      ice1712.c
  13. +0
    -217
      impulse_grabber.c
  14. +0
    -445
      jackd.c
  15. +0
    -459
      memops.c
  16. +0
    -30
      monitor_client.c
  17. +0
    -37
      pool.c
  18. +0
    -128
      simple_client.c

+ 3
- 0
README View File

@@ -0,0 +1,3 @@
Welcome to JACK, the Jack Audio Connection Kit.

Please see the website (http://jackit.sf.net/) for more information.

+ 0
- 1664
alsa_driver.c
File diff suppressed because it is too large
View File


+ 0
- 176
cache_killer.c View File

@@ -1,176 +0,0 @@
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>

#include <jack/jack.h>
#include <glib.h>
#include <jack/port.h>
#include <jack/cycles.h>

jack_port_t *input_port;
jack_port_t *output_port;

volatile char *buf;
unsigned long stompsize;
int do_stomp = 0;

pthread_mutex_t foolock = PTHREAD_MUTEX_INITIALIZER;

int
process (jack_nframes_t nframes, void *arg)

{
unsigned long i;
unsigned long long now, then;

jack_default_audio_sample_t *out = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port, nframes);
jack_default_audio_sample_t *in = (jack_default_audio_sample_t *) jack_port_get_buffer (input_port, nframes);

now = get_cycles ();
if (pthread_mutex_trylock (&foolock) == 0) {
then = get_cycles ();
if (do_stomp) {
for (i = 0; i < stompsize; ++i) {
buf[i]++;
}
} else {
for (i = 0; i < stompsize; ++i) {
buf[0]++;
}
}
then = get_cycles ();
pthread_mutex_unlock (&foolock);
}

memcpy (out, in, sizeof (jack_default_audio_sample_t) * nframes);
return 0;
}

int
bufsize (jack_nframes_t nframes, void *arg)

{
printf ("the maximum buffer size is now %lu\n", nframes);
return 0;
}

int
srate (jack_nframes_t nframes, void *arg)

{
printf ("the sample rate is now %lu/sec\n", nframes);
return 0;
}

void
jack_shutdown (void *arg)
{
printf ("shutdown by JACK\n");
exit (1);
}

void *
other_thread (void *arg)
{
while (1) {
pthread_mutex_lock (&foolock);
usleep (3000);
pthread_mutex_unlock (&foolock);
usleep (3000);
}
return 0;
}

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

{
jack_client_t *client;
pthread_t other;

if (argc < 2) {
fprintf (stderr, "usage: jack_simple_client <name>\n");
return 1;
}

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

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

stompsize = atoi (argv[2]);
buf = (char *) malloc (sizeof (char) * stompsize);

do_stomp = atoi (argv[3]);

pthread_create (&other, NULL, other_thread, NULL);

/* 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 `bufsize()' whenever
the maximum number of frames that will be passed
to `process()' changes
*/

jack_set_buffer_size_callback (client, bufsize, 0);

/* tell the JACK server to call `srate()' whenever
the sample rate of the system changes.
*/


jack_set_sample_rate_callback (client, srate, 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);

/* display the current sample rate. once the client is activated
(see below), you should rely on your own sample rate
callback (see above) for this value.
*/

printf ("engine sample rate: %lu\n", jack_get_sample_rate (client));

/* create two ports */

input_port = jack_port_register (client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
output_port = jack_port_register (client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

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

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

/* connect the ports. Note: you can't do this before
the client is activated (this may change in the future).
*/

if (jack_connect (client, "alsa_pcm:in_1", jack_port_name (input_port))) {
fprintf (stderr, "cannot connect input ports\n");
}
if (jack_connect (client, jack_port_name (output_port), "alsa_pcm:out_1")) {
fprintf (stderr, "cannot connect output ports\n");
}

/* Since this is just a toy, run for a few seconds, then finish */

sleep (10);
jack_client_close (client);
printf ("finished OK\n");
exit (0);
}


+ 0
- 372
capture_client.c View File

@@ -1,372 +0,0 @@
/*
Copyright (C) 2001 Paul Davis
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.

$Id$
*/

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sndfile.h>
#include <pthread.h>
#include <glib.h>
#include <getopt.h>

#include <jack/jack.h>

typedef struct _thread_info {
pthread_t thread_id;
SNDFILE *sf;
jack_nframes_t duration;
jack_client_t *client;
unsigned int channels;
int bitdepth;
int can_capture;
char *path;
int status;
int can_process;
} thread_info_t;

unsigned int nports;
jack_port_t **ports;

pthread_mutex_t buffer_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t data_ready = PTHREAD_COND_INITIALIZER;

typedef struct _sample_buffer {
jack_nframes_t nframes;
jack_default_audio_sample_t **data;
} sample_buffer_t;

sample_buffer_t *
sample_buffer_new (jack_nframes_t nframes, unsigned int nchans)
{
sample_buffer_t *buf;
unsigned int i;

buf = (sample_buffer_t *) malloc (sizeof (sample_buffer_t));
buf->nframes = nframes;
buf->data = (jack_default_audio_sample_t **) malloc (sizeof (jack_default_audio_sample_t *) * nchans);

for (i = 0; i < nchans; i++) {
buf->data[i] = (jack_default_audio_sample_t *) malloc (sizeof (jack_default_audio_sample_t) * nframes);
}

return buf;
}

GSList *pending_writes = NULL;
GSList *free_buffers = NULL;

sample_buffer_t *
get_free_buffer (jack_nframes_t nframes, unsigned int nchans)
{
sample_buffer_t *buf;

if (free_buffers == NULL) {
buf = sample_buffer_new (nframes, nchans);
} else {
buf = (sample_buffer_t *) free_buffers->data;
free_buffers = g_slist_next (free_buffers);
}

return buf;
}

sample_buffer_t *
get_write_buffer ()
{
sample_buffer_t *buf;

if (pending_writes == NULL) {
return NULL;
}

buf = (sample_buffer_t *) pending_writes->data;
pending_writes = g_slist_next (pending_writes);

return buf;
}

void
put_write_buffer (sample_buffer_t *buf)
{
pending_writes = g_slist_append (pending_writes, buf);
}

void
put_free_buffer (sample_buffer_t *buf)
{
free_buffers = g_slist_prepend (free_buffers, buf);
}

void *
disk_thread (void *arg)
{
sample_buffer_t *buf;
thread_info_t *info = (thread_info_t *) arg;
int i;
unsigned int chn;
jack_nframes_t total_captured = 0;
int done = 0;
double *fbuf;

pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_mutex_lock (&buffer_lock);

/* preload the buffer cache */

for (i = 0; i < 8; i++) {
buf = sample_buffer_new (jack_get_buffer_size (info->client), info->channels);
put_free_buffer (buf);
}

info->status = 0;

while (!done) {
pthread_cond_wait (&data_ready, &buffer_lock);

while ((buf = get_write_buffer ()) != 0) {
pthread_mutex_unlock (&buffer_lock);

/* grrr ... libsndfile doesn't do float data yet, only double */
if (info->can_capture) {

fbuf = (double *) malloc (sizeof (double) * buf->nframes * info->channels);

for (chn = 0; chn < info->channels; chn++) {
for (i = 0; i < buf->nframes; i++) {
fbuf[chn+(i*info->channels)] = buf->data[chn][i];
}
}
if (sf_writef_double (info->sf, fbuf, buf->nframes, 1) != buf->nframes) {
char errstr[256];
sf_error_str (0, errstr, sizeof (errstr) - 1);
fprintf (stderr, "cannot write data to sndfile (%s)\n", errstr);
info->status = -1;
done = 1;
break;
}
free (fbuf);
total_captured += buf->nframes;

if (total_captured >= info->duration) {
printf ("disk thread finished\n");
done = 1;
break;
}
}

pthread_mutex_lock (&buffer_lock);
put_free_buffer (buf);
}
}

pthread_mutex_unlock (&buffer_lock);
return 0;
}
int
process (jack_nframes_t nframes, void *arg)

{
thread_info_t *info = (thread_info_t *) arg;
jack_default_audio_sample_t *in;
sample_buffer_t *buf;
unsigned int i;

if (!info->can_process) {
return 0;
}

/* we don't like taking locks, but until we have a lock
free ringbuffer written in C, this is what has to be done
*/

pthread_mutex_lock (&buffer_lock);

buf = get_free_buffer (nframes, nports);

for (i = 0; i < nports; i++) {
in = (jack_default_audio_sample_t *) jack_port_get_buffer (ports[i], nframes);
memcpy (buf->data[i], in, sizeof (jack_default_audio_sample_t) * nframes);
}

put_write_buffer (buf);

/* tell the disk thread that there is work to do */
pthread_cond_signal (&data_ready);
pthread_mutex_unlock (&buffer_lock);

return 0;
}

void
jack_shutdown (void *arg)
{
fprintf (stderr, "JACK shutdown\n");
exit (0);
}

void
setup_disk_thread (thread_info_t *info)
{
SF_INFO sf_info;

sf_info.samplerate = jack_get_sample_rate (info->client);
sf_info.channels = info->channels;
sf_info.format = SF_FORMAT_WAV|SF_FORMAT_PCM;
sf_info.pcmbitwidth = info->bitdepth;

if ((info->sf = sf_open_write (info->path, &sf_info)) == NULL) {
char errstr[256];
sf_error_str (0, errstr, sizeof (errstr) - 1);
fprintf (stderr, "cannot open sndfile \"%s\" for output (%s)\n", info->path, errstr);
jack_client_close (info->client);
exit (1);
}

info->duration *= sf_info.samplerate;
info->can_capture = 0;

pthread_create (&info->thread_id, NULL, disk_thread, info);
}

void
run_disk_thread (thread_info_t *info)
{
info->can_capture = 1;
pthread_join (info->thread_id, NULL);
sf_close (info->sf);
if (info->status) {
unlink (info->path);
}
}

void
setup_ports (int sources, char *source_names[], thread_info_t *info)
{
int i;

nports = sources;

ports = (jack_port_t **) malloc (sizeof (jack_port_t *) * nports);

for (i = 0; i < nports; i++) {
char name[64];

sprintf (name, "input%d", i+1);

if ((ports[i] = jack_port_register (info->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == 0) {
fprintf (stderr, "cannot register input port \"%s\"!\n", name);
jack_client_close (info->client);
exit (1);
}
}

for (i = 0; i < nports; i++) {
if (jack_connect (info->client, source_names[i], jack_port_name (ports[i]))) {
fprintf (stderr, "cannot connect input port %s to %s\n", jack_port_name (ports[i]), source_names[i]);
jack_client_close (info->client);
exit (1);
}
}

info->can_process = 1;
}

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

{
jack_client_t *client;
thread_info_t thread_info;
int c;
int longopt_index = 0;
extern int optind, opterr;
int show_usage = 0;
char *optstring = "d:f:b:h";
struct option long_options[] = {
{ "help", 1, 0, 'h' },
{ "duration", 1, 0, 'd' },
{ "file", 1, 0, 'f' },
{ "bitdepth", 1, 0, 'b' },
{ 0, 0, 0, 0 }
};

memset (&thread_info, 0, sizeof (thread_info));
opterr = 0;

while ((c = getopt_long (argc, argv, optstring, long_options, &longopt_index)) != -1) {
switch (c) {
case 1:
/* getopt signals end of '-' options */
break;

case 'h':
show_usage++;
break;
case 'd':
thread_info.duration = atoi (optarg);
break;
case 'f':
thread_info.path = optarg;
break;
case 'b':
thread_info.bitdepth = atoi (optarg);
break;
default:
fprintf (stderr, "error\n");
show_usage++;
break;
}
}

if (show_usage || thread_info.path == NULL || optind == argc) {
fprintf (stderr, "usage: jackrec -f filename [ -d second ] [ -b bitdepth ] port1 [ port2 ... ]\n");
exit (1);
}

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

thread_info.client = client;
thread_info.channels = argc - optind;
thread_info.can_process = 0;

setup_disk_thread (&thread_info);

jack_set_process_callback (client, process, &thread_info);
jack_on_shutdown (client, jack_shutdown, NULL);

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

setup_ports (argc - optind, &argv[optind], &thread_info);

run_disk_thread (&thread_info);

jack_client_close (client);
exit (0);
}

+ 0
- 1847
client.c
File diff suppressed because it is too large
View File


+ 0
- 121
connect.c View File

@@ -1,121 +0,0 @@
#include <stdio.h>
/*
Copyright (C) 2002 Jeremy Hall
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.

$Id$
*/

#include <errno.h>
#include <unistd.h>
#include <string.h>

#include <jack/jack.h>

jack_port_t *input_port;
jack_port_t *output_port;
int connecting, disconnecting;
#define TRUE 1
#define FALSE 0

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

{
jack_client_t *client;
char *my_name = strrchr(argv[0], '/');
connecting = disconnecting = FALSE;
if (my_name == 0) {
my_name = argv[0];
} else {
my_name ++;
}

if (strstr(my_name, "disconnect")) {
disconnecting = TRUE;
} else
if (strstr(my_name, "connect")) {
connecting = TRUE;
} else {
fprintf(stderr, "ERROR! client should be called jack_connect or jack_disconnect. client is called %s\n", my_name);
return 1;
}

if (argc != 3) {
fprintf (stderr, "usage: %s <src_port> <dst_port>\n", my_name);
fprintf(stderr, "The source port must be an output port of the source client.\n");
fprintf (stderr, "The destination port must be an input port of the destination client.\n");
return 1;
}

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

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

/* display the current sample rate. once the client is activated
(see below), you should rely on your own sample rate
callback (see above) for this value.
*/

printf ("engine sample rate: %lu\n", jack_get_sample_rate (client));

/* find the two ports */

if ((input_port = jack_port_by_name(client, argv[1])) == 0) {
fprintf (stderr, "ERROR %s not a valid port\n", argv[1]);
return 1;
}
if ((output_port = jack_port_by_name(client, argv[2])) == 0) {
fprintf (stderr, "ERROR %s not a valid port\n", argv[2]);
return 1;
}

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

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

/* connect the ports. Note: you can't do this before
the client is activated (this may change in the future).
*/

/* jack_port_connect not implemented
if (jack_port_connect(client, input_port, output_port)) {
fprintf (stderr, "cannot connect ports\n");
}
*/
if (connecting) {
if (jack_connect(client, jack_port_name(input_port), jack_port_name(output_port))) {
fprintf (stderr, "cannot connect ports\n");
return 1;
}
}
if (disconnecting) {
if (jack_disconnect(client, jack_port_name(input_port), jack_port_name(output_port))) {
fprintf (stderr, "cannot disconnect ports\n");
return 1;
}
}

jack_client_close (client);
exit (0);
}


+ 0
- 106
driver.c View File

@@ -1,106 +0,0 @@
/*
Copyright (C) 2001 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
$Id$
*/

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>

#include <jack/driver.h>
#include <jack/internal.h>
#include <jack/error.h>

static int dummy_attach (jack_driver_t *drv, jack_engine_t *eng) { return 0; }
static int dummy_detach (jack_driver_t *drv, jack_engine_t *eng) { return 0; }
static jack_nframes_t dummy_wait (jack_driver_t *drv, int fd, int *status, float *delayed_usecs) { *status = 0; *delayed_usecs = 0; return 0; }
static int dummy_process (jack_driver_t *drv, jack_nframes_t nframes) { return 0; }
static int dummy_stop (jack_driver_t *drv) { return 0; }
static int dummy_start (jack_driver_t *drv) { return 0; }

void
jack_driver_init (jack_driver_t *driver)

{
memset (driver, 0, sizeof (*driver));

driver->attach = dummy_attach;
driver->detach = dummy_detach;
driver->wait = dummy_wait;
driver->process = dummy_process;
driver->start = dummy_start;
driver->stop = dummy_stop;
}

jack_driver_t *
jack_driver_load (int argc, char **argv)

{
const char *errstr;
dlhandle handle;
jack_driver_t *driver;
jack_driver_t *(*initialize)(int, char **);
void (*finish)(jack_driver_t *);
char path_to_so[PATH_MAX+1];

snprintf (path_to_so, sizeof (path_to_so), ADDON_DIR "/jack_%s.so", argv[0]);
handle = dlopen (path_to_so, RTLD_NOW|RTLD_GLOBAL);
if (handle == 0) {
if ((errstr = dlerror ()) != 0) {
jack_error ("can't load \"%s\": %s", path_to_so, errstr);
} else {
jack_error ("bizarre error loading driver shared object %s", path_to_so);
}
return 0;
}

initialize = dlsym (handle, "driver_initialize");

if ((errstr = dlerror ()) != 0) {
jack_error ("no initialize function in shared object %s\n", path_to_so);
dlclose (handle);
return 0;
}

finish = dlsym (handle, "driver_finish");

if ((errstr = dlerror ()) != 0) {
jack_error ("no finish function in in shared driver object %s", path_to_so);
dlclose (handle);
return 0;
}

if ((driver = initialize (argc, argv)) != 0) {
driver->handle = handle;
driver->finish = finish;
}

return driver;

}

void
jack_driver_unload (jack_driver_t *driver)
{
driver->finish (driver);
dlclose (driver->handle);
}

+ 0
- 2840
engine.c
File diff suppressed because it is too large
View File


+ 0
- 99
fltk_client.cc View File

@@ -1,99 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

extern "C"
{
#include <jack/jack.h>
}

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Slider.H>

jack_port_t *input_port;
jack_port_t *output_port;

float gain = 0.0; /* slider starts out with zero gain */

int
process (jack_nframes_t nframes, void *arg)

{
jack_default_audio_sample_t *out = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port, nframes);
jack_default_audio_sample_t *in = (jack_default_audio_sample_t *) jack_port_get_buffer (input_port, nframes);

while (nframes--)
out[nframes] = in[nframes] * gain;

return 0;
}

int
bufsize (jack_nframes_t nframes, void *arg)

{
printf ("the maximum buffer size is now %lu\n", nframes);
return 0;
}

int
srate (jack_nframes_t nframes, void *arg)

{
printf ("the sample rate is now %lu/sec\n", nframes);
return 0;
}

void callback(Fl_Slider* s)
{
gain = s->value();
}

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

{
Fl_Window w(0,0,100,120);
Fl_Slider s(10,10,20,100);
w.show();
s.callback((Fl_Callback*) callback);
jack_client_t *client;

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

jack_set_process_callback (client, process, 0);
jack_set_buffer_size_callback (client, bufsize, 0);
jack_set_sample_rate_callback (client, srate, 0);

printf ("engine sample rate: %lu\n", jack_get_sample_rate (client));

input_port = jack_port_register (client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
output_port = jack_port_register (client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

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

printf ("client activated\n");

if (jack_connect (client, "alsa_pcm:in_1", jack_port_name (input_port))) {
fprintf (stderr, "cannot connect input ports\n");
}

if (jack_connect (client, jack_port_name (output_port), "alsa_pcm:out_1")) {
fprintf (stderr, "cannot connect output ports\n");
}

Fl::run();

printf ("done sleeping, now closing...\n");
jack_client_close (client);
exit (0);
}


+ 0
- 57
generic_hw.c View File

@@ -1,57 +0,0 @@
/*
Copyright (C) 2001 Paul Davis

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.

$Id$
*/

#include <jack/hardware.h>
#include <jack/alsa_driver.h>

static int generic_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask)
{
return -1;
}

static int generic_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode)
{
return -1;
}

void
jack_alsa_generic_hw_release (jack_hardware_t *hw)

{
return;
}

jack_hardware_t *
jack_alsa_generic_hw_new (alsa_driver_t *driver)

{
jack_hardware_t *hw;

hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t));

hw->capabilities = 0;
hw->input_monitor_mask = 0;
hw->set_input_monitor_mask = generic_set_input_monitor_mask;
hw->change_sample_clock = generic_change_sample_clock;
hw->release = jack_alsa_generic_hw_release;

return hw;
}

+ 0
- 296
hammerfall.c View File

@@ -1,296 +0,0 @@
/*
Copyright (C) 2001 Paul Davis

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.

$Id$
*/

#include <jack/hardware.h>
#include <jack/alsa_driver.h>
#include <jack/hammerfall.h>
#include <jack/error.h>

static void
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_device (ctl, 0);
snd_ctl_elem_id_set_subdevice (ctl, 0);
snd_ctl_elem_id_set_index (ctl, 0);
}

static void
hammerfall_broadcast_channel_status_change (hammerfall_t *h, int lock, int sync, channel_t lowchn, channel_t highchn)

{
channel_t chn;
ClockSyncStatus status = 0;

if (lock) {
status |= Lock;
} else {
status |= NoLock;
}

if (sync) {
status |= Sync;
} else {
status |= NoSync;
}

for (chn = lowchn; chn < highchn; chn++) {
alsa_driver_set_clock_sync_status (h->driver, chn, status);
}
}

static void
hammerfall_check_sync_state (hammerfall_t *h, int val, int adat_id)

{
int lock;
int sync;

/* S/PDIF channel is always locked and synced, but we only
need tell people once that this is TRUE.

XXX - maybe need to make sure that the rate matches our
idea of the current rate ?
*/

if (!h->said_that_spdif_is_fine) {
ClockSyncStatus status;
status = Lock|Sync;

/* XXX broken! fix for hammerfall light ! */

alsa_driver_set_clock_sync_status (h->driver, 24, status);
alsa_driver_set_clock_sync_status (h->driver, 25, status);

h->said_that_spdif_is_fine = TRUE;
}

lock = (val & 0x1) ? TRUE : FALSE;
sync = (val & 0x2) ? TRUE : FALSE;
if (h->lock_status[adat_id] != lock ||
h->sync_status[adat_id] != sync) {
hammerfall_broadcast_channel_status_change (h, lock, sync, adat_id*8, (adat_id*8)+8);
}

h->lock_status[adat_id] = lock;
h->sync_status[adat_id] = sync;
}

static void
hammerfall_check_sync (hammerfall_t *h, snd_ctl_elem_value_t *ctl)

{
const char *name;
int val;
snd_ctl_elem_id_t *ctl_id;
printf ("check sync\n");

snd_ctl_elem_id_alloca (&ctl_id);
snd_ctl_elem_value_get_id (ctl, ctl_id);

name = snd_ctl_elem_id_get_name (ctl_id);

if (strcmp (name, "ADAT1 Sync Check") == 0) {
val = snd_ctl_elem_value_get_enumerated (ctl, 0);
hammerfall_check_sync_state (h, val, 0);
} else if (strcmp (name, "ADAT2 Sync Check") == 0) {
val = snd_ctl_elem_value_get_enumerated (ctl, 0);
hammerfall_check_sync_state (h, val, 1);
} else if (strcmp (name, "ADAT3 Sync Check") == 0) {
val = snd_ctl_elem_value_get_enumerated (ctl, 0);
hammerfall_check_sync_state (h, val, 2);
} else {
jack_error ("Hammerfall: unknown control \"%s\"", name);
}
}

static int
hammerfall_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask)
{
hammerfall_t *h = (hammerfall_t *) hw->private;
snd_ctl_elem_value_t *ctl;
snd_ctl_elem_id_t *ctl_id;
int err;
int i;
snd_ctl_elem_value_alloca (&ctl);
snd_ctl_elem_id_alloca (&ctl_id);
set_control_id (ctl_id, "Channels Thru");
snd_ctl_elem_value_set_id (ctl, ctl_id);
for (i = 0; i < 26; i++) {
snd_ctl_elem_value_set_integer (ctl, i, (mask & (1<<i)) ? 1 : 0);
}
if ((err = snd_ctl_elem_write (h->driver->ctl_handle, ctl)) != 0) {
jack_error ("ALSA/Hammerfall: cannot set input monitoring (%s)", snd_strerror (err));
return -1;
}
hw->input_monitor_mask = mask;

return 0;
}

static int
hammerfall_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode)
{
hammerfall_t *h = (hammerfall_t *) hw->private;
snd_ctl_elem_value_t *ctl;
snd_ctl_elem_id_t *ctl_id;
int err;

snd_ctl_elem_value_alloca (&ctl);
snd_ctl_elem_id_alloca (&ctl_id);
set_control_id (ctl_id, "Sync Mode");
snd_ctl_elem_value_set_id (ctl, ctl_id);

switch (mode) {
case AutoSync:
snd_ctl_elem_value_set_enumerated (ctl, 0, 0);
break;
case ClockMaster:
snd_ctl_elem_value_set_enumerated (ctl, 0, 1);
break;
case WordClock:
snd_ctl_elem_value_set_enumerated (ctl, 0, 2);
break;
}

if ((err = snd_ctl_elem_write (h->driver->ctl_handle, ctl)) < 0) {
jack_error ("ALSA-Hammerfall: cannot set clock mode");
}

return 0;
}

static void
hammerfall_release (jack_hardware_t *hw)

{
hammerfall_t *h = (hammerfall_t *) hw->private;
void *status;

if (h == 0) {
return;
}

pthread_cancel (h->monitor_thread);
pthread_join (h->monitor_thread, &status);

free (h);
}

static void *
hammerfall_monitor_controls (void *arg)
{
jack_hardware_t *hw = (jack_hardware_t *) arg;
hammerfall_t *h = (hammerfall_t *) hw->private;
snd_ctl_elem_id_t *switch_id[3];
snd_ctl_elem_value_t *sw[3];

pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

snd_ctl_elem_id_malloc (&switch_id[0]);
snd_ctl_elem_id_malloc (&switch_id[1]);
snd_ctl_elem_id_malloc (&switch_id[2]);

snd_ctl_elem_value_malloc (&sw[0]);
snd_ctl_elem_value_malloc (&sw[1]);
snd_ctl_elem_value_malloc (&sw[2]);

set_control_id (switch_id[0], "ADAT1 Sync Check");
set_control_id (switch_id[1], "ADAT2 Sync Check");
set_control_id (switch_id[2], "ADAT3 Sync Check");

snd_ctl_elem_value_set_id (sw[0], switch_id[0]);
snd_ctl_elem_value_set_id (sw[1], switch_id[1]);
snd_ctl_elem_value_set_id (sw[2], switch_id[2]);

while (1) {
if (snd_ctl_elem_read (h->driver->ctl_handle, sw[0])) {
jack_error ("cannot read control switch 0 ...");
}
hammerfall_check_sync (h, sw[0]);

if (snd_ctl_elem_read (h->driver->ctl_handle, sw[1])) {
jack_error ("cannot read control switch 0 ...");
}
hammerfall_check_sync (h, sw[1]);

if (snd_ctl_elem_read (h->driver->ctl_handle, sw[2])) {
jack_error ("cannot read control switch 0 ...");
}
hammerfall_check_sync (h, sw[2]);
if (nanosleep (&h->monitor_interval, 0)) {
break;
}
}

pthread_exit (0);
}

jack_hardware_t *
jack_alsa_hammerfall_hw_new (alsa_driver_t *driver)

{
jack_hardware_t *hw;
hammerfall_t *h;

hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t));

hw->capabilities = Cap_HardwareMonitoring|Cap_AutoSync|Cap_WordClock|Cap_ClockMaster|Cap_ClockLockReporting;
hw->input_monitor_mask = 0;
hw->private = 0;

hw->set_input_monitor_mask = hammerfall_set_input_monitor_mask;
hw->change_sample_clock = hammerfall_change_sample_clock;
hw->release = hammerfall_release;

h = (hammerfall_t *) malloc (sizeof (hammerfall_t));

h->lock_status[0] = FALSE;
h->sync_status[0] = FALSE;
h->lock_status[1] = FALSE;
h->sync_status[1] = FALSE;
h->lock_status[2] = FALSE;
h->sync_status[2] = FALSE;
h->said_that_spdif_is_fine = FALSE;
h->driver = driver;

h->monitor_interval.tv_sec = 1;
h->monitor_interval.tv_nsec = 0;

hw->private = h;

#if 0
if (pthread_create (&h->monitor_thread, 0, hammerfall_monitor_controls, hw)) {
jack_error ("ALSA/Hammerfall: cannot create sync monitor thread");
}
#endif

return hw;
}

+ 0
- 152
ice1712.c View File

@@ -1,152 +0,0 @@
/*
Copyright (C) 2002 Anthony Van Groningen

Parts based on source code taken from the
"Env24 chipset (ICE1712) control utility" that is

Copyright (C) 2000 by Jaroslav Kysela <perex@suse.cz>

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 <jack/hardware.h>
#include <jack/alsa_driver.h>
#include <jack/ice1712.h>
#include <jack/error.h>

static int
ice1712_hw_monitor_toggle(jack_hardware_t *hw, int idx, int onoff)

{
ice1712_t *h = (ice1712_t *) hw->private;
snd_ctl_elem_value_t *val;
int err;
snd_ctl_elem_value_alloca (&val);
snd_ctl_elem_value_set_interface (val, SND_CTL_ELEM_IFACE_MIXER);
if (idx >= 8) {
snd_ctl_elem_value_set_name (val, SPDIF_PLAYBACK_ROUTE_NAME);
snd_ctl_elem_value_set_index (val, idx - 8);
} else {
snd_ctl_elem_value_set_name (val, ANALOG_PLAYBACK_ROUTE_NAME);
snd_ctl_elem_value_set_index (val, idx);
}
if (onoff) {
snd_ctl_elem_value_set_enumerated (val, 0, idx + 1);
} else {
snd_ctl_elem_value_set_enumerated (val, 0, 0);
}
if ((err = snd_ctl_elem_write (h->driver->ctl_handle, val)) != 0) {
jack_error ("ALSA/ICE1712: (%d) cannot set input monitoring (%s)",
idx,snd_strerror (err));
return -1;
}

return 0;
}

static int
ice1712_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask)
{
int idx;
ice1712_t *h = (ice1712_t *) hw->private;
for (idx = 0; idx < 10; idx++) {
if (h->active_channels & (1<<idx)) {
ice1712_hw_monitor_toggle (hw, idx, mask & (1<<idx) ? 1 : 0);
}
}
hw->input_monitor_mask = mask;
return 0;
}

static int
ice1712_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode)
{
return -1;
}

static void
ice1712_release (jack_hardware_t *hw)

{
return;
}




jack_hardware_t *
jack_alsa_ice1712_hw_new (alsa_driver_t *driver)

{
jack_hardware_t *hw;
ice1712_t *h;
snd_ctl_elem_value_t *val;
int err;

hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t));

hw->capabilities = Cap_HardwareMonitoring;
hw->input_monitor_mask = 0;
hw->private = 0;

hw->set_input_monitor_mask = ice1712_set_input_monitor_mask;
hw->change_sample_clock = ice1712_change_sample_clock;
hw->release = ice1712_release;

h = (ice1712_t *) malloc (sizeof (ice1712_t));

h->driver = driver;

/* Get the EEPROM (adopted from envy24control) */
h->eeprom = (ice1712_eeprom_t *) malloc (sizeof (ice1712_eeprom_t));
snd_ctl_elem_value_alloca (&val);
snd_ctl_elem_value_set_interface (val, SND_CTL_ELEM_IFACE_CARD);
snd_ctl_elem_value_set_name (val, "ICE1712 EEPROM");
if ((err = snd_ctl_elem_read (driver->ctl_handle, val)) < 0) {
jack_error( "ALSA/ICE1712: Unable to read EEPROM contents (%s)\n", snd_strerror (err));
/* Recover? */
}
memcpy(h->eeprom, snd_ctl_elem_value_get_bytes(val), 32);

/* determine number of pro ADC's. We're asumming that there is at least one stereo pair.
Should check this first, but how? */
switch((h->eeprom->codec & 0xCU) >> 2) {
case 0:
h->active_channels = 0x3U;
break;
case 1:
h->active_channels = 0xfU;
break;
case 2:
h->active_channels = 0x3fU;
break;
case 3:
h->active_channels = 0xffU;
break;
}
/* check for SPDIF In's */
if (h->eeprom->spdif & 0x1U) {
h->active_channels |= 0x300U;
}
hw->private = h;

return hw;
}

+ 0
- 217
impulse_grabber.c View File

@@ -1,217 +0,0 @@
/*
* Copyright (C) 2001 Steve Harris
*
* 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.
*
* $Id$
*/

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <math.h>
#include <getopt.h>

#include <jack/jack.h>

jack_port_t *input_port;
jack_port_t *output_port;

unsigned int impulse_sent = 0;
float *response;
unsigned long response_duration;
unsigned long response_pos;
int grab_finished = 0;

int
process (jack_nframes_t nframes, void *arg)

{
jack_default_audio_sample_t *out = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port, nframes);
jack_default_audio_sample_t *in = (jack_default_audio_sample_t *) jack_port_get_buffer (input_port, nframes);
unsigned int i;

if (grab_finished) {
return 0;
} else if (impulse_sent) {
for(i=0; i<nframes && response_pos < response_duration; i++) {
response[response_pos++] = in[i];
}
if (response_pos >= response_duration) {
grab_finished = 1;
}
for (i=0; i<nframes; i++) {
out[i] = 0.0f;;
}
} else {
out[0] = 1.0f;
for (i=1; i<nframes; i++) {
out[i] = 0.0f;
}
impulse_sent = 1;
}

return 0;
}

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

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

{
jack_client_t *client;
float fs; // The sample rate
float peak;
unsigned long peak_sample;
unsigned int i;
float duration = 0.0f;
unsigned int c_format = 0;
int longopt_index = 0;
int c;
extern int optind, opterr;
int show_usage = 0;
char *optstring = "d:f";
struct option long_options[] = {
{ "help", 1, 0, 'h' },
{ "duration", 1, 0, 'd' },
{ "format", 1, 0, 'f' },
{ 0, 0, 0, 0 }
};

while ((c = getopt_long (argc, argv, optstring, long_options, &longopt_index)) != -1) {
switch (c) {
case 1:
// end of opts, but don't care
break;
case 'h':
show_usage++;
break;
case 'd':
duration = (float)atof(optarg);
break;
case 'f':
if (*optarg == 'c' || *optarg == 'C') {
c_format = 1;
}
break;
default:
show_usage++;
break;
}
}
if (show_usage || duration <= 0.0f) {
fprintf(stderr, "usage: jack_impulse_grab -d duration [-f (C|gnuplot)]\n");
exit(1);
}

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

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

/* 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);

/* display the current sample rate. once the client is activated
(see below), you should rely on your own sample rate
callback (see above) for this value.
*/

fs = jack_get_sample_rate(client);
response_duration = (int)(fs * duration);
response = malloc(response_duration * sizeof(float));
fprintf(stderr, "Grabbing %f seconds (%lu samples) of impulse response\n", duration, response_duration);

/* create two ports */

input_port = jack_port_register (client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
output_port = jack_port_register (client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

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

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

/* connect the ports. Note: you can't do this before
the client is activated (this may change in the future).
*/

if (jack_connect (client, "alsa_pcm:in_1", jack_port_name (input_port))) {
fprintf (stderr, "cannot connect input ports\n");
}
if (jack_connect (client, jack_port_name (output_port), "alsa_pcm:out_1")) {
fprintf (stderr, "cannot connect output ports\n");
}

/* Wait for grab to finish */
while (!grab_finished) {
sleep (1);
}
jack_client_close (client);

peak = response[0];
peak_sample = 0;
if (c_format) {
printf("impulse[%lu] = {", response_duration);
for (i=0; i<response_duration; i++) {
if (i % 4 != 0) {
printf(" ");
} else {
printf("\n\t");
}
printf("\"%+1.10f\"", response[i]);
if (i < response_duration - 1) {
printf(",");
}
if (fabs(response[i]) > peak) {
peak = fabs(response[i]);
peak_sample = i;
}
}
printf("\n};\n");
} else {
for (i=0; i<response_duration; i++) {
printf("%1.12f\n", response[i]);
if (fabs(response[i]) > peak) {
peak = fabs(response[i]);
peak_sample = i;
}
}
}
fprintf(stderr, "Peak value was %f at sample %lu\n", peak, peak_sample);

exit (0);
}

+ 0
- 445
jackd.c View File

@@ -1,445 +0,0 @@
/*
Copyright (C) 2001 Paul Davis
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.

$Id$
*/

#include <stdio.h>
#include <signal.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <errno.h>
#include <wait.h>

#include <jack/engine.h>
#include <jack/internal.h>
#include <jack/driver.h>

static sigset_t signals;
static jack_engine_t *engine = 0;
static int jackd_pid;
static int realtime = 0;
static int realtime_priority = 10;
static int with_fork = 1;
static int verbose = 0;
static int asio_mode = 0;

typedef struct {
pid_t pid;
int argc;
char **argv;
} waiter_arg_t;

#define ILOWER 0
#define IRANGE 3000
int wait_times[IRANGE];
int unders = 0;
int overs = 0;
int max_over = 0;
int min_under = INT_MAX;

#define WRANGE 3000
int work_times[WRANGE];
int work_overs = 0;
int work_max = 0;

void
store_work_time (int howlong)
{
if (howlong < WRANGE) {
work_times[howlong]++;
} else {
work_overs++;
}

if (work_max < howlong) {
work_max = howlong;
}
}

void
show_work_times ()
{
int i;
for (i = 0; i < WRANGE; ++i) {
printf ("%d %d\n", i, work_times[i]);
}
printf ("work overs = %d\nmax = %d\n", work_overs, work_max);
}

void
store_wait_time (int interval)
{
if (interval < ILOWER) {
unders++;
} else if (interval >= ILOWER + IRANGE) {
overs++;
} else {
wait_times[interval-ILOWER]++;
}

if (interval > max_over) {
max_over = interval;
}

if (interval < min_under) {
min_under = interval;
}
}

void
show_wait_times ()
{
int i;

for (i = 0; i < IRANGE; i++) {
printf ("%d %d\n", i+ILOWER, wait_times[i]);
}

printf ("unders: %d\novers: %d\n", unders, overs);
printf ("max: %d\nmin: %d\n", max_over, min_under);
}

static void
signal_handler (int sig)
{
fprintf (stderr, "jackd: signal %d received\n", sig);
kill (jackd_pid, SIGTERM);
}

static void
posix_me_harder (void)

{
/* what's this for?

POSIX says that signals are delivered like this:

* if a thread has blocked that signal, it is not
a candidate to receive the signal.
* of all threads not blocking the signal, pick
one at random, and deliver the signal.

this means that a simple-minded multi-threaded
program can expect to get POSIX signals delivered
randomly to any one of its threads,

here, we block all signals that we think we
might receive and want to catch. all "child"
threads will inherit this setting. if we
create a thread that calls sigwait() on the
same set of signals, implicitly unblocking
all those signals. any of those signals that
are delivered to the process will be delivered
to that thread, and that thread alone. this
makes cleanup for a signal-driven exit much
easier, since we know which thread is doing
it and more importantly, we are free to
call async-unsafe functions, because the
code is executing in normal thread context
after a return from sigwait().
*/

sigemptyset (&signals);
sigaddset(&signals, SIGHUP);
sigaddset(&signals, SIGINT);
sigaddset(&signals, SIGQUIT);
sigaddset(&signals, SIGILL);
sigaddset(&signals, SIGTRAP);
sigaddset(&signals, SIGABRT);
sigaddset(&signals, SIGIOT);
sigaddset(&signals, SIGFPE);
sigaddset(&signals, SIGPIPE);
sigaddset(&signals, SIGTERM);
sigaddset(&signals, SIGUSR1);

/* this can make debugging a pain, but it also makes
segv-exits cleanup_files after themselves rather than
leaving the audio thread active. i still
find it truly wierd that _exit() or whatever is done
by the default SIGSEGV handler does not
cancel all threads in a process, but what
else can we do?
*/

sigaddset(&signals, SIGSEGV);

/* all child threads will inherit this mask */

pthread_sigmask (SIG_BLOCK, &signals, 0);
}

static void *
jack_engine_waiter_thread (void *arg)
{
waiter_arg_t *warg = (waiter_arg_t *) arg;
jack_driver_t *driver;

pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

if ((engine = jack_engine_new (realtime, realtime_priority, verbose)) == 0) {
fprintf (stderr, "cannot create engine\n");
kill (warg->pid, SIGTERM);
return 0;
}

if (warg->argc) {
if ((driver = jack_driver_load (warg->argc, warg->argv)) == 0) {
fprintf (stderr, "cannot load driver module %s\n", warg->argv[0]);
kill (warg->pid, SIGTERM);
return 0;
}

jack_use_driver (engine, driver);
}

if (asio_mode) {
jack_set_asio_mode (engine, TRUE);
}

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

jack_wait (engine);

fprintf (stderr, "telling signal thread that the engine is done\n");
kill (warg->pid, SIGHUP);

return 0; /* nobody cares what this returns */
}

static void
jack_main (int argc, char **argv)
{
int sig;
pthread_t waiter_thread;
waiter_arg_t warg;

pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

posix_me_harder ();
/* what we'd really like to do here is to be able to
wait for either the engine to stop or a POSIX signal,
whichever arrives sooner. but there is no mechanism
to do that, so instead we create a thread to wait
for the engine to finish, and here we stop and wait
for any (reasonably likely) POSIX signal.

if the engine finishes first, the waiter thread will
tell us about it via a signal.

if a signal arrives, we'll stop the engine and then
exit.

in normal operation, our parent process will be waiting
for us and will cleanup.
*/

warg.pid = getpid();
warg.argc = argc;
warg.argv = argv;

if (pthread_create (&waiter_thread, 0, jack_engine_waiter_thread, &warg)) {
fprintf (stderr, "jackd: cannot create engine waiting thread\n");
return;
}

/* Note: normal operation has with_fork == 1 */

if (with_fork) {
/* let the parent handle SIGINT */
sigdelset (&signals, SIGINT);
}

if (verbose) {
fprintf (stderr, "%d waiting for signals\n", getpid());
}

while(1) {
sigwait (&signals, &sig);

printf ("jack main caught signal %d\n", sig);
if (sig == SIGUSR1) {
jack_dump_configuration(engine, 1);
} else {
/* continue to kill engine */
break;
}
}

pthread_cancel (waiter_thread);
jack_engine_delete (engine);

return;
}

static void usage ()

{
fprintf (stderr, "\
usage: jackd [ --asio OR -a ]
[ --realtime OR -R [ --realtime-priority OR -P priority ] ]
[ --verbose OR -v ]
[ --getcap OR -g capability-program-name ]
[ --tmpdir OR -D directory-for-temporary-files ]
-d driver [ ... driver args ... ]
");
}

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

{
const char *options = "ad:D:P:vhRFl:";
struct option long_options[] =
{
{ "asio", 0, 0, 'a' },
{ "driver", 1, 0, 'd' },
{ "tmpdir", 1, 0, 'D' },
{ "getcap", 1, 0, 'g' },
{ "verbose", 0, 0, 'v' },
{ "help", 0, 0, 'h' },
{ "realtime", 0, 0, 'R' },
{ "realtime-priority", 1, 0, 'P' },
{ "spoon", 0, 0, 'F' },
{ 0, 0, 0, 0 }
};
int option_index;
int opt;
int seen_driver = 0;
char *driver_name = 0;
char *getcap_name = 0;
char **driver_args = 0;
int driver_nargs = 1;
int i;

opterr = 0;
while (!seen_driver && (opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) {
switch (opt) {
case 'a':
asio_mode = TRUE;
break;

case 'D':
jack_set_temp_dir (optarg);
break;

case 'd':
seen_driver = 1;
driver_name = optarg;
break;

case 'g':
getcap_name = optarg;
break;

case 'v':
verbose = 1;
break;

case 'F':
with_fork = 0;
break;

case 'P':
realtime_priority = atoi (optarg);
break;

case 'R':
realtime = 1;
break;

default:
fprintf (stderr, "unknown option character %c\n", optopt);
/*fallthru*/
case 'h':
usage();
return -1;
}
}

if (!seen_driver) {
usage ();
exit (1);
}

if (optind < argc) {
driver_nargs = 1 + argc - optind;
} else {
driver_nargs = 1;
}

driver_args = (char **) malloc (sizeof (char *) * driver_nargs);
driver_args[0] = driver_name;
for (i = 1; i < driver_nargs; i++) {
driver_args[i] = argv[optind++];
}

printf ( "jackd " VERSION "\n"
"Copyright 2001-2002 Paul Davis and others.\n"
"jackd comes with ABSOLUTELY NO WARRANTY\n"
"This is free software, and you are welcome to redistribute it\n"
"under certain conditions; see the file COPYING for details\n\n");

/* get real-time capabilities for this process, we should check for errors */
if (getcap_name) system (getcap_name);

if (!with_fork) {

/* This is really here so that we can run gdb easily */

jack_main (driver_nargs, driver_args);

} else {

int pid = fork ();
if (pid < 0) {

fprintf (stderr, "could not fork jack server (%s)", strerror (errno));
exit (1);

} else if (pid == 0) {

jack_main (driver_nargs, driver_args);

} else {
jackd_pid = pid;

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

waitpid (pid, NULL, 0);
}
}

jack_cleanup_shm ();
jack_cleanup_files ();

return 0;
}

+ 0
- 459
memops.c View File

@@ -1,459 +0,0 @@
/*
Copyright (C) 2000 Paul Davis

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.

$Id$
*/

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <memory.h>
#include <stdlib.h>
#include <limits.h>

#include <jack/memops.h>

#define SAMPLE_MAX_24BIT 8388607.0f
#define SAMPLE_MAX_16BIT 32767.0f

/* Round float to int (can't go in memops.h otherwise it gets multiply
defined) */
inline int f_round(float f) {
f += (3<<22);
return *((int*)&f) - 0x4b400000;
}

/* XXX we could use rint(), but for now we'll accept whatever default
floating-point => int conversion the compiler provides.
*/

void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)

{
long long y;

while (nsamples--) {
y = (long long)(*src * SAMPLE_MAX_24BIT) << 8;
if (y > INT_MAX) {
*((int *) dst) = INT_MAX;
} else if (y < INT_MIN) {
*((int *) dst) = INT_MIN;
} else {
*((int *) dst) = (int)y;
}
dst += dst_skip;
src++;
}
}

void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
/* ALERT: signed sign-extension portability !!! */

while (nsamples--) {
*dst = (*((int *) src) >> 8) / SAMPLE_MAX_24BIT;
dst++;
src += src_skip;
}
}

void sample_move_dither_rect_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)

{
/* ALERT: signed sign-extension portability !!! */
jack_default_audio_sample_t x;
long long y;

while (nsamples--) {
x = *src * SAMPLE_MAX_16BIT;
x -= (float)rand() / (float)RAND_MAX;
y = (long long)f_round(x);
y <<= 16;
if (y > INT_MAX) {
*((int *) dst) = INT_MAX;
} else if (y < INT_MIN) {
*((int *) dst) = INT_MIN;
} else {
*((int *) dst) = (int)y;
}
dst += dst_skip;
src++;
}
}

void sample_move_dither_tri_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
jack_default_audio_sample_t x;
float r;
float rm1 = state->rm1;
long long y;

while (nsamples--) {
x = *src * (float)SAMPLE_MAX_16BIT;
r = 2.0f * (float)rand() / (float)RAND_MAX - 1.0f;
x += r - rm1;
rm1 = r;
/* swh: This could be some inline asm on x86 */
y = (long long)f_round(x);
y <<= 16;

if (y > INT_MAX) {
*((int *) dst) = INT_MAX;
} else if (y < INT_MIN) {
*((int *) dst) = INT_MIN;
} else {
*((int *) dst) = (int)y;
}

dst += dst_skip;
src++;
}
state->rm1 = rm1;
}

void sample_move_dither_shaped_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
jack_default_audio_sample_t x;
jack_default_audio_sample_t xe; /* the innput sample - filtered error */
jack_default_audio_sample_t xp; /* x' */
float r;
float rm1 = state->rm1;
unsigned int idx = state->idx;
long long y;

while (nsamples--) {
x = *src * (float)SAMPLE_MAX_16BIT;
r = 2.0f * (float)rand() / (float)RAND_MAX - 1.0f;
/* Filter the error with Lipshitz's minimally audible FIR:
[2.033 -2.165 1.959 -1.590 0.6149] */
xe = x
- state->e[idx] * 2.033f
+ state->e[(idx - 1) & DITHER_BUF_MASK] * 2.165f
- state->e[(idx - 2) & DITHER_BUF_MASK] * 1.959f
+ state->e[(idx - 3) & DITHER_BUF_MASK] * 1.590f
- state->e[(idx - 4) & DITHER_BUF_MASK] * 0.6149f;
xp = xe + r - rm1;
rm1 = r;

/* This could be some inline asm on x86 */
y = (long long)f_round(xp);

/* Intrinsic z^-1 delay */
idx = (idx + 1) & DITHER_BUF_MASK;
state->e[idx] = y - xe;

y <<= 16;

if (y > INT_MAX) {
*((int *) dst) = INT_MAX;
} else if (y < INT_MIN) {
*((int *) dst) = INT_MIN;
} else {
*((int *) dst) = (int)y;
}
dst += dst_skip;
src++;
}
state->rm1 = rm1;
state->idx = idx;
}

void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
jack_default_audio_sample_t val;

/* ALERT: signed sign-extension portability !!! */

/* XXX good to use x86 assembler here, since float->short
sucks that h/w.
*/
while (nsamples--) {
val = *src;
if (val > 1.0f) {
*((short *)dst) = SHRT_MAX;
} else if (val < -1.0f) {
*((short *)dst) = SHRT_MIN;
} else {
*((short *) dst) = (short) (val * SAMPLE_MAX_16BIT);
}
dst += dst_skip;
src++;
}
}

void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
jack_default_audio_sample_t val;
int tmp;

while (nsamples--) {
val = *src * (float)SAMPLE_MAX_16BIT;
val -= (float)rand() / (float)RAND_MAX;
/* swh: This could be some inline asm on x86 */
tmp = f_round(val);
if (tmp > SHRT_MAX) {
*((short *)dst) = SHRT_MAX;
} else if (tmp < SHRT_MIN) {
*((short *)dst) = SHRT_MIN;
} else {
*((short *) dst) = (short)tmp;
}
dst += dst_skip;
src++;
}
}

void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
jack_default_audio_sample_t x;
float r;
float rm1 = state->rm1;
int y;

while (nsamples--) {
x = *src * (float)SAMPLE_MAX_16BIT;
r = 2.0f * (float)rand() / (float)RAND_MAX - 1.0f;
x += r - rm1;
rm1 = r;
/* swh: This could be some inline asm on x86 */
y = f_round(x);

if (y > SHRT_MAX) {
*((short *)dst) = SHRT_MAX;
} else if (y < SHRT_MIN) {
*((short *)dst) = SHRT_MIN;
} else {
*((short *) dst) = (short)y;
}

dst += dst_skip;
src++;
}
state->rm1 = rm1;
}

void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
jack_default_audio_sample_t x;
jack_default_audio_sample_t xe; /* the innput sample - filtered error */
jack_default_audio_sample_t xp; /* x' */
float r;
float rm1 = state->rm1;
unsigned int idx = state->idx;
int y;

while (nsamples--) {
x = *src * (float)SAMPLE_MAX_16BIT;
r = 2.0f * (float)rand() / (float)RAND_MAX - 1.0f;
/* Filter the error with Lipshitz's minimally audible FIR:
[2.033 -2.165 1.959 -1.590 0.6149] */
xe = x
- state->e[idx] * 2.033f
+ state->e[(idx - 1) & DITHER_BUF_MASK] * 2.165f
- state->e[(idx - 2) & DITHER_BUF_MASK] * 1.959f
+ state->e[(idx - 3) & DITHER_BUF_MASK] * 1.590f
- state->e[(idx - 4) & DITHER_BUF_MASK] * 0.6149f;
xp = xe + r - rm1;
rm1 = r;

/* This could be some inline asm on x86 */
y = f_round(xp);

/* Intrinsic z^-1 delay */
idx = (idx + 1) & DITHER_BUF_MASK;
state->e[idx] = y - xe;

if (y > SHRT_MAX) {
*((short *)dst) = SHRT_MAX;
} else if (y < SHRT_MIN) {
*((short *)dst) = SHRT_MIN;
} else {
*((short *) dst) = (short)y;
}
dst += dst_skip;
src++;
}
state->rm1 = rm1;
state->idx = idx;
}

void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
/* ALERT: signed sign-extension portability !!! */
while (nsamples--) {
*dst = (*((short *) src)) / SAMPLE_MAX_16BIT;
dst++;
src += src_skip;
}
}

void sample_merge_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
short val;

/* ALERT: signed sign-extension portability !!! */
while (nsamples--) {
val = (short) (*src * SAMPLE_MAX_16BIT);
if (val > SHRT_MAX - *((short *) dst)) {
*((short *)dst) = SHRT_MAX;
} else if (val < SHRT_MIN - *((short *) dst)) {
*((short *)dst) = SHRT_MIN;
} else {
*((short *) dst) += val;
}
dst += dst_skip;
src++;
}
}

void sample_merge_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)

{
/* ALERT: signed sign-extension portability !!! */

while (nsamples--) {
*((int *) dst) += (((int) (*src * SAMPLE_MAX_24BIT)) << 8);
dst += dst_skip;
src++;
}
}

void memset_interleave (char *dst, char val, unsigned long bytes,
unsigned long unit_bytes,
unsigned long skip_bytes)
{
switch (unit_bytes) {
case 1:
while (bytes--) {
*dst = val;
dst += skip_bytes;
}
break;
case 2:
while (bytes) {
*((short *) dst) = (short) val;
dst += skip_bytes;
bytes -= 2;
}
break;
case 4:
while (bytes) {
*((int *) dst) = (int) val;
dst += skip_bytes;
bytes -= 4;
}
break;
}
}

/* COPY FUNCTIONS: used to move data from an input channel to an
output channel. Note that we assume that the skip distance
is the same for both channels. This is completely fine
unless the input and output were on different audio interfaces that
were interleaved differently. We don't try to handle that.
*/

void
memcpy_fake (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar)
{
memcpy (dst, src, src_bytes);
}

void
merge_memcpy_d16_s16 (char *dst, char *src, unsigned long src_bytes,
unsigned long dst_skip_bytes, unsigned long src_skip_bytes)
{
while (src_bytes) {
*((short *) dst) += *((short *) src);
dst += 2;
src += 2;
src_bytes -= 2;
}
}

void
merge_memcpy_d32_s32 (char *dst, char *src, unsigned long src_bytes,
unsigned long dst_skip_bytes, unsigned long src_skip_bytes)

{
while (src_bytes) {
*((int *) dst) += *((int *) src);
dst += 4;
src += 4;
src_bytes -= 4;
}
}

void
merge_memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes,
unsigned long dst_skip_bytes, unsigned long src_skip_bytes)

{
while (src_bytes) {
*((short *) dst) += *((short *) src);
dst += dst_skip_bytes;
src += src_skip_bytes;
src_bytes -= 2;
}
}

void
merge_memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes,
unsigned long dst_skip_bytes, unsigned long src_skip_bytes)
{
while (src_bytes) {
*((int *) dst) += *((int *) src);
dst += dst_skip_bytes;
src += src_skip_bytes;
src_bytes -= 4;
}
}

void
memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes,
unsigned long dst_skip_bytes, unsigned long src_skip_bytes)
{
while (src_bytes) {
*((short *) dst) = *((short *) src);
dst += dst_skip_bytes;
src += src_skip_bytes;
src_bytes -= 2;
}
}

void
memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes,
unsigned long dst_skip_bytes, unsigned long src_skip_bytes)

{
while (src_bytes) {
*((int *) dst) = *((int *) src);
dst += dst_skip_bytes;
src += src_skip_bytes;
src_bytes -= 4;
}
}

+ 0
- 30
monitor_client.c View File

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

#include <jack/jack.h>

#define TRUE 1
#define FALSE 0

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

{
jack_client_t *client;

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

if (jack_port_request_monitor_by_name (client, "alsa_pcm:in_1", TRUE)) {
fprintf (stderr, "could not enable monitoring for in_1\n");
}
sleep (30);
if (jack_port_request_monitor_by_name (client, "alsa_pcm:in_1", FALSE)) {
fprintf (stderr, "could not disable monitoring for in_1\n");
}
jack_client_close (client);
exit (0);
}


+ 0
- 37
pool.c View File

@@ -1,37 +0,0 @@
/*
Copyright (C) 2001 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
$Id$
*/

#include <stdlib.h>
#include <jack/pool.h>

void *
jack_pool_alloc (size_t bytes)

{
/* XXX need RT-pool based allocator here */

return malloc (bytes);
}

void
jack_pool_release (void *ptr)
{
free (ptr);
}

+ 0
- 128
simple_client.c View File

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

#include <jack/jack.h>

jack_port_t *input_port;
jack_port_t *output_port;

int
process (jack_nframes_t nframes, void *arg)

{
jack_default_audio_sample_t *out = (jack_default_audio_sample_t *) jack_port_get_buffer (output_port, nframes);
jack_default_audio_sample_t *in = (jack_default_audio_sample_t *) jack_port_get_buffer (input_port, nframes);

memcpy (out, in, sizeof (jack_default_audio_sample_t) * nframes);

return 0;
}

int
bufsize (jack_nframes_t nframes, void *arg)

{
printf ("the maximum buffer size is now %lu\n", nframes);
return 0;
}

int
srate (jack_nframes_t nframes, void *arg)

{
printf ("the sample rate is now %lu/sec\n", nframes);
return 0;
}

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

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

{
jack_client_t *client;

if (argc < 2) {
fprintf (stderr, "usage: jack_simple_client <name>\n");
return 1;
}

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

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

/* 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 `bufsize()' whenever
the maximum number of frames that will be passed
to `process()' changes
*/

jack_set_buffer_size_callback (client, bufsize, 0);

/* tell the JACK server to call `srate()' whenever
the sample rate of the system changes.
*/


jack_set_sample_rate_callback (client, srate, 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);

/* display the current sample rate. once the client is activated
(see below), you should rely on your own sample rate
callback (see above) for this value.
*/

printf ("engine sample rate: %lu\n", jack_get_sample_rate (client));

/* create two ports */

input_port = jack_port_register (client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
output_port = jack_port_register (client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

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

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

/* connect the ports. Note: you can't do this before
the client is activated, because we can't allow
connections to be made to clients that aren't
running.
*/

if (jack_connect (client, "alsa_pcm:in_1", jack_port_name (input_port))) {
fprintf (stderr, "cannot connect input ports\n");
}
if (jack_connect (client, jack_port_name (output_port), "alsa_pcm:out_1")) {
fprintf (stderr, "cannot connect output ports\n");
}

/* Since this is just a toy, run for a few seconds, then finish */

sleep (10);
jack_client_close (client);
exit (0);
}


Loading…
Cancel
Save