Пример #1
0
int calculate_track_dr(const char *filename, struct track_info *t, int number) {
	struct stream_context sc;
	struct dr_meter meter;
	int err;

	meter_init(&meter);

	err = sc_open(&sc, filename);
	if (err < 0) { return print_av_error("sc_open", err); }

	if (debug) {
		printf("DEBUG: Codec: %s\n", avcodec_get_name(sc_get_codec_id(&sc)));
	}


	int stream_index = err = av_find_best_stream(
		sc.format_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
	if (err < 0) { print_av_error("av_find_best_stream", err); goto cleanup; }

	err = sc_start_stream(&sc, stream_index);
	if (err < 0) { print_av_error("sc_start_stream", err); goto cleanup; }

	t->artist = strdup(sc_get_metadata(&sc, "artist"));
	t->album = strdup(sc_get_metadata(&sc, "album"));
        t->tracknumber = strdup(sc_get_metadata(&sc, "track"));
	t->title = strdup(sc_get_metadata(&sc, "title"));

	AVCodecParameters *codecpar = sc_get_codec_parameters(&sc);
	err = meter_start(&meter, codecpar->channels, codecpar->sample_rate, codecpar->format);
	if (err) { goto cleanup; }

	size_t fragment = 0;
	int throbbler_stage = 0;
	while (!sc_eof(&sc)) {
		err = sc_get_next_frame(&sc);
		if (err < 0) {
			print_av_error("sc_get_next_frame", err);
			goto cleanup;
		}

		err = meter_feed(&meter, sc_get_buf(&sc), sc_get_samples(&sc));
		if (err) { goto cleanup; }

		if (fragment < meter.fragment) {
			fragment = meter.fragment;
			if ((throbbler_stage % 4) == 0) {
				fprintf(stderr, "\033[1K\033[1G"
						"Analyzing track %i... "
						"%c  %2zu:%02zu ",
						number,
						throbbler[throbbler_stage / 4],
						(fragment * 3) / 60,
						(fragment * 3) % 60);
			}
			throbbler_stage += 1;
			throbbler_stage %= 16;
		}
	}

	fprintf(stderr, "\033[1K\033[1G");
	meter_finish(&meter, t);

cleanup:
	meter_free(&meter);
	sc_close(&sc);

	if (err < 0) {
		return err;
	}

	return 0;
}
Пример #2
0
int do_calculate_dr(const char *filename) {
	struct stream_context sc;
	struct dr_meter meter;
	int err;

	meter_init(&meter);

	err = sc_open(&sc, filename);
	if (err < 0) { return print_av_error("sc_open", err); }

	int stream_index = err = av_find_best_stream(
		sc.format_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
	if (err < 0) { print_av_error("av_find_best_stream", err); goto cleanup; }

	err = sc_start_stream(&sc, stream_index);
	if (err < 0) { print_av_error("sc_start_stream", err); goto cleanup; }

	// Print out the stream info
	AVCodecContext *codec_ctx = sc_get_codec(&sc);
	char codecinfobuf[256];
	avcodec_string(codecinfobuf, sizeof(codecinfobuf), codec_ctx, 0);
	fprintf(stderr, "%.256s\n", codecinfobuf);

	err = meter_start(&meter, codec_ctx->channels, codec_ctx->sample_rate, codec_ctx->sample_fmt);
	if (err) { goto cleanup; }

	fprintf(stderr, "Collecting fragments information...\n");

	size_t fragment = 0;
	int throbbler_stage = 0;
	while (!sc_eof(&sc)) {
		err = sc_get_next_frame(&sc);
		if (err < 0) {
			print_av_error("sc_get_next_frame", err);
			goto cleanup;
		}

		err = meter_feed(&meter, sc.buf, sc.buf_size);
		if (err) { goto cleanup; }

		if (fragment < meter.fragment) {
			fragment = meter.fragment;
			if ((throbbler_stage % 4) == 0) {
				fprintf(stderr, "\033[1K\033[1G %c  %2i:%02i ",
						throbbler[throbbler_stage / 4],
						(fragment * 3) / 60,
						(fragment * 3) % 60);
			}
			throbbler_stage += 1;
			throbbler_stage %= 16;
		}
	}

	meter_finish(&meter);

cleanup:
	meter_free(&meter);
	sc_close(&sc);

	if (err < 0) {
		return err;
	}

	return 0;
}