<commit_before>#include "groove.h"
#include "decode.h"

#include <libavutil/opt.h>
#include <libavutil/channel_layout.h>

#include <SDL/SDL.h>

static double dB_scale;

static double dB_to_float(double dB) {
    return exp(dB * dB_scale);
}

static void deinit_network() {
    avformat_network_deinit();
}

int groove_init() {
    dB_scale = log(10.0) * 0.05;

    srand(time(NULL));

    // register all codecs, demux and protocols
    avcodec_register_all();
    av_register_all();
    avformat_network_init();
    avfilter_register_all();

    atexit(deinit_network);

    if (SDL_Init(SDL_INIT_AUDIO)) {
        av_log(NULL, AV_LOG_ERROR, "Could not initialize SDL - %s\n", SDL_GetError());
        return -1;
    }
    atexit(SDL_Quit);

    av_log_set_level(AV_LOG_QUIET);
    return 0;
}

// decode one audio packet and return its uncompressed size
static int audio_decode_frame(GrooveDecodeContext *decode_ctx, GrooveFile *file) {
    GrooveFilePrivate * f = file->internals;

    AVPacket *pkt = &f->audio_pkt;
    AVCodecContext *dec = f->audio_st->codec;

    AVPacket *pkt_temp = &decode_ctx->audio_pkt_temp;
    *pkt_temp = *pkt;

    // update the audio clock with the pts if we can
    if (pkt->pts != AV_NOPTS_VALUE)
        f->audio_clock = av_q2d(f->audio_st->time_base)*pkt->pts;

    int data_size = 0;
    int len1, got_frame;
    int new_packet = 1;
    AVFrame *frame = decode_ctx->frame;

    // NOTE: the audio packet can contain several frames
    while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {
        avcodec_get_frame_defaults(frame);
        new_packet = 0;

        len1 = avcodec_decode_audio4(dec, frame, &got_frame, pkt_temp);
        if (len1 < 0) {
            // if error, we skip the frame
            pkt_temp->size = 0;
            return -1;
        }

        pkt_temp->data += len1;
        pkt_temp->size -= len1;

        if (!got_frame) {
            // stop sending empty packets if the decoder is finished
            if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)
                return 0;
            continue;
        }

        // push the audio data from decoded frame into the filtergraph
        int err = av_buffersrc_write_frame(decode_ctx->abuffer_ctx, frame);
        if (err < 0) {
            av_strerror(err, decode_ctx->strbuf, sizeof(decode_ctx->strbuf));
            av_log(NULL, AV_LOG_ERROR, "error writing frame to buffersrc: %s\n",
                    decode_ctx->strbuf);
            return -1;
        }

        // pull filtered audio from the filtergraph
        AVFrame *oframe = av_frame_alloc();
        for (;;) {
            int err = av_buffersink_get_frame(decode_ctx->abuffersink_ctx, oframe);
            if (err == AVERROR_EOF || err == AVERROR(EAGAIN))
                break;
            if (err < 0) {
                av_log(NULL, AV_LOG_ERROR, "error reading buffer from buffersink\n");
                return -1;
            }
            data_size += oframe->linesize[0];
            err = decode_ctx->buffer(decode_ctx, oframe);
            if (err < 0)
                return err;
        }

        // if no pts, then estimate it
        if (pkt->pts == AV_NOPTS_VALUE)
            f->audio_clock += data_size / (double)decode_ctx->dest_bytes_per_sec;

        return data_size;
    }
    return data_size;
}

static double get_replaygain_adjustment(GrooveDecodeContext *decode_ctx,
        GrooveFile *file, const char *tag_name)
{
    GrooveTag *tag = groove_file_metadata_get(file, "REPLAYGAIN_TRACK_GAIN", NULL, 0);
    if (tag) {
        const char *tag_value = groove_tag_value(tag);
        double gain_value;
        if (sscanf(tag_value, "%lf", &gain_value) == 1)
            return dB_to_float(gain_value);
        GrooveFilePrivate *f = file->internals;
        av_log(NULL, AV_LOG_WARNING, "track %s lacks replaygain metadata\n", f->ic->filename);
    }
    return decode_ctx->replaygain_default;
}

