gboolean gitg_shell_run_stream (GitgShell *shell, GInputStream *stream, GError **error) { g_return_val_if_fail (GITG_IS_SHELL (shell), FALSE); g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE); gitg_io_cancel (GITG_IO (shell)); run_stream (shell, stream); return TRUE; }
static gboolean run_commands (GitgShell *shell, GitgCommand **commands, GError **error) { GitgIO *io; GitgRunner *prev = NULL; GOutputStream *output; gboolean ret = TRUE; GitgCommand **ptr; io = GITG_IO (shell); output = gitg_io_get_output (io); shell->priv->read_done = TRUE; gitg_io_cancel (GITG_IO (shell)); gitg_io_begin (GITG_IO (shell)); /* Ref sink all commands */ for (ptr = commands; *ptr; ++ptr) { g_object_ref_sink (*ptr); } if (shell->priv->synchronized) { shell->priv->main_loop = g_main_loop_new (NULL, FALSE); } /* Setup runners */ for (ptr = commands; *ptr; ++ptr) { GitgRunner *runner; runner = gitg_runner_new (*ptr); if (gitg_io_get_stderr_to_stdout (GITG_IO (shell))) { gitg_io_set_stderr_to_stdout (GITG_IO (runner), TRUE); } g_signal_connect (runner, "end", G_CALLBACK (runner_end), shell); if (ptr == commands) { /* Copy input set on the shell to the first runner */ GInputStream *input; input = gitg_io_get_input (io); if (input != NULL) { gitg_io_set_input (GITG_IO (runner), input); } } else { /* Set output of the previous runner to the input of this runner */ gitg_io_set_input (GITG_IO (runner), gitg_runner_get_stream (prev)); } if (!*(ptr + 1)) { shell->priv->last_runner = runner; /* Copy output set on the shell to the last runner */ if (output != NULL) { gitg_io_set_output (GITG_IO (runner), output); } } shell->priv->runners = g_slist_append (shell->priv->runners, runner); /* Start the runner */ gitg_runner_run (runner); if (shell->priv->runners == NULL) { /* This means it there was an error */ if (error && shell->priv->error) { *error = g_error_copy (shell->priv->error); } if (shell->priv->error) { g_error_free (shell->priv->error); shell->priv->error = NULL; } ret = FALSE; goto cleanup; } prev = runner; } /* Setup line reader if necessary in async mode */ if (output == NULL) { run_stream (shell, gitg_runner_get_stream (shell->priv->last_runner)); } if (shell->priv->synchronized) { return run_sync (shell, error); } cleanup: for (ptr = commands; *ptr; ++ptr) { g_object_unref (*ptr); } if (shell->priv->main_loop) { g_main_loop_unref (shell->priv->main_loop); shell->priv->main_loop = NULL; } return ret; }
int main (int argc, char * argv[]) { struct roar_audio_info info = {.rate = ROAR_RATE_DEFAULT, .bits = ROAR_BITS_DEFAULT, .channels = ROAR_CHANNELS_DEFAULT, .codec = ROAR_CODEC_DEFAULT }; struct roar_audio_info dinfo; struct roar_vio_calls dvio, svio, svio_jumbo, svio_real; struct roar_vio_calls * svio_p; struct roardsp_filter * filter; char * driver = DRIVER; char * device = NULL; char * server = NULL; char * k; int i; union { int32_t i32; size_t size; } tmp; memset(&g_conf, 0, sizeof(g_conf)); g_conf.antiecho = AE_ROARD; g_conf.dtx_threshold = -1; g_conf.ioflush_interval = -1; memset(&g_cons, 0, sizeof(g_cons)); g_cons.state = CON_NONE; memset(&g_meta, 0, sizeof(g_meta)); roardsp_fchain_init(&(g_filterchains.input)); roardsp_fchain_init(&(g_filterchains.output)); for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 ) { server = argv[++i]; } else if ( strcmp(k, "--jumbo-mtu") == 0 ) { g_conf.jumbo_mtu = atoi(argv[++i]); } else if ( strcmp(k, "--io-flush") == 0 ) { g_conf.ioflush_interval = atoi(argv[++i]); } else if ( strcmp(k, "--rate") == 0 ) { info.rate = atoi(argv[++i]); } else if ( strcmp(k, "--bits") == 0 ) { info.bits = atoi(argv[++i]); } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 ) { info.channels = atoi(argv[++i]); } else if ( strcmp(k, "--afi-downmix") == 0 ) { g_conf.filter.in.downmix = 1; } else if ( strcmp(k, "--afi-lowpass") == 0 ) { g_conf.filter.in.lowp_freq = atof(argv[++i]); } else if ( strcmp(k, "--afi-speex-prep") == 0 ) { g_conf.filter.in.speex_prep = 1; } else if ( strcmp(k, "--afi-speex-denoise") == 0 ) { g_conf.filter.in.speex_prep = 1; g_conf.filter.in.speex_prep_denoise = 1; } else if ( strcmp(k, "--afi-speex-agc") == 0 ) { g_conf.filter.in.speex_prep = 1; g_conf.filter.in.speex_prep_agc = 1; } else if ( strcmp(k, "--afi-speex-vad") == 0 ) { g_conf.filter.in.speex_prep = 1; g_conf.filter.in.speex_prep_vad = 1; } else if ( strcmp(k, "--codec") == 0 ) { info.codec = roar_str2codec(argv[++i]); } else if ( strcmp(k, "--driver") == 0 ) { driver = argv[++i]; } else if ( strcmp(k, "--device") == 0 ) { device = argv[++i]; } else if ( strcmp(k, "--antiecho") == 0 ) { k = argv[++i]; if ( !strcmp(k, "none") ) { g_conf.antiecho = AE_NONE; } else if ( !strcmp(k, "simple") ) { g_conf.antiecho = AE_SIMPLE; } else if ( !strcmp(k, "speex") ) { g_conf.antiecho = AE_SPEEX; } else if ( !strcmp(k, "roard") ) { g_conf.antiecho = AE_ROARD; } else { fprintf(stderr, "Error: unknown mode: %s\n", k); return 1; } } else if ( strcmp(k, "--threshold") == 0 ) { g_conf.dtx_threshold = atol(argv[++i]); // use threshold^2 or threshold < 0 for not using DTX if ( g_conf.dtx_threshold > 0 ) g_conf.dtx_threshold *= g_conf.dtx_threshold; } else if ( strcmp(k, "--transcode") == 0 ) { g_conf.transcode = 1; // META DATA: } else if ( strcmp(k, "--m-rn") == 0 ) { g_meta.rn = argv[++i]; } else if ( strcmp(k, "--m-nick") == 0 ) { g_meta.nick = argv[++i]; } else if ( strcmp(k, "--m-email") == 0 ) { g_meta.email = argv[++i]; } else if ( strcmp(k, "--m-hp") == 0 ) { g_meta.hp = argv[++i]; } else if ( strcmp(k, "--m-thumbn") == 0 ) { g_meta.thumbnail = argv[++i]; } else if ( strcmp(k, "--m-loc") == 0 ) { g_meta.loc = argv[++i]; } else if ( strcmp(k, "--m-org") == 0 ) { g_meta.org = argv[++i]; } else if ( strcmp(k, "--help") == 0 ) { usage(); return 0; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } // ignore errors, maybe it will work even if this fails // (btw. it will never fail without crashing the rest of the app ;) roar_libroar_set_server(server); if ( g_conf.antiecho == AE_SPEEX ) { ROAR_WARN("Speex Antiecho is obsolete and may be removed in future versions. Use --antiecho roard"); } g_conf.samples = info.channels * info.rate / TIMEDIV; memcpy(&dinfo, &info, sizeof(dinfo)); if ( g_conf.transcode ) { dinfo.bits = 16; dinfo.codec = ROAR_CODEC_DEFAULT; switch (info.codec) { case ROAR_CODEC_ALAW: case ROAR_CODEC_MULAW: info.bits = 8; break; case ROAR_CODEC_ROAR_CELT: info.bits = 16; break; case ROAR_CODEC_ROAR_SPEEX: info.bits = 16; break; } } if ( roar_cdriver_open(&dvio, driver, device, &dinfo, ROAR_DIR_BIDIR) == -1 ) { ROAR_ERR("Can not open sound card."); return 1; } ROAR_DBG("main(*): CALL open_stream(&svio, server, &info)"); if ( open_stream(&svio_real, server, &info) == -1 ) { ROAR_ERR("Can not open connection to server."); roar_vio_close(&dvio); return 2; } ROAR_DBG("main(*): RET"); if ( roar_vio_open_re(&svio, &svio_real) == -1 ) { ROAR_ERR("Can not open connection to server (RE VIO)."); roar_vio_close(&dvio); return 2; } if ( g_conf.jumbo_mtu ) { if ( roar_vio_open_jumbo(&svio_jumbo, &svio, g_conf.jumbo_mtu) == -1 ) { roar_vio_close(&dvio); roar_vio_close(&svio); return 2; } svio_p = &svio_jumbo; } else { svio_p = &svio; } set_meta(); if ( g_conf.transcode ) { dinfo.codec = info.codec; if ( roar_bixcoder_init(transcoder, &dinfo, svio_p) == -1 ) { roar_vio_close(&svio); roar_vio_close(&dvio); return 10; } // ignore errors as it may also work if this fails roar_bixcoder_write_header(transcoder); roar_bixcoder_read_header(transcoder); g_conf.samples = 8 * roar_bixcoder_packet_size(transcoder, -1) / dinfo.bits; } #define _err(x) roar_vio_close(&dvio); roar_vio_close(&svio); return (x) if ( g_conf.filter.in.downmix ) { if ( roardsp_filter_new(&filter, &(g_cons.stream), ROARDSP_FILTER_DOWNMIX) == -1 ) { _err(2); } if ( roardsp_fchain_add(&(g_filterchains.input), filter) == -1 ) { _err(2); } } if ( g_conf.filter.in.lowp_freq > 1 ) { if ( roardsp_filter_new(&filter, &(g_cons.stream), ROARDSP_FILTER_LOWP) == -1 ) { _err(2); } if ( roardsp_filter_ctl(filter, ROARDSP_FCTL_FREQ, &(g_conf.filter.in.lowp_freq)) == -1 ) { _err(2); } if ( roardsp_fchain_add(&(g_filterchains.input), filter) == -1 ) { _err(2); } } if ( g_conf.filter.in.speex_prep ) { if ( roardsp_filter_new(&filter, &(g_cons.stream), ROARDSP_FILTER_SPEEX_PREP) == -1 ) { _err(2); } tmp.size = g_conf.samples; if ( roardsp_filter_ctl(filter, ROARDSP_FCTL_PACKET_SIZE, &tmp) == -1 ) { _err(2); } tmp.i32 = 0; if ( g_conf.filter.in.speex_prep_denoise ) tmp.i32 |= ROARDSP_SPEEX_PREP_DENOISE_ON; if ( g_conf.filter.in.speex_prep_agc ) tmp.i32 |= ROARDSP_SPEEX_PREP_AGC_ON; if ( g_conf.filter.in.speex_prep_vad ) tmp.i32 |= ROARDSP_SPEEX_PREP_VAD_ON; if ( roardsp_filter_ctl(filter, ROARDSP_FCTL_MODE, &tmp) == -1 ) { _err(2); } if ( roardsp_fchain_add(&(g_filterchains.input), filter) == -1 ) { _err(2); } } #undef _err ROAR_DBG("main(*): CALL run_stream(&dvio, &svio, &info);"); run_stream(&dvio, svio_p, &info); ROAR_DBG("main(*): RET"); roar_bixcoder_close(transcoder); roar_vio_close(svio_p); roar_vio_close(&dvio); roardsp_fchain_uninit(&(g_filterchains.input)); roardsp_fchain_uninit(&(g_filterchains.output)); roar_disconnect(&(g_cons.con)); return 0; }