Пример #1
0
static const struct audio_format *
ao_filter_open(struct audio_output *ao,
               struct audio_format *audio_format,
               GError **error_r)
{
    assert(audio_format_valid(audio_format));

    /* the replay_gain filter cannot fail here */
    if (ao->replay_gain_filter != NULL)
        filter_open(ao->replay_gain_filter, audio_format, error_r);
    if (ao->other_replay_gain_filter != NULL)
        filter_open(ao->other_replay_gain_filter, audio_format,
                    error_r);

    const struct audio_format *af
        = filter_open(ao->filter, audio_format, error_r);
    if (af == NULL) {
        if (ao->replay_gain_filter != NULL)
            filter_close(ao->replay_gain_filter);
        if (ao->other_replay_gain_filter != NULL)
            filter_close(ao->other_replay_gain_filter);
    }

    return af;
}
Пример #2
0
static void
ao_filter_close(struct audio_output *ao)
{
    if (ao->replay_gain_filter != NULL)
        filter_close(ao->replay_gain_filter);
    if (ao->other_replay_gain_filter != NULL)
        filter_close(ao->other_replay_gain_filter);

    filter_close(ao->filter);
}
static void
autoconvert_filter_close(struct filter *_filter)
{
	struct autoconvert_filter *filter =
		(struct autoconvert_filter *)_filter;

	if (filter->convert != NULL) {
		filter_close(filter->convert);
		filter_free(filter->convert);
	}

	filter_close(filter->filter);
}
static const struct audio_format *
autoconvert_filter_open(struct filter *_filter,
			struct audio_format *in_audio_format,
			GError **error_r)
{
	struct autoconvert_filter *filter =
		(struct autoconvert_filter *)_filter;
	const struct audio_format *out_audio_format;

	assert(audio_format_valid(in_audio_format));

	/* open the "real" filter */

	filter->in_audio_format = *in_audio_format;

	out_audio_format = filter_open(filter->filter,
				       &filter->in_audio_format, error_r);
	if (out_audio_format == NULL)
		return NULL;

	/* need to convert? */

	if (!audio_format_equals(&filter->in_audio_format, in_audio_format)) {
		/* yes - create a convert_filter */
		struct audio_format audio_format2 = *in_audio_format;
		const struct audio_format *audio_format3;

		filter->convert = filter_new(&convert_filter_plugin, NULL,
					     error_r);
		if (filter->convert == NULL) {
			filter_close(filter->filter);
			return NULL;
		}

		audio_format3 = filter_open(filter->convert, &audio_format2,
					    error_r);
		if (audio_format3 == NULL) {
			filter_free(filter->convert);
			filter_close(filter->filter);
			return NULL;
		}

		assert(audio_format_equals(&audio_format2, in_audio_format));

		convert_filter_set(filter->convert, &filter->in_audio_format);
	} else
		/* no */
		filter->convert = NULL;

	return out_audio_format;
}
static void
chain_close_child(gpointer data, G_GNUC_UNUSED gpointer user_data)
{
	struct filter *filter = data;

	filter_close(filter);
}
static const struct audio_format *
chain_open_child(struct filter *filter,
		 const struct audio_format *prev_audio_format,
		 GError **error_r)
{
	struct audio_format conv_audio_format = *prev_audio_format;
	const struct audio_format *next_audio_format;

	next_audio_format = filter_open(filter, &conv_audio_format, error_r);
	if (next_audio_format == NULL)
		return NULL;

	if (!audio_format_equals(&conv_audio_format, prev_audio_format)) {
		struct audio_format_string s;

		filter_close(filter);
		g_set_error(error_r, filter_quark(), 0,
			    "Audio format not supported by filter '%s': %s",
			    filter->plugin->name,
			    audio_format_to_string(prev_audio_format, &s));
		return NULL;
	}

	return next_audio_format;
}
static void
ao_reopen_filter(struct audio_output *ao)
{
	const struct audio_format *filter_audio_format;
	GError *error = NULL;

	filter_close(ao->filter);
	filter_audio_format = filter_open(ao->filter, &ao->in_audio_format,
					  &error);
	if (filter_audio_format == NULL) {
		g_warning("Failed to open filter for \"%s\" [%s]: %s",
			  ao->name, ao->plugin->name, error->message);
		g_error_free(error);

		/* this is a little code duplication fro ao_close(),
		   but we cannot call this function because we must
		   not call filter_close(ao->filter) again */

		ao->pipe = NULL;

		ao->chunk = NULL;
		ao->open = false;
		ao->fail_timer = g_timer_new();

		g_mutex_unlock(ao->mutex);
		ao_plugin_close(ao->plugin, ao->data);
		g_mutex_lock(ao->mutex);

		return;
	}

	convert_filter_set(ao->convert_filter, &ao->out_audio_format);
}
Пример #8
0
static void
quh_signal_handler (int signum)
{
  switch (signum)
    {
      case SIGINT:
      case SIGTERM:
        if (quh.filter_chain)
          filter_close (quh.filter_chain, &quh.nfo);
              
        fflush (stdout);
        fputs ("Quh: break", stderr);
        exit (0);
        break;
        
      default:
        break;
    }
}
/**
 * Close all filters in the chain until #until is reached.  #until
 * itself is not closed.
 */
