git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2349 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.90
@@ -46,6 +46,11 @@ example_programs = { | |||
'jack_zombie' : 'zombie.c', | |||
'jack_load' : 'ipload.c', | |||
'jack_unload' : 'ipunload.c', | |||
'jack_showtime' : 'showtime.c', | |||
'jack_alias' : 'alias.c', | |||
'jack_bufsize' : 'bufsize.c', | |||
'jack_evmon' : 'evmon.c', | |||
'jack_monitor_client' : 'monitor_client.c', | |||
} | |||
example_libs = { | |||
@@ -0,0 +1,118 @@ | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <unistd.h> | |||
#include <string.h> | |||
#include <getopt.h> | |||
//#include <config.h> | |||
#include <jack/jack.h> | |||
char * my_name; | |||
void | |||
show_version (void) | |||
{ | |||
//fprintf (stderr, "%s: JACK Audio Connection Kit version " VERSION "\n", my_name); | |||
} | |||
void | |||
show_usage (void) | |||
{ | |||
show_version (); | |||
fprintf (stderr, "\nUsage: %s [options] portname alias\n", my_name); | |||
fprintf (stderr, "List active Jack ports, and optionally display extra information.\n\n"); | |||
fprintf (stderr, "Display options:\n"); | |||
fprintf (stderr, " -u, --unalias remove `alias' as an alias for `port'\n"); | |||
fprintf (stderr, " -h, --help Display this help message\n"); | |||
fprintf (stderr, " --version Output version information and exit\n\n"); | |||
fprintf (stderr, "For more information see http://jackaudio.org/\n"); | |||
} | |||
int | |||
main (int argc, char *argv[]) | |||
{ | |||
jack_client_t *client; | |||
jack_status_t status; | |||
char* portname; | |||
char* alias; | |||
int unset = 0; | |||
int ret; | |||
int c; | |||
int option_index; | |||
extern int optind; | |||
jack_port_t* port; | |||
struct option long_options[] = { | |||
{ "unalias", 0, 0, 'u' }, | |||
{ "help", 0, 0, 'h' }, | |||
{ "version", 0, 0, 'v' }, | |||
{ 0, 0, 0, 0 } | |||
}; | |||
if (argc < 3) { | |||
show_usage (); | |||
return 1; | |||
} | |||
my_name = strrchr(argv[0], '/'); | |||
if (my_name == 0) { | |||
my_name = argv[0]; | |||
} else { | |||
my_name ++; | |||
} | |||
while ((c = getopt_long (argc, argv, "uhv", long_options, &option_index)) >= 0) { | |||
switch (c) { | |||
case 'u': | |||
unset = 1; | |||
break; | |||
case 'h': | |||
show_usage (); | |||
return 1; | |||
break; | |||
case 'v': | |||
show_version (); | |||
return 1; | |||
break; | |||
default: | |||
show_usage (); | |||
return 1; | |||
break; | |||
} | |||
} | |||
portname = argv[optind++]; | |||
alias = argv[optind]; | |||
/* Open a client connection to the JACK server. Starting a | |||
* new server only to list its ports seems pointless, so we | |||
* specify JackNoStartServer. */ | |||
//JOQ: need a new server name option | |||
client = jack_client_open ("lsp", JackNoStartServer, &status); | |||
if (client == NULL) { | |||
if (status & JackServerFailed) { | |||
fprintf (stderr, "JACK server not running\n"); | |||
} else { | |||
fprintf (stderr, "jack_client_open() failed, " | |||
"status = 0x%2.0x\n", status); | |||
} | |||
return 1; | |||
} | |||
if ((port = jack_port_by_name (client, portname)) == 0) { | |||
fprintf (stderr, "No port named \"%s\"\n", portname); | |||
return 1; | |||
} | |||
if (!unset) { | |||
ret = jack_port_set_alias (port, alias); | |||
} else { | |||
ret = jack_port_unset_alias (port, alias); | |||
} | |||
jack_client_close (client); | |||
return ret; | |||
} |
@@ -0,0 +1,96 @@ | |||
/* | |||
* bufsize.c -- change JACK buffer size. | |||
* | |||
* Copyright (C) 2003 Jack O'Quin. | |||
* | |||
* 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 <stdio.h> | |||
#include <errno.h> | |||
#include <unistd.h> | |||
#include <signal.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <jack/jack.h> | |||
#include <jack/transport.h> | |||
char *package; /* program name */ | |||
jack_client_t *client; | |||
jack_nframes_t nframes; | |||
void jack_shutdown(void *arg) | |||
{ | |||
fprintf(stderr, "JACK shut down, exiting ...\n"); | |||
exit(1); | |||
} | |||
void signal_handler(int sig) | |||
{ | |||
jack_client_close(client); | |||
fprintf(stderr, "signal received, exiting ...\n"); | |||
exit(0); | |||
} | |||
void parse_arguments(int argc, char *argv[]) | |||
{ | |||
/* basename $0 */ | |||
package = strrchr(argv[0], '/'); | |||
if (package == 0) | |||
package = argv[0]; | |||
else | |||
package++; | |||
if (argc < 2) { | |||
fprintf(stderr, "usage: %s <bufsize>\n", package); | |||
exit(9); | |||
} | |||
nframes = strtoul(argv[1], NULL, 0); | |||
if (errno == ERANGE) { | |||
fprintf(stderr, "%s: invalid buffer size: %s\n", | |||
package, argv[1]); | |||
exit(2); | |||
} | |||
} | |||
int main(int argc, char *argv[]) | |||
{ | |||
int rc; | |||
parse_arguments(argc, argv); | |||
/* become a JACK client */ | |||
if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) { | |||
fprintf(stderr, "JACK server not running?\n"); | |||
exit(1); | |||
} | |||
signal(SIGQUIT, signal_handler); | |||
signal(SIGTERM, signal_handler); | |||
signal(SIGHUP, signal_handler); | |||
signal(SIGINT, signal_handler); | |||
jack_on_shutdown(client, jack_shutdown, 0); | |||
rc = jack_set_buffer_size(client, nframes); | |||
if (rc) | |||
fprintf(stderr, "jack_set_buffer_size(): %s\n", strerror(rc)); | |||
jack_client_close(client); | |||
return rc; | |||
} |
@@ -0,0 +1,351 @@ | |||
/* | |||
Copyright (C) 2001 Paul Davis | |||
Copyright (C) 2003 Jack O'Quin | |||
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. | |||
* 2002/08/23 - modify for libsndfile 1.0.0 <andy@alsaplayer.org> | |||
* 2003/05/26 - use ringbuffers - joq | |||
*/ | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <errno.h> | |||
#include <unistd.h> | |||
#include <sndfile.h> | |||
#include <pthread.h> | |||
#include <signal.h> | |||
#include <getopt.h> | |||
#include <jack/jack.h> | |||
#include <jack/ringbuffer.h> | |||
typedef struct _thread_info { | |||
pthread_t thread_id; | |||
SNDFILE *sf; | |||
jack_nframes_t duration; | |||
jack_nframes_t rb_size; | |||
jack_client_t *client; | |||
unsigned int channels; | |||
int bitdepth; | |||
char *path; | |||
volatile int can_capture; | |||
volatile int can_process; | |||
volatile int status; | |||
} jack_thread_info_t; | |||
/* JACK data */ | |||
unsigned int nports; | |||
jack_port_t **ports; | |||
jack_default_audio_sample_t **in; | |||
jack_nframes_t nframes; | |||
const size_t sample_size = sizeof(jack_default_audio_sample_t); | |||
/* Synchronization between process thread and disk thread. */ | |||
#define DEFAULT_RB_SIZE 16384 /* ringbuffer size in frames */ | |||
jack_ringbuffer_t *rb; | |||
pthread_mutex_t disk_thread_lock = PTHREAD_MUTEX_INITIALIZER; | |||
pthread_cond_t data_ready = PTHREAD_COND_INITIALIZER; | |||
long overruns = 0; | |||
jack_client_t *client; | |||
static void signal_handler(int sig) | |||
{ | |||
jack_client_close(client); | |||
fprintf(stderr, "signal received, exiting ...\n"); | |||
exit(0); | |||
} | |||
static void * | |||
disk_thread (void *arg) | |||
{ | |||
jack_thread_info_t *info = (jack_thread_info_t *) arg; | |||
static jack_nframes_t total_captured = 0; | |||
jack_nframes_t samples_per_frame = info->channels; | |||
size_t bytes_per_frame = samples_per_frame * sample_size; | |||
void *framebuf = malloc (bytes_per_frame); | |||
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); | |||
pthread_mutex_lock (&disk_thread_lock); | |||
info->status = 0; | |||
while (1) { | |||
/* Write the data one frame at a time. This is | |||
* inefficient, but makes things simpler. */ | |||
while (info->can_capture && | |||
(jack_ringbuffer_read_space (rb) >= bytes_per_frame)) { | |||
jack_ringbuffer_read (rb, framebuf, bytes_per_frame); | |||
if (sf_writef_float (info->sf, framebuf, 1) != 1) { | |||
char errstr[256]; | |||
sf_error_str (0, errstr, sizeof (errstr) - 1); | |||
fprintf (stderr, | |||
"cannot write sndfile (%s)\n", | |||
errstr); | |||
info->status = EIO; /* write failed */ | |||
goto done; | |||
} | |||
if (++total_captured >= info->duration) { | |||
printf ("disk thread finished\n"); | |||
goto done; | |||
} | |||
} | |||
/* wait until process() signals more data */ | |||
pthread_cond_wait (&data_ready, &disk_thread_lock); | |||
} | |||
done: | |||
pthread_mutex_unlock (&disk_thread_lock); | |||
free (framebuf); | |||
return 0; | |||
} | |||
static int | |||
process (jack_nframes_t nframes, void *arg) | |||
{ | |||
int chn; | |||
size_t i; | |||
jack_thread_info_t *info = (jack_thread_info_t *) arg; | |||
/* Do nothing until we're ready to begin. */ | |||
if ((!info->can_process) || (!info->can_capture)) | |||
return 0; | |||
for (chn = 0; chn < nports; chn++) | |||
in[chn] = jack_port_get_buffer (ports[chn], nframes); | |||
/* Sndfile requires interleaved data. It is simpler here to | |||
* just queue interleaved samples to a single ringbuffer. */ | |||
for (i = 0; i < nframes; i++) { | |||
for (chn = 0; chn < nports; chn++) { | |||
if (jack_ringbuffer_write (rb, (void *) (in[chn]+i), | |||
sample_size) | |||
< sample_size) | |||
overruns++; | |||
} | |||
} | |||
/* Tell the disk thread there is work to do. If it is already | |||
* running, the lock will not be available. We can't wait | |||
* here in the process() thread, but we don't need to signal | |||
* in that case, because the disk thread will read all the | |||
* data queued before waiting again. */ | |||
if (pthread_mutex_trylock (&disk_thread_lock) == 0) { | |||
pthread_cond_signal (&data_ready); | |||
pthread_mutex_unlock (&disk_thread_lock); | |||
} | |||
return 0; | |||
} | |||
static void | |||
jack_shutdown (void *arg) | |||
{ | |||
fprintf (stderr, "JACK shutdown\n"); | |||
// exit (0); | |||
abort(); | |||
} | |||
static void | |||
setup_disk_thread (jack_thread_info_t *info) | |||
{ | |||
SF_INFO sf_info; | |||
int short_mask; | |||
sf_info.samplerate = jack_get_sample_rate (info->client); | |||
sf_info.channels = info->channels; | |||
switch (info->bitdepth) { | |||
case 8: short_mask = SF_FORMAT_PCM_U8; | |||
break; | |||
case 16: short_mask = SF_FORMAT_PCM_16; | |||
break; | |||
case 24: short_mask = SF_FORMAT_PCM_24; | |||
break; | |||
case 32: short_mask = SF_FORMAT_PCM_32; | |||
break; | |||
default: short_mask = SF_FORMAT_PCM_16; | |||
break; | |||
} | |||
sf_info.format = SF_FORMAT_WAV|short_mask; | |||
if ((info->sf = sf_open (info->path, SFM_WRITE, &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); | |||
} | |||
static void | |||
run_disk_thread (jack_thread_info_t *info) | |||
{ | |||
info->can_capture = 1; | |||
pthread_join (info->thread_id, NULL); | |||
sf_close (info->sf); | |||
if (overruns > 0) { | |||
fprintf (stderr, | |||
"jackrec failed with %ld overruns.\n", overruns); | |||
fprintf (stderr, " try a bigger buffer than -B %" | |||
PRIu32 ".\n", info->rb_size); | |||
info->status = EPIPE; | |||
} | |||
} | |||
static void | |||
setup_ports (int sources, char *source_names[], jack_thread_info_t *info) | |||
{ | |||
unsigned int i; | |||
size_t in_size; | |||
/* Allocate data structures that depend on the number of ports. */ | |||
nports = sources; | |||
ports = (jack_port_t **) malloc (sizeof (jack_port_t *) * nports); | |||
in_size = nports * sizeof (jack_default_audio_sample_t *); | |||
in = (jack_default_audio_sample_t **) malloc (in_size); | |||
rb = jack_ringbuffer_create (nports * sample_size * info->rb_size); | |||
/* When JACK is running realtime, jack_activate() will have | |||
* called mlockall() to lock our pages into memory. But, we | |||
* still need to touch any newly allocated pages before | |||
* process() starts using them. Otherwise, a page fault could | |||
* create a delay that would force JACK to shut us down. */ | |||
memset(in, 0, in_size); | |||
memset(rb->buf, 0, rb->size); | |||
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; /* process() can start, now */ | |||
} | |||
int | |||
main (int argc, char *argv[]) | |||
{ | |||
jack_thread_info_t thread_info; | |||
int c; | |||
int longopt_index = 0; | |||
extern int optind, opterr; | |||
int show_usage = 0; | |||
char *optstring = "d:f:b:B:h"; | |||
struct option long_options[] = { | |||
{ "help", 0, 0, 'h' }, | |||
{ "duration", 1, 0, 'd' }, | |||
{ "file", 1, 0, 'f' }, | |||
{ "bitdepth", 1, 0, 'b' }, | |||
{ "bufsize", 1, 0, 'B' }, | |||
{ 0, 0, 0, 0 } | |||
}; | |||
memset (&thread_info, 0, sizeof (thread_info)); | |||
thread_info.rb_size = DEFAULT_RB_SIZE; | |||
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; | |||
case 'B': | |||
thread_info.rb_size = 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 ] [ -B bufsize ] port1 [ port2 ... ]\n"); | |||
exit (1); | |||
} | |||
if ((client = jack_client_open ("jackrec", JackNullOption, NULL)) == 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, &thread_info); | |||
if (jack_activate (client)) { | |||
fprintf (stderr, "cannot activate client"); | |||
} | |||
setup_ports (argc - optind, &argv[optind], &thread_info); | |||
/* install a signal handler to properly quits jack client */ | |||
signal(SIGQUIT, signal_handler); | |||
signal(SIGTERM, signal_handler); | |||
signal(SIGHUP, signal_handler); | |||
signal(SIGINT, signal_handler); | |||
run_disk_thread (&thread_info); | |||
jack_client_close (client); | |||
jack_ringbuffer_free (rb); | |||
exit (0); | |||
} |
@@ -0,0 +1,114 @@ | |||
/* | |||
Copyright (C) 2007 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. | |||
*/ | |||
#include <stdio.h> | |||
#include <errno.h> | |||
#ifndef WIN32 | |||
#include <unistd.h> | |||
#endif | |||
#include <string.h> | |||
#include <signal.h> | |||
#include <stdlib.h> | |||
#include <jack/jack.h> | |||
jack_client_t *client; | |||
static void signal_handler(int sig) | |||
{ | |||
jack_client_close(client); | |||
fprintf(stderr, "signal received, exiting ...\n"); | |||
exit(0); | |||
} | |||
static void | |||
port_callback (jack_port_id_t port, int yn, void* arg) | |||
{ | |||
printf ("Port %d %s\n", port, (yn ? "registered" : "unregistered")); | |||
} | |||
static void | |||
connect_callback (jack_port_id_t a, jack_port_id_t b, int yn, void* arg) | |||
{ | |||
printf ("Ports %d and %d %s\n", a, b, (yn ? "connected" : "disconnected")); | |||
} | |||
static void | |||
client_callback (const char* client, int yn, void* arg) | |||
{ | |||
printf ("Client %s %s\n", client, (yn ? "registered" : "unregistered")); | |||
} | |||
static int | |||
graph_callback (void* arg) | |||
{ | |||
printf ("Graph reordered\n"); | |||
return 0; | |||
} | |||
int | |||
main (int argc, char *argv[]) | |||
{ | |||
jack_options_t options = JackNullOption; | |||
jack_status_t status; | |||
if ((client = jack_client_open ("event-monitor", options, &status, NULL)) == 0) { | |||
fprintf (stderr, "jack_client_open() failed, " | |||
"status = 0x%2.0x\n", status); | |||
if (status & JackServerFailed) { | |||
fprintf (stderr, "Unable to connect to JACK server\n"); | |||
} | |||
return 1; | |||
} | |||
if (jack_set_port_registration_callback (client, port_callback, NULL)) { | |||
fprintf (stderr, "cannot set port registration callback\n"); | |||
return 1; | |||
} | |||
if (jack_set_port_connect_callback (client, connect_callback, NULL)) { | |||
fprintf (stderr, "cannot set port connect callback\n"); | |||
return 1; | |||
} | |||
if (jack_set_client_registration_callback (client, client_callback, NULL)) { | |||
fprintf (stderr, "cannot set client registration callback\n"); | |||
return 1; | |||
} | |||
if (jack_set_graph_order_callback (client, graph_callback, NULL)) { | |||
fprintf (stderr, "cannot set graph order registration callback\n"); | |||
return 1; | |||
} | |||
if (jack_activate (client)) { | |||
fprintf (stderr, "cannot activate client"); | |||
return 1; | |||
} | |||
#ifdef WIN32 | |||
signal(SIGINT, signal_handler); | |||
signal(SIGABRT, signal_handler); | |||
signal(SIGTERM, signal_handler); | |||
#else | |||
signal(SIGQUIT, signal_handler); | |||
signal(SIGTERM, signal_handler); | |||
signal(SIGHUP, signal_handler); | |||
signal(SIGINT, signal_handler); | |||
#endif | |||
sleep (-1); | |||
exit (0); | |||
} | |||
@@ -0,0 +1,246 @@ | |||
/* | |||
* 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. | |||
* | |||
*/ | |||
#include <stdio.h> | |||
#include <errno.h> | |||
#include <unistd.h> | |||
#include <stdlib.h> | |||
#include <signal.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; | |||
jack_client_t *client; | |||
static void signal_handler(int sig) | |||
{ | |||
jack_client_close(client); | |||
fprintf(stderr, "signal received, exiting ...\n"); | |||
exit(0); | |||
} | |||
static 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; | |||
} | |||
static void | |||
jack_shutdown (void *arg) | |||
{ | |||
exit (1); | |||
} | |||
int | |||
main (int argc, char *argv[]) | |||
{ | |||
const char **ports; | |||
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_open("impulse_grabber", JackNullOption, NULL)) == 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 = (unsigned long) (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 ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == NULL) { | |||
fprintf(stderr, "Cannot find any physical capture ports"); | |||
exit(1); | |||
} | |||
if (jack_connect (client, ports[0], jack_port_name (input_port))) { | |||
fprintf (stderr, "cannot connect input ports\n"); | |||
} | |||
free (ports); | |||
if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) { | |||
fprintf(stderr, "Cannot find any physical playback ports"); | |||
exit(1); | |||
} | |||
if (jack_connect (client, jack_port_name (output_port), ports[0])) { | |||
fprintf (stderr, "cannot connect output ports\n"); | |||
} | |||
free (ports); | |||
/* install a signal handler to properly quits jack client */ | |||
signal(SIGQUIT, signal_handler); | |||
signal(SIGTERM, signal_handler); | |||
signal(SIGHUP, signal_handler); | |||
signal(SIGINT, signal_handler); | |||
/* 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,0 +1,46 @@ | |||
#include <stdio.h> | |||
#include <unistd.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <jack/jack.h> | |||
#define TRUE 1 | |||
#define FALSE 0 | |||
int | |||
main (int argc, char *argv[]) | |||
{ | |||
jack_client_t *client; | |||
char *my_name = strrchr(argv[0], '/'); | |||
if (my_name == 0) { | |||
my_name = argv[0]; | |||
} else { | |||
my_name ++; | |||
} | |||
if (argc != 2) { | |||
fprintf (stderr, "Usage: %s client\n", my_name); | |||
return 1; | |||
} | |||
if ((client = jack_client_open ("input monitoring", JackNullOption, NULL)) == 0) { | |||
fprintf (stderr, "jack server not running?\n"); | |||
return 1; | |||
} | |||
if (jack_port_request_monitor_by_name (client, argv[1], TRUE)) { | |||
fprintf (stderr, "could not enable monitoring for %s\n", argv[1]); | |||
jack_client_close (client); | |||
return 1; | |||
} | |||
sleep (30); | |||
if (jack_port_request_monitor_by_name (client, argv[1], FALSE)) { | |||
fprintf (stderr, "could not disable monitoring for %s\n", argv[1]); | |||
} | |||
jack_client_close (client); | |||
exit (0); | |||
} | |||
@@ -9,7 +9,7 @@ | |||
jack_client_t *client; | |||
void | |||
static void | |||
showtime () | |||
{ | |||
jack_position_t current; | |||
@@ -19,9 +19,7 @@ showtime () | |||
transport_state = jack_transport_query (client, ¤t); | |||
frame_time = jack_frame_time (client); | |||
//printf ("frame: %7" PRIu32 " @ %" PRIu32 "\t", current.frame, frame_time); | |||
printf ("frame = %ld frame_time = %ld usecs = %lld \t", current.frame, frame_time, current.usecs); | |||
printf ("frame = %u frame_time = %u usecs = %lld \t", current.frame, frame_time, current.usecs); | |||
switch (transport_state) { | |||
case JackTransportStopped: | |||
@@ -47,7 +45,7 @@ showtime () | |||
printf ("\n"); | |||
} | |||
void | |||
static void | |||
jack_shutdown (void *arg) | |||
{ | |||
exit (1); | |||
@@ -66,7 +64,7 @@ main (int argc, char *argv[]) | |||
{ | |||
/* try to become a client of the JACK server */ | |||
if ((client = jack_client_new ("showtime")) == 0) { | |||
if ((client = jack_client_open ("showtime", JackNullOption, NULL)) == 0) { | |||
fprintf (stderr, "jack server not running?\n"); | |||
return 1; | |||
} | |||