static int init_filter_graph(GrooveDecodeContext *decode_ctx, GrooveFile *file) {
    GrooveFilePrivate *f = file->internals;

    decode_ctx->last_decoded_file = file;

    // destruct old graph
    avfilter_graph_free(&decode_ctx->filter_graph);

    // create new graph
    decode_ctx->filter_graph = avfilter_graph_alloc();
    if (!decode_ctx->filter_graph) {
        av_log(NULL, AV_LOG_ERROR, "unable to create filter graph: out of memory\n");
        return -1;
    }

    AVFilter *abuffer = avfilter_get_by_name("abuffer");
    AVFilter *volume = avfilter_get_by_name("volume");
    AVFilter *aformat = avfilter_get_by_name("aformat");
    AVFilter *abuffersink = avfilter_get_by_name("abuffersink");<commit_msg>fix always using track replaygain because of typo<commit_after>#include "groove.h"
#include "decode.h"

#include <libavutil/opt.h>
#include <libavutil/channel_layout.h>

#include <SDL/SDL.h>

static double dB_scale;

static double dB_to_float(double dB) {
    return exp(dB * dB_scale);
}

static void deinit_network() {
    avformat_network_deinit();
}

int groove_init() {
    dB_scale = log(10.0) * 0.05;

    srand(time(NULL));

    // register all codecs, demux and protocols
    avcodec_register_all();
    av_register_all();
    avformat_network_init();
    avfilter_register_all();

    atexit(deinit_network);

    if (SDL_Init(SDL_INIT_AUDIO)) {
        av_log(NULL, AV_LOG_ERROR, "Could not initialize SDL - %s\n", SDL_GetError());
        return -1;
    }
    atexit(SDL_Quit);

    av_log_set_level(AV_LOG_QUIET);
    return 0;
}

// decode one audio packet and return its uncompressed size
static int audio_decode_frame(GrooveDecodeContext *decode_ctx, GrooveFile *file) {
    GrooveFilePrivate * f = file->internals;

    AVPacket *pkt = &f->audio_pkt;
    AVCodecContext *dec = f->audio_st->codec;

    AVPacket *pkt_temp = &decode_ctx->audio_pkt_temp;
    *pkt_temp = *pkt;

    // update the audio clock with the pts if we can
    if (pkt->pts != AV_NOPTS_VALUE)
        f->audio_clock = av_q2d(f->audio_st->time_base)*pkt->pts;

    int data_size = 0;
    int len1, got_frame;
    int new_packet = 1;
    AVFrame *frame = decode_ctx->frame;

    // NOTE: the audio packet can contain several frames
    while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {
        avcodec_get_frame_defaults(frame);
        new_packet = 0;

        len1 = avcodec_decode_audio4(dec, frame, &got_frame, pkt_temp);
        if (len1 < 0) {
            // if error, we skip the frame
            pkt_temp->size = 0;
            return -1;
        }

        pkt_temp->data += len1;
        pkt_temp->size -= len1;

        if (!got_frame) {
            // stop sending empty packets if the decoder is finished
            if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)
                return 0;
            continue;
        }

        // push the audio data from decoded frame into the filtergraph
        int err = av_buffersrc_write_frame(decode_ctx->abuffer_ctx, frame);
        if (err < 0) {
            av_strerror(err, decode_ctx->strbuf, sizeof(decode_ctx->strbuf));
            av_log(NULL, AV_LOG_ERROR, "error writing frame to buffersrc: %s\n",
                    decode_ctx->strbuf);
            return -1;
        }

        // pull filtered audio from the filtergraph
        AVFrame *oframe = av_frame_alloc();
        for (;;) {
            int err = av_buffersink_get_frame(decode_ctx->abuffersink_ctx, oframe);
            if (err == AVERROR_EOF || err == AVERROR(EAGAIN))
                break;
            if (err < 0) {
                av_log(NULL, AV_LOG_ERROR, "error reading buffer from buffersink\n");
                return -1;
            }
            data_size += oframe->linesize[0];
            err = decode_ctx->buffer(decode_ctx, oframe);
            if (err < 0)
                return err;
        }

        // if no pts, then estimate it
        if (pkt->pts == AV_NOPTS_VALUE)
            f->audio_clock += data_size / (double)decode_ctx->dest_bytes_per_sec;

        return data_size;
    }
    return data_size;
}

static double get_replaygain_adjustment(GrooveDecodeContext *decode_ctx,
        GrooveFile *file, const char *tag_name)
{
    GrooveTag *tag = groove_file_metadata_get(file, tag_name, NULL, 0);
    if (tag) {
        const char *tag_value = groove_tag_value(tag);
        double gain_value;
        if (sscanf(tag_value, "%lf", &gain_value) == 1)
            return dB_to_float(gain_value);
        GrooveFilePrivate *f = file->internals;
    }
    av_log(NULL, AV_LOG_WARNING, "track %s lacks replaygain metadata\n", f->ic->filename);
    return decode_ctx->replaygain_default;
}

static int init_filter_graph(GrooveDecodeContext *decode_ctx, GrooveFile *file) {
    GrooveFilePrivate *f = file->internals;

    decode_ctx->last_decoded_file = file;

    // destruct old graph
    avfilter_graph_free(&decode_ctx->filter_graph);

    // create new graph
    decode_ctx->filter_graph = avfilter_graph_alloc();
    if (!decode_ctx->filter_graph) {
        av_log(NULL, AV_LOG_ERROR, "unable to create filter graph: out of memory\n");
        return -1;
    }

    AVFilter *abuffer = avfilter_get_by_name("abuffer");
    AVFilter *volume = avfilter_get_by_name("volume");
    AVFilter *aformat = avfilter_get_by_name("aformat");
    AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
{'fraction_non_alphanumeric': 0.11069478642543625, 'fraction_numerical': 0.006851514827106306, 'mean_word_length': 2.590315142198309, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6290389', 'n_tokens_mistral': 3177, 'n_tokens_neox': 3063, 'n_words': 700}