static void
chain_close_until(struct filter_chain *chain, const struct filter *until)
{
	GSList *i = chain->children;
	struct filter *filter;

	while (true) {
		/* this assertion fails if #until does not exist
		   (anymore) */
		assert(i != NULL);

		if (i->data == until)
			/* don't close this filter */
			break;

		/* close this filter */
		filter = i->data;
		filter_close(filter);

		i = g_slist_next(i);
	}
}
Пример #10
0
static void
ao_close(struct audio_output *ao, bool drain)
{
	assert(ao->open);

	ao->pipe = NULL;

	ao->chunk = NULL;
	ao->open = false;

	g_mutex_unlock(ao->mutex);

	if (drain)
		ao_plugin_drain(ao->plugin, ao->data);
	else
		ao_plugin_cancel(ao->plugin, ao->data);

	ao_plugin_close(ao->plugin, ao->data);
	filter_close(ao->filter);

	g_mutex_lock(ao->mutex);

	g_debug("closed plugin=%s name=\"%s\"", ao->plugin->name, ao->name);
}
Пример #11
0
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;
}
Пример #12
0
int main(int argc, char **argv){
	/* extract program name from path. e.g. /path/to/MArCd -> MArCd */
	const char* separator = strrchr(argv[0], '/');
	if ( separator ){
		program_name = separator + 1;
	} else {
		program_name = argv[0];
	}

	struct filter filter;
	if ( filter_from_argv(&argc, argv, &filter) != 0 ){
		return 0; /* error already shown */
	}

	int op, option_index = -1;
	while ( (op = getopt_long(argc, argv, shortopts, longopts, &option_index)) != -1 ){
		switch (op){
		case 0:   /* long opt */
		case '?': /* unknown opt */
			break;

		case '1':
		case '2':
		case '3':
		case '4':
		{
			const unsigned int mask = (7<<FORMAT_LAYER_BIT);
			flags &= ~mask; /* reset all layer bits */
			flags |= (op-'0')<<FORMAT_LAYER_BIT;
			break;
		}

		case 'd': /* --calender */
			flags |= FORMAT_DATE_STR | FORMAT_DATE_UTC;
			break;

		case 'D': /* --localtime */
			flags |= FORMAT_DATE_STR | FORMAT_DATE_LOCALTIME;
			break;

		case 'a': /* --absolute */
			flags &= ~FORMAT_REL_TIMESTAMP;
			break;

		case 'r': /* --relative */
			flags |= FORMAT_REL_TIMESTAMP;
			break;

		case 'H': /* --headers */
			flags |= FORMAT_HEADER;
			break;

		case 'p': /* --packets */
			max_packets = atoi(optarg);
			break;

		case 'c': /* --packets */
			max_matched_packets = atoi(optarg);
			break;

		case 't': /* --timeout */
		{
			int tmp = atoi(optarg);
			timeout.tv_sec  = tmp / 1000;
			timeout.tv_usec = tmp % 1000 * 1000;
		}
		break;

		case 'x': /* --hexdump */
			flags |= FORMAT_HEXDUMP;
			break;

		case 'i': /* --iface */
			iface = optarg;
			break;

		case ARGUMENT_VERSION: /* --version */
			show_version();
			return 0;

		case 'h': /* --help */
			show_usage();
			return 0;

		default:
			fprintf (stderr, "%s: argument '-%c' declared but not handled\n", argv[0], op);
		}
	}

	int ret;

	/* Open stream(s) */
	struct stream* stream;
	if ( (ret=stream_from_getopt(&stream, argv, optind, argc, iface, "-", program_name, 0)) != 0 ) {
		return ret; /* Error already shown */
	}
	const stream_stat_t* stat = stream_get_stat(stream);
	stream_print_info(stream, stderr);

	/* handle C-c */
	signal(SIGINT, handle_sigint);

	/* setup formatter */
	struct format format;
	format_setup(&format, flags);

	uint64_t matched = 0;
	while ( keep_running ) {
		/* A short timeout is used to allow the application to "breathe", i.e
		 * terminate if SIGINT was received. */
		struct timeval tv = timeout;

		/* Read the next packet */
		cap_head* cp;
		ret = stream_read(stream, &cp, NULL, &tv);
		if ( ret == EAGAIN ){
			continue; /* timeout */
		} else if ( ret != 0 ){
			break; /* shutdown or error */
		}

		/* identify connection even if filter doesn't match so id will be
		 * deterministic when changing the filter */
		connection_id(cp);

		if ( filter_match(&filter, cp->payload, cp) ){
			format_pkg(stdout, &format, cp);
			matched++;
		} else {
			format_ignore(stdout, &format, cp);
		}

		if ( max_packets > 0 && stat->matched >= max_packets) {
			/* Read enough pkts lets break. */
			break;
		}
		if ( max_matched_packets > 0 && matched >= max_matched_packets) {
			/* Read enough pkts lets break. */
			break;
		}
	}

	/* if ret == -1 the stream was closed properly (e.g EOF or TCP shutdown)
	 * In addition EINTR should not give any errors because it is implied when the
	 * user presses C-c */
	if ( ret > 0 && ret != EINTR ){
		fprintf(stderr, "stream_read() returned 0x%08X: %s\n", ret, caputils_error_string(ret));
	}

	/* Write stats */
	fprintf(stderr, "%"PRIu64" packets read.\n", stat->read);
	fprintf(stderr, "%"PRIu64" packets matched filter.\n", matched);

	/* Release resources */
	stream_close(stream);
	filter_close(&filter);

	return 0;
}
Пример #13
0
static void
ao_open(struct audio_output *ao)
{
	bool success;
	GError *error = NULL;
	const struct audio_format *filter_audio_format;
	struct audio_format_string af_string;

	assert(!ao->open);
	assert(ao->fail_timer == NULL);
	assert(ao->pipe != NULL);
	assert(ao->chunk == NULL);

	/* enable the device (just in case the last enable has failed) */

	if (!ao_enable(ao))
		/* still no luck */
		return;

	/* open the filter */

	filter_audio_format = filter_open(ao->filter, &ao->in_audio_format,
					  &error);
	if (filter_audio_format == NULL) {
		g_warning("Failed to open filter for \"%s\" [%s]: %s",
			  ao->name, ao->plugin->name, error->message);
		g_error_free(error);

		ao->fail_timer = g_timer_new();
		return;
	}

	ao->out_audio_format = *filter_audio_format;
	audio_format_mask_apply(&ao->out_audio_format,
				&ao->config_audio_format);

	g_mutex_unlock(ao->mutex);
	success = ao_plugin_open(ao->plugin, ao->data,
				 &ao->out_audio_format,
				 &error);
	g_mutex_lock(ao->mutex);

	assert(!ao->open);

	if (!success) {
		g_warning("Failed to open \"%s\" [%s]: %s",
			  ao->name, ao->plugin->name, error->message);
		g_error_free(error);

		filter_close(ao->filter);
		ao->fail_timer = g_timer_new();
		return;
	}

	convert_filter_set(ao->convert_filter, &ao->out_audio_format);

	ao->open = true;

	g_debug("opened plugin=%s name=\"%s\" "
		"audio_format=%s",
		ao->plugin->name, ao->name,
		audio_format_to_string(&ao->out_audio_format, &af_string));

	if (!audio_format_equals(&ao->in_audio_format,
				 &ao->out_audio_format))
		g_debug("converting from %s",
			audio_format_to_string(&ao->in_audio_format,
					       &af_string));
}