int main(int argc, char **argv) { GError *error = NULL; struct audio_format audio_format; bool ret; const char *encoder_name; const struct encoder_plugin *plugin; struct encoder *encoder; struct config_param *param; static char buffer[32768]; ssize_t nbytes; /* parse command line */ if (argc > 3) { g_printerr("Usage: run_encoder [ENCODER] [FORMAT] <IN >OUT\n"); return 1; } if (argc > 1) encoder_name = argv[1]; else encoder_name = "vorbis"; audio_format_init(&audio_format, 44100, SAMPLE_FORMAT_S16, 2); /* create the encoder */ plugin = encoder_plugin_get(encoder_name); if (plugin == NULL) { g_printerr("No such encoder: %s\n", encoder_name); return 1; } param = config_new_param(NULL, -1); config_add_block_param(param, "quality", "5.0", -1); encoder = encoder_init(plugin, param, &error); if (encoder == NULL) { g_printerr("Failed to initialize encoder: %s\n", error->message); g_error_free(error); return 1; } /* open the encoder */ if (argc > 2) { ret = audio_format_parse(&audio_format, argv[2], false, &error); if (!ret) { g_printerr("Failed to parse audio format: %s\n", error->message); g_error_free(error); return 1; } } ret = encoder_open(encoder, &audio_format, &error); if (encoder == NULL) { g_printerr("Failed to open encoder: %s\n", error->message); g_error_free(error); return 1; } /* do it */ while ((nbytes = read(0, buffer, sizeof(buffer))) > 0) { ret = encoder_write(encoder, buffer, nbytes, &error); if (!ret) { g_printerr("encoder_write() failed: %s\n", error->message); g_error_free(error); return 1; } encoder_to_stdout(encoder); } ret = encoder_flush(encoder, &error); if (!ret) { g_printerr("encoder_flush() failed: %s\n", error->message); g_error_free(error); return 1; } encoder_to_stdout(encoder); }
int main(int argc, char **argv) { struct audio_format audio_format; struct audio_format_string af_string; bool success; GError *error = NULL; struct filter *filter; const struct audio_format *out_audio_format; char buffer[4096]; size_t frame_size; if (argc < 3 || argc > 4) { g_printerr("Usage: run_filter CONFIG NAME [FORMAT] <IN\n"); return 1; } audio_format_init(&audio_format, 44100, SAMPLE_FORMAT_S16, 2); /* initialize GLib */ g_thread_init(NULL); g_log_set_default_handler(my_log_func, NULL); /* read configuration file (mpd.conf) */ config_global_init(); success = config_read_file(argv[1], &error); if (!success) { g_printerr("%s:", error->message); g_error_free(error); return 1; } /* parse the audio format */ if (argc > 3) { success = audio_format_parse(&audio_format, argv[3], false, &error); if (!success) { g_printerr("Failed to parse audio format: %s\n", error->message); g_error_free(error); return 1; } } /* initialize the filter */ filter = load_filter(argv[2]); if (filter == NULL) return 1; /* open the filter */ out_audio_format = filter_open(filter, &audio_format, &error); if (out_audio_format == NULL) { g_printerr("Failed to open filter: %s\n", error->message); g_error_free(error); filter_free(filter); return 1; } g_printerr("audio_format=%s\n", audio_format_to_string(out_audio_format, &af_string)); frame_size = audio_format_frame_size(&audio_format); /* play */ while (true) { ssize_t nbytes; size_t length; const void *dest; nbytes = read(0, buffer, sizeof(buffer)); if (nbytes <= 0) break; dest = filter_filter(filter, buffer, (size_t)nbytes, &length, &error); if (dest == NULL) { g_printerr("Filter failed: %s\n", error->message); filter_close(filter); filter_free(filter); return 1; } nbytes = write(1, dest, length); if (nbytes < 0) { g_printerr("Failed to write: %s\n", strerror(errno)); filter_close(filter); filter_free(filter); return 1; } } /* cleanup and exit */ filter_close(filter); filter_free(filter); config_global_finish(); return 0; }
int main(int argc, char **argv) { struct audio_output ao; struct audio_format audio_format; struct audio_format_string af_string; bool success; GError *error = NULL; char buffer[4096]; ssize_t nbytes; size_t frame_size, length = 0, play_length, consumed; if (argc < 3 || argc > 4) { g_printerr("Usage: run_output CONFIG NAME [FORMAT] <IN\n"); return 1; } audio_format_init(&audio_format, 44100, SAMPLE_FORMAT_S16, 2); g_thread_init(NULL); /* read configuration file (mpd.conf) */ config_global_init(); success = config_read_file(argv[1], &error); if (!success) { g_printerr("%s:", error->message); g_error_free(error); return 1; } /* initialize the audio output */ if (!load_audio_output(&ao, argv[2])) return 1; /* parse the audio format */ if (argc > 3) { success = audio_format_parse(&audio_format, argv[3], false, &error); if (!success) { g_printerr("Failed to parse audio format: %s\n", error->message); g_error_free(error); return 1; } } /* open the audio output */ success = ao_plugin_open(ao.plugin, ao.data, &audio_format, &error); if (!success) { g_printerr("Failed to open audio output: %s\n", error->message); g_error_free(error); return 1; } g_printerr("audio_format=%s\n", audio_format_to_string(&audio_format, &af_string)); frame_size = audio_format_frame_size(&audio_format); /* play */ while (true) { if (length < sizeof(buffer)) { nbytes = read(0, buffer + length, sizeof(buffer) - length); if (nbytes <= 0) break; length += (size_t)nbytes; } play_length = (length / frame_size) * frame_size; if (play_length > 0) { consumed = ao_plugin_play(ao.plugin, ao.data, buffer, play_length, &error); if (consumed == 0) { g_printerr("Failed to play: %s\n", error->message); g_error_free(error); return 1; } assert(consumed <= length); assert(consumed % frame_size == 0); length -= consumed; memmove(buffer, buffer + consumed, length); } } /* cleanup and exit */ ao_plugin_close(ao.plugin, ao.data); ao_plugin_finish(ao.plugin, ao.data); g_mutex_free(ao.mutex); config_global_finish(); return 0; }
bool audio_output_init(struct audio_output *ao, const struct config_param *param, GError **error_r) { const struct audio_output_plugin *plugin = NULL; GError *error = NULL; if (param) { const char *p; p = config_get_block_string(param, AUDIO_OUTPUT_TYPE, NULL); if (p == NULL) { g_set_error(error_r, audio_output_quark(), 0, "Missing \"type\" configuration"); return false; } plugin = audio_output_plugin_get(p); if (plugin == NULL) { g_set_error(error_r, audio_output_quark(), 0, "No such audio output plugin: %s", p); return false; } ao->name = config_get_block_string(param, AUDIO_OUTPUT_NAME, NULL); if (ao->name == NULL) { g_set_error(error_r, audio_output_quark(), 0, "Missing \"name\" configuration"); return false; } p = config_get_block_string(param, AUDIO_OUTPUT_FORMAT, NULL); if (p != NULL) { bool success = audio_format_parse(&ao->config_audio_format, p, true, error_r); if (!success) return false; } else audio_format_clear(&ao->config_audio_format); } else { g_warning("No \"%s\" defined in config file\n", CONF_AUDIO_OUTPUT); plugin = audio_output_detect(error_r); if (plugin == NULL) return false; g_message("Successfully detected a %s audio device", plugin->name); ao->name = "default detected output"; audio_format_clear(&ao->config_audio_format); } ao->plugin = plugin; ao->always_on = config_get_block_bool(param, "always_on", false); ao->enabled = config_get_block_bool(param, "enabled", true); ao->really_enabled = false; ao->open = false; ao->pause = false; ao->fail_timer = NULL; pcm_buffer_init(&ao->cross_fade_buffer); /* set up the filter chain */ ao->filter = filter_chain_new(); assert(ao->filter != NULL); /* create the replay_gain filter */ const char *replay_gain_handler = config_get_block_string(param, "replay_gain_handler", "software"); if (strcmp(replay_gain_handler, "none") != 0) { ao->replay_gain_filter = filter_new(&replay_gain_filter_plugin, param, NULL); assert(ao->replay_gain_filter != NULL); ao->replay_gain_serial = 0; ao->other_replay_gain_filter = filter_new(&replay_gain_filter_plugin, param, NULL); assert(ao->other_replay_gain_filter != NULL); ao->other_replay_gain_serial = 0; } else { ao->replay_gain_filter = NULL; ao->other_replay_gain_filter = NULL; } /* create the normalization filter (if configured) */ if (config_get_bool(CONF_VOLUME_NORMALIZATION, false)) { struct filter *normalize_filter = filter_new(&normalize_filter_plugin, NULL, NULL); assert(normalize_filter != NULL); filter_chain_append(ao->filter, autoconvert_filter_new(normalize_filter)); } filter_chain_parse(ao->filter, config_get_block_string(param, AUDIO_FILTERS, ""), &error ); // It's not really fatal - Part of the filter chain has been set up already // and even an empty one will work (if only with unexpected behaviour) if (error != NULL) { g_warning("Failed to initialize filter chain for '%s': %s", ao->name, error->message); g_error_free(error); } ao->thread = NULL; ao->command = AO_COMMAND_NONE; ao->mutex = g_mutex_new(); ao->cond = g_cond_new(); ao->data = ao_plugin_init(plugin, &ao->config_audio_format, param, error_r); if (ao->data == NULL) return false; ao->mixer = audio_output_load_mixer(ao->data, param, plugin->mixer_plugin, ao->filter, &error); if (ao->mixer == NULL && error != NULL) { g_warning("Failed to initialize hardware mixer for '%s': %s", ao->name, error->message); g_error_free(error); } /* use the hardware mixer for replay gain? */ if (strcmp(replay_gain_handler, "mixer") == 0) { if (ao->mixer != NULL) replay_gain_filter_set_mixer(ao->replay_gain_filter, ao->mixer, 100); else g_warning("No such mixer for output '%s'", ao->name); } else if (strcmp(replay_gain_handler, "software") != 0 && ao->replay_gain_filter != NULL) { g_set_error(error_r, audio_output_quark(), 0, "Invalid \"replay_gain_handler\" value"); return false; } /* the "convert" filter must be the last one in the chain */ ao->convert_filter = filter_new(&convert_filter_plugin, NULL, NULL); assert(ao->convert_filter != NULL); filter_chain_append(ao->filter, ao->convert_filter); /* done */ return true; }