Re: [linux-audio-dev] timemachine auto recorder patch

From: Hans Fugal <hans@email-addr-hidden>
Date: Sun Jan 15 2006 - 02:50:22 EET

FWIW I've never had issues running timemachine in the background.

On Sat, 14 Jan 2006 at 12:41 -0700, Garett Shulman wrote:
> Hello, I have created a patch that allows timeachine to automatically
> start and stop recording based on the audio signal. Recording will start
> when a sample value exceeds a start threashold. Recording stops when
> sample values remain below a stop threashold for a period of time.
> Recording of a new file will then start again when a sample value again
> exceeds the start threashold. These values as well as enabeling auto
> recording can all be set at the command line.
>
> With this functionallity I would like to be able to launch timemachine
> backgrounded.
> Eg: timemachine args &
> I would also need to be able to send the process SIGINT and SIGTERM
> signals and have it exit gracefully. I have attempted to add the
> necessary handlers for this.
>
> However if I try to start timemachine backgrounded it just seems to exit
> and brings jack down with it. If I run it in the foreground and try to
> killall timemachine it does not exit gracefully but brings jack down as
> well. In either case I see output from jack like:
>
> subgraph starting at time timed out (subgraph_wait_fd = 7, status = 0,
> state = Triggered)
> jackd watchdog: timeout - killed jack
> [1]+ Killed timemachine
>
> Any suggestions or ideas are greatly appreciated. Also, the auto
> recorder functionallity works great asside from the backgrounding and
> SIGTERM business.
>
> Thanks!
> -Garett
>
> PATCH FOLLOWS
> diff -urN timemachine-0.3.1/src/main.c
> timemachine-0.3.1.autorecord/src/main.c
> --- timemachine-0.3.1/src/main.c 2005-09-19 03:41:30.000000000 -0600
> +++ timemachine-0.3.1.autorecord/src/main.c 2006-01-14
> 11:24:13.000000000 -0700
> @@ -28,6 +28,10 @@
> #include <sndfile.h>
> #include <gtk/gtk.h>
>
> +/* garetts mod here */
> +#include <signal.h>
> +/* end garetts mod */
> +
> #ifdef HAVE_LASH
> #include <lash/lash.h>
>
> @@ -71,6 +75,10 @@
> GdkPixbuf *img_on, *img_off, *img_busy;
> GdkPixbuf *icon_on, *icon_off;
>
> +/* garetts mod here */
> +void signal_handler(int signal);
> +/* end garetts mod */
> +
> int main(int argc, char *argv[])
> {
> unsigned int i;
> @@ -78,13 +86,22 @@
> int help = 0;
> int console = 0;
> char port_name[32];
> + /* garetts mod here */
> + int AUTO_RECORD = 0;
> + signal(SIGINT, signal_handler);
> + signal(SIGTERM, signal_handler);
> + float SECONDS_OF_SILENCE_BEFORE_STOP = 5;
> + float START_THREASHOLD = 0.000005;
> + float STOP_THREASHOLD = 0;
> + /* end garetts mod */
> +
> pthread_t dt;
> #ifdef HAVE_LASH
> lash_args_t *lash_args = lash_extract_args(&argc, &argv);
> lash_event_t *event;
> #endif
>
> - while ((opt = getopt(argc, argv, "hic:t:n:p:f:")) != -1) {
> + while ((opt = getopt(argc, argv, "hic:t:n:p:f:q:w:e:r")) != -1) {
> switch (opt) {
> case 'h':
> help = 1;
> @@ -111,6 +128,20 @@
> case 'f':
> format_name = optarg;
> break;
> + /* garetts mod here */
> + case 'q':
> + SECONDS_OF_SILENCE_BEFORE_STOP = atof(optarg);
> + break;
> + case 'w':
> + START_THREASHOLD = atof(optarg);
> + break;
> + case 'e':
> + STOP_THREASHOLD = atof(optarg);
> + break;
> + case 'r':
> + AUTO_RECORD = 1;
> + break;
> + /* end garetts mod */
> default:
> num_ports = 0;
> break;
> @@ -132,6 +163,9 @@
> fprintf(stderr, "\t-t\tspecify the pre-recording buffer length\n");
> fprintf(stderr, "\t-p\tspecify the saved file prefix, may include
> path\n");
> fprintf(stderr, "\t-f\tspecify the saved file format\n");
> + fprintf(stderr, "\t-q\tspecify the seconds of silence before stop\n");
> + fprintf(stderr, "\t-w\tspecify the start threashold\n");
> + fprintf(stderr, "\t-e\tspecify the stop threashold\n");
> fprintf(stderr, "\n");
> fprintf(stderr, "\tchannels must be in the range 1-8, default %d\n",
> DEFAULT_NUM_PORTS);
> @@ -164,7 +198,10 @@
> }
> DEBUG(1, "registering as %s\n", client_name);
>
> - process_init(buf_length);
> + /* garetts mod here
> + * process_init(buf_length)
> + */
> + process_init(buf_length, SECONDS_OF_SILENCE_BEFORE_STOP,
> START_THREASHOLD, STOP_THREASHOLD, AUTO_RECORD);
>
> #ifdef HAVE_LASH
> lash_client = lash_init (lash_args, "TimeMachine",
> @@ -287,6 +324,11 @@
> exit(0);
> }
>
> +void signal_handler(int iSignal) {
> + recording_stop();
> + cleanup();
> +}
> +
> #ifdef HAVE_LASH
> gboolean idle_cb(gpointer data)
> {
> diff -urN timemachine-0.3.1/src/threads.c
> timemachine-0.3.1.autorecord/src/threads.c
> --- timemachine-0.3.1/src/threads.c 2005-07-18 08:03:06.000000000 -0600
> +++ timemachine-0.3.1.autorecord/src/threads.c 2006-01-14
> 10:58:18.000000000 -0700
> @@ -19,7 +19,7 @@
> #include <string.h>
> #include <stdio.h>
> #include <unistd.h>
> -#include <time.h>
> +#include <sys/time.h>
> #include <sndfile.h>
> #include <jack/jack.h>
> #include <gtk/gtk.h>
> @@ -46,6 +46,15 @@
> static unsigned int disk_read_pos = 0;
> static unsigned int disk_write_pos = 0;
>
> +/* garetts mod here */
> +static float seconds_of_silence_before_stop = 0;
> +static float start_threashold = 0;
> +static float stop_threashold = 0;
> +static float seconds_of_silence = 0;
> +static int sample_rate = 0;
> +static int autorecord = 0;
> +/* end garetts mod */
> +
> /* Peak data for meters */
> static volatile float peak[MAX_PORTS];
>
> @@ -69,6 +78,32 @@
> fprintf(stderr, "bad buffer!\n");
> break;
> }
> +
> + /* garetts mod here */
> + if (autorecord) {
> + if (rec) {
> + for (i = 0; i < nframes; i++) {
> + if (fabsf(in[i]) <= stop_threashold) {
> + seconds_of_silence = seconds_of_silence + 1.0/sample_rate;
> + }
> + else {
> + seconds_of_silence = 0;
> + }
> + if (seconds_of_silence > seconds_of_silence_before_stop) {
> + recording_stop();
> + }
> + }
> + }
> + else {
> + for (i = 0; i < nframes; i++) {
> + if (fabsf(in[i]) > start_threashold) {
> + recording_start();
> + break;
> + }
> + }
> + }
> + }
> + /* end garetts mod */
>
> for (i = 0; i < nframes; i++) {
> if (fabsf(in[i]) > peak[port]) {
> @@ -202,7 +236,10 @@
> return 0;
> }
>
> -void process_init(unsigned int time)
> +/* garetts mod here
> + * void process_init(unsigned int time)
> + */
> +void process_init(unsigned int time, float secs_of_silence_before_stop,
> float strt_threashold, float stp_threashold, int use_autorecord)
> {
> unsigned int port;
>
> @@ -220,6 +257,14 @@
> pre_size = time * jack_get_sample_rate(client);
> pre_time = time;
>
> + /* garetts mod here */
> + seconds_of_silence_before_stop = secs_of_silence_before_stop;
> + start_threashold = strt_threashold;
> + stop_threashold = stp_threashold;
> + sample_rate = jack_get_sample_rate(client);
> + autorecord = use_autorecord;
> + /* end garetts mod */
> +
> for (port = 0; port < num_ports; port++) {
> pre_buffer[port] = calloc(pre_size, sizeof(float));
> disk_buffer[port] = calloc(DISK_SIZE, sizeof(float));
> diff -urN timemachine-0.3.1/src/threads.h
> timemachine-0.3.1.autorecord/src/threads.h
> --- timemachine-0.3.1/src/threads.h 2005-07-18 08:03:06.000000000 -0600
> +++ timemachine-0.3.1.autorecord/src/threads.h 2006-01-14
> 10:56:37.000000000 -0700
> @@ -9,7 +9,10 @@
>
> int process(jack_nframes_t nframes, void *arg);
>
> -void process_init(unsigned int time);
> +/* garetts mod here
> + * void process_init(unsigned int time)
> + */
> +void process_init(unsigned int time, float secs_of_silence_before_stop,
> float strt_threashold, float stp_threashold, int use_autorecord);
>
> int writer_thread(void *d);
>
>

-- 
Hans Fugal ; http://hans.fugal.net
 
There's nothing remarkable about it. All one has to do is hit the 
right keys at the right time and the instrument plays itself.
    -- Johann Sebastian Bach

Received on Sun Jan 15 04:15:07 2006

This archive was generated by hypermail 2.1.8 : Sun Jan 15 2006 - 04:15:07 EET