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; }
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; }