int main (int argc, char * argv[]) { int rate = 44100; int bits = 16; int channels = 2; int codec = ROAR_CODEC_OGG_VORBIS; char * server = NULL; char * k; char * s_server = NULL; char * s_mount = NULL; char * s_pw = NULL; int s_port = -1; char * s_desc = NULL; char * s_genre = NULL; char * s_name = NULL; char * s_url = NULL; int s_public = 0; int fh; int i; char buf[BUFSIZE]; shout_t * shout; for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 ) { server = argv[++i]; } else if ( strcmp(k, "--rate") == 0 ) { rate = atoi(argv[++i]); } else if ( strcmp(k, "--bits") == 0 ) { bits = atoi(argv[++i]); } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 ) { channels = atoi(argv[++i]); } else if ( strcmp(k, "--codec") == 0 ) { codec = roar_str2codec(argv[++i]); } else if ( strcmp(k, "-p") == 0 || strcmp(k, "--public") == 0 ) { s_public = 1; } else if ( strcmp(k, "-d") == 0 ) { s_desc = argv[++i]; } else if ( strcmp(k, "-g") == 0 ) { s_genre = argv[++i]; } else if ( strcmp(k, "-n") == 0 ) { s_name = argv[++i]; } else if ( strcmp(k, "-u") == 0 ) { s_url = argv[++i]; } else if ( strcmp(k, "-h") == 0 || strcmp(k, "--help") == 0 ) { usage(); return 0; } else if ( s_server == NULL ) { s_server = k; } else if ( s_port == -1 ) { s_port = atoi(k); } else if ( s_pw == NULL ) { s_pw = k; } else if ( s_mount == NULL ) { s_mount = k; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } if ( s_server == NULL ) s_server = "localhost"; if ( s_mount == NULL ) s_mount = "/roar.ogg"; if ( s_pw == NULL ) s_pw = "hackme"; if ( s_port == -1 ) s_port = 8000; shout_init(); if (!(shout = shout_new())) { ROAR_ERR("Can not create shout object"); return 1; } if (shout_set_host(shout, s_server) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting hostname: %s", shout_get_error(shout)); return 1; } if (shout_set_protocol(shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting protocol: %s", shout_get_error(shout)); return 1; } if (shout_set_port(shout, s_port) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting port: %s", shout_get_error(shout)); return 1; } if (shout_set_password(shout, s_pw) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting password: %s", shout_get_error(shout)); return 1; } if (shout_set_mount(shout, s_mount) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting mount: %s", shout_get_error(shout)); return 1; } if (shout_set_user(shout, "source") != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting user: %s", shout_get_error(shout)); return 1; } if (shout_set_format(shout, SHOUT_FORMAT_OGG) != SHOUTERR_SUCCESS) { ROAR_ERR("Error setting format: %s", shout_get_error(shout)); return 1; } shout_set_public(shout, s_public); if (s_desc != NULL) shout_set_description(shout, s_desc); if (s_genre != NULL) shout_set_genre(shout, s_genre); if (s_name != NULL) shout_set_name(shout, s_name); if (s_url != NULL) shout_set_url(shout, s_url); if ( (fh = roar_simple_monitor(rate, channels, bits, codec, server, "roarshout")) == -1 ) { fprintf(stderr, "Error: can not start monitoring\n"); return 1; } if (shout_open(shout) != SHOUTERR_SUCCESS) { ROAR_ERR("Can not open connection via libshout!"); return -1; } while((i = read(fh, buf, BUFSIZE))) if (shout_send(shout, (unsigned char*)buf, i) != SHOUTERR_SUCCESS) break; roar_simple_close(fh); shout_sync(shout); shout_close(shout); shout_shutdown(); return 0; }
input_module_t *roar_open_module(module_param_t *params) { input_module_t *mod = calloc(1, sizeof(input_module_t)); im_roar_state *s; module_param_t *current; const char * server = NULL; int dir = ROAR_DIR_MONITOR; enum { MD_NONE = 0, MD_FILE = 1, MD_STREAM = 2 } use_metadata = MD_STREAM; int err; mod->getdata = roar_read; mod->handle_event = event_handler; mod->metadata_update = metadata_update; mod->internal = calloc(1, sizeof(im_roar_state)); s = mod->internal; if(roar_profile2info(&s->info, "default") == -1) { LOG_ERROR1("Failed to get default audio profile: %s", roar_error2str(roar_error)); return NULL; } s->info.bits = 16; s->vss = NULL; s->plugins = roar_plugincontainer_new_simple(IM_ROAR_APPNAME, IM_ROAR_ABIVERSION); if (!s->plugins) { LOG_ERROR1("Failed to create plugin container: %s", roar_error2str(roar_error)); return NULL; } thread_mutex_create(&s->metadatalock); current = params; while(current) { if(!strcmp(current->name, "rate")) s->info.rate = roar_str2rate(current->value); else if(!strcmp(current->name, "channels")) s->info.channels = roar_str2channels(current->value); else if(!strcmp(current->name, "codec")) s->info.codec = roar_str2codec(current->value); else if(!strcmp(current->name, "aiprofile")) { if (roar_profile2info(&s->info, current->value) == -1) { LOG_WARN2("Can not get audio info profile %s: %s", current->value, roar_error2str(roar_error)); } s->info.bits = 16; } else if(!strcmp(current->name, "dir")) { if ( !strcasecmp(current->value, "monitor") ) { dir = ROAR_DIR_MONITOR; } else if ( !strcasecmp(current->value, "record") ) { dir = ROAR_DIR_RECORD; } else { LOG_WARN2("Unknown value %s for parameter %s for roar module", current->value, current->name); } } else if(!strcmp(current->name, "device") || !strcmp(current->name, "server")) server = current->value; else if(!strcmp(current->name, "metadata")) { if ( !strcasecmp(current->value, "none") ) { use_metadata = MD_NONE; } else if ( !strcasecmp(current->value, "file") ) { use_metadata = MD_FILE; } else if ( !strcasecmp(current->value, "stream") ) { use_metadata = MD_STREAM; } else { use_metadata = atoi(current->value); } } else if(!strcmp(current->name, "metadatafilename")) { ices_config->metadata_filename = current->value; use_metadata = MD_FILE; } else if(!strcmp(current->name, "plugin")) { roar_plugin_load(mod, current->value); } else LOG_WARN1("Unknown parameter %s for roar module", current->name); current = current->next; } mod->type = ICES_INPUT_PCM; switch (s->info.codec) { case ROAR_CODEC_PCM_LE: mod->subtype = INPUT_PCM_LE_16; break; case ROAR_CODEC_PCM_BE: mod->subtype = INPUT_PCM_BE_16; break; case ROAR_CODEC_OGG_GENERAL: LOG_WARN0("Codec may not work, specify ogg_vorbis for Vorbis streaming"); case ROAR_CODEC_OGG_VORBIS: mod->type = ICES_INPUT_VORBIS; // we do not set mod->subtype here, strange design ices2 has... break; case -1: LOG_ERROR0("Unknown Codec"); return NULL; default: LOG_ERROR1("Unsupported Codec: %s", roar_codec2str(s->info.codec)); return NULL; } roar_plugincontainer_appsched_trigger(s->plugins, ROAR_DL_APPSCHED_INIT); /* Open the VS connection */ if ( (s->vss = roar_vs_new(server, IM_ROAR_PROGNAME, &err)) == NULL ) { LOG_ERROR2("Failed to open sound server %s: %s", server, roar_vs_strerr(err)); goto fail; } /* Now, set the required parameters on that device */ if ( roar_vs_stream(s->vss, &s->info, dir, &err) == -1 ) { LOG_ERROR2("Failed to create a new stream on sound server %s: %s", server, roar_vs_strerr(err)); goto fail; } if ( _set_flags(roar_vs_connection_obj(s->vss, NULL), roar_vs_stream_obj(s->vss, NULL), ROAR_FLAG_META, ROAR_RESET_FLAG) != 0 ) { LOG_WARN0("Can not reset metadata flag from stream"); } /* We're done, and we didn't fail! */ LOG_INFO3("Opened sound server at %s at %d channel(s), %d Hz", server, s->info.channels, s->info.rate); switch (use_metadata) { case MD_NONE: break; case MD_FILE: LOG_INFO0("Starting metadata update thread"); if(ices_config->metadata_filename) thread_create("im_roar-metadata", metadata_thread_signal, mod, 1); else thread_create("im_roar-metadata", metadata_thread_stdin, mod, 1); break; case MD_STREAM: if ( _set_flags(roar_vs_connection_obj(s->vss, NULL), roar_vs_stream_obj(s->vss, NULL), ROAR_FLAG_META, ROAR_SET_FLAG) != 0 ) { LOG_WARN0("Can not set metadata flag from stream"); } break; } return mod; fail: close_module(mod); /* safe, this checks for valid contents */ return NULL; }
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; }
int main (int argc, char * argv[]) { int rate = 44100; int bits = 16; int channels = 2; int codec = ROAR_CODEC_DEFAULT; char * server = NULL; char * k; int i; int in = ROAR_STDIN; struct roar_connection con; struct roar_stream s; for (i = 1; i < argc; i++) { k = argv[i]; if ( strcmp(k, "--server") == 0 ) { server = argv[++i]; } else if ( strcmp(k, "--rate") == 0 ) { rate = atoi(argv[++i]); } else if ( strcmp(k, "--bits") == 0 ) { bits = atoi(argv[++i]); } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 ) { channels = atoi(argv[++i]); } else if ( strcmp(k, "--codec") == 0 ) { codec = roar_str2codec(argv[++i]); } else if ( strcmp(k, "--help") == 0 ) { usage(); return 0; } else { fprintf(stderr, "Error: unknown argument: %s\n", k); usage(); return 1; } } if ( roar_simple_connect(&con, server, "roarcatpassfh") == -1 ) { ROAR_DBG("roar_simple_play(*): roar_simple_connect() faild!"); return 1; } if ( roar_stream_new(&s, rate, channels, bits, codec) == -1 ) { roar_disconnect(&con); return 1; } if ( roar_stream_connect(&con, &s, ROAR_DIR_PLAY) == -1 ) { roar_disconnect(&con); return 1; } if ( roar_stream_passfh(&con, &s, in) == -1 ) { roar_disconnect(&con); return 1; } close(in); sleep(1000); roar_disconnect(&con); return 0; }