[linux-audio-dev] timemachine auto recorder patch

Hans Fugal hans at fugal.net
Sun Jan 15 00:50:22 UTC 2006


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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.linuxaudio.org/pipermail/linux-audio-dev/attachments/20060114/d106a05b/attachment.pgp>


More information about the Linux-audio-dev mailing list