PRIVATE int init_instance(Generator *g) { Data *data; instance_count++; if (instance_count > 1) /* Not allowed more than one of these things. */ return 0; data = safe_malloc(sizeof(Data)); data->audiofd = open_audiofd(); if (data->audiofd < 0) { free(data); popup_msgbox("Error", MSGBOX_OK, 120000, MSGBOX_OK, "Could not open ESound audio subsystem."); return 0; } data->input_tag = -1; data->clock = gen_register_clock(g, "ESD Output Clock", clock_handler); g->data = data; gen_register_realtime_fn(g, realtime_handler); gen_select_clock(data->clock); /* a not unreasonable assumption? */ return 1; }
PRIVATE void clock_handler(AClock *clock, AClockReason reason) { Data *data = clock->gen->data; switch (reason) { case CLOCK_DISABLE: if (data->open) { gtk_idle_remove(data->idle_tag); close_audiofd(data->hwo); data->open = FALSE; } break; case CLOCK_ENABLE: if (!data->open) { data->open = open_audiofd(&data->hwo); if (data->open) data->idle_tag = gtk_idle_add(idle_handler, NULL); } break; default: g_message("Unreachable code reached (win_output)... reason = %d", reason); break; } }
int main (int argc, char *argv[]) { char jack_name[64] = "alsa_out"; char alsa_device[64] = "hw:0"; char server_name[64] = "default"; extern char *optarg; extern int optind, optopt; int errflg=0; int c; while ((c = getopt(argc, argv, "ivj:r:c:p:n:d:q:m:t:f:F:C:Q:s:S:")) != -1) { switch(c) { case 'j': strncpy(jack_name,optarg, sizeof(jack_name)); break; case 'r': sample_rate = atoi(optarg); break; case 'c': num_channels = atoi(optarg); break; case 'p': period_size = atoi(optarg); break; case 'n': num_periods = atoi(optarg); break; case 'd': strncpy(alsa_device,optarg,sizeof(alsa_device)); break; case 't': target_delay = atoi(optarg); break; case 'q': samplerate_quality = atoi(optarg); break; case 'm': max_diff = atoi(optarg); break; case 'f': catch_factor = atoi(optarg); break; case 'F': catch_factor2 = atoi(optarg); break; case 'C': pclamp = (double) atoi(optarg); break; case 'Q': controlquant = (double) atoi(optarg); break; case 'v': verbose = 1; break; case 'i': instrument = 1; break; case 's': smooth_size = atoi(optarg); break; case 'S': strncpy(server_name,optarg,sizeof(server_name)); break; case ':': fprintf(stderr, "Option -%c requires an operand\n", optopt); errflg++; break; case '?': fprintf(stderr, "Unrecognized option: -%c\n", optopt); errflg++; } } if (errflg) { printUsage(); exit(2); } if( (samplerate_quality < 0) || (samplerate_quality > 4) ) { fprintf (stderr, "invalid samplerate quality\n"); return 1; } if ((client = jack_client_open (jack_name, JackServerName, NULL, server_name)) == 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); if (jack_set_latency_callback) jack_set_latency_callback (client, latency_cb, 0); // get jack sample_rate jack_sample_rate = jack_get_sample_rate( client ); if( !sample_rate ) sample_rate = jack_sample_rate; static_resample_factor = (double) sample_rate / (double) jack_sample_rate; resample_lower_limit = static_resample_factor * 0.25; resample_upper_limit = static_resample_factor * 4.0; resample_mean = static_resample_factor; offset_array = malloc( sizeof(double) * smooth_size ); if( offset_array == NULL ) { fprintf( stderr, "no memory for offset_array !!!\n" ); exit(20); } window_array = malloc( sizeof(double) * smooth_size ); if( window_array == NULL ) { fprintf( stderr, "no memory for window_array !!!\n" ); exit(20); } int i; for( i=0; i<smooth_size; i++ ) { offset_array[i] = 0.0; window_array[i] = hann( (double) i / ((double) smooth_size - 1.0) ); } jack_buffer_size = jack_get_buffer_size( client ); // Setup target delay and max_diff for the normal user, who does not play with them... if( !target_delay ) target_delay = (num_periods*period_size / 2) - jack_buffer_size/2; if( !max_diff ) max_diff = target_delay; if( max_diff > target_delay ) { fprintf( stderr, "target_delay (%d) cant be smaller than max_diff(%d)\n", target_delay, max_diff ); exit(20); } if( (target_delay+max_diff) > (num_periods*period_size) ) { fprintf( stderr, "target_delay+max_diff (%d) cant be bigger than buffersize(%d)\n", target_delay+max_diff, num_periods*period_size ); exit(20); } // now open the alsa fd... alsa_handle = open_audiofd( alsa_device, 0, sample_rate, num_channels, period_size, num_periods); if( alsa_handle == 0 ) exit(20); printf( "selected sample format: %s\n", formats[format].name ); // alloc input ports, which are blasted out to alsa... alloc_ports( 0, num_channels ); outbuf = malloc( num_periods * period_size * formats[format].sample_size * num_channels ); resampbuf = malloc( num_periods * period_size * sizeof( float ) ); tmpbuf = malloc( 512 * formats[format].sample_size * num_channels ); if ((outbuf == NULL) || (resampbuf == NULL) || (tmpbuf == NULL)) { fprintf( stderr, "no memory for buffers.\n" ); exit(20); } /* tell the JACK server that we are ready to roll */ if (jack_activate (client)) { fprintf (stderr, "cannot activate client"); return 1; } signal( SIGTERM, sigterm_handler ); signal( SIGINT, sigterm_handler ); if( verbose ) { while(!quit) { usleep(500000); if( output_new_delay ) { printf( "delay = %d\n", output_new_delay ); output_new_delay = 0; } printf( "res: %f, \tdiff = %f, \toffset = %f \n", output_resampling_factor, output_diff, output_offset ); } } else if( instrument ) { printf( "# n\tresamp\tdiff\toffseti\tintegral\n"); int n=0; while(!quit) { usleep(1000); printf( "%d\t%f\t%f\t%f\t%f\n", n++, output_resampling_factor, output_diff, output_offset, output_integral ); } } else { while(!quit) { usleep(500000); if( output_new_delay ) { printf( "delay = %d\n", output_new_delay ); output_new_delay = 0; } } } jack_deactivate( client ); jack_client_close (client); exit (0); }