<commit_before>/*
 * Utility functions for libacm.
 *
 * Copyright (c) 2004-2008, <NAME>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <string.h>

#include "libacm.h"

#define ACM_HEADER_LEN	14

/*
 * error strings
 */
static const char *_errlist[] = {
	"No error",
	"ACM error",
	"Cannot open file",
	"Not an ACM file",
	"Read error",
	"Bad format",
	"Corrupt file",
	"Unexcpected EOF",
	"Stream not seekable"
};

const char *acm_strerror(int err)
{
	int nerr = sizeof(_errlist) / sizeof(char *);
	if ((-err) < 0 || (-err) >= nerr)
		return "Unknown error";
	return _errlist[-err];
}

/*
 * File IO using stdio
 */

static int _read_file(void *ptr, int size, int n, void *arg)
{
	FILE *f = (FILE *)arg;
	return fread(ptr, size, n, f);
}
                                                                                
static int _close_file(void *arg)
{
	FILE *f = (FILE *)arg;
	return fclose(f);
}
                                                                                
static int _seek_file(void *arg, int offset, int whence)
{
	FILE *f = (FILE *)arg;
	return fseek(f, offset, whence);
}

static int _get_length_file(void *arg)
{
	FILE *f = (FILE *)arg;
	int res, pos, len = -1;

	pos = ftell(f);
	if (pos < 0)
		return -1;

	res = fseek(f, 0, SEEK_END);
	if (res >= 0) {
		len = ftell(f);
		fseek(f, pos, SEEK_SET);
	}
	return len;
}

int acm_open_file(ACMStream **res, const char *filename)
{
	int err;
	FILE *f;
	acm_io_callbacks io;
	ACMStream *acm;

	if ((f = fopen(filename, "rb")) == NULL)
       		return ACM_ERR_OPEN;

	memset(&io, 0, sizeof(io));
	io.read_func = _read_file;
	io.seek_func = _seek_file;
	io.close_func = _close_file;
	io.get_length_func = _get_length_file;

	if ((err = acm_open_decoder(&acm, f, io)) < 0) {
		fclose(f);
		return err;
	}
	*res = acm;
	return 0;
}

/*
 * utility functions
 */

static unsigned pcm2time(ACMStream *acm, unsigned long long pcm)
{
	return pcm * 1000 / acm->info.rate;
	/* return ((10 * pcm) / acm->info.rate) * 100; */
}

static unsigned time2pcm(ACMStream *acm, unsigned long long time_ms)
{
	return time_ms * acm->info.rate / 1000;
	/* return (time_ms / 100) * (acm->info.rate / 10); */
}

/*
 * info functions
 */

const ACMInfo *acm_info(ACMStream *acm)
{
	return &acm->info;
}

unsigned acm_rate(ACMStream *acm)
{
	return acm->info.rate;
}

unsigned acm_channels(ACMStream *acm)
{
	return acm->info.channels;
}

int acm_seekable(ACMStream *acm)
{
	return acm->data_len > 0;
}

unsigned acm_bitrate(ACMStream *acm)
{
	unsigned long secs8, bitrate = 0;

	if (acm_raw_total(acm) == 0)
		return 13000;

	secs8 = 8 * acm_pcm_total(acm) / acm_rate(acm);
	if (secs8 > 0)
		bitrate = acm_raw_total(acm) / secs8;
	return bitrate;
}

unsigned acm_pcm_tell(ACMStream *acm)
{
	return acm->stream_pos / acm->info.channels;
}

unsigned acm_pcm_total(ACMStream *acm)
{
	return acm->total_values / acm->info.channels;
}

unsigned acm_time_tell(ACMStream *acm)
{
	return pcm2time(acm, acm_pcm_tell(acm));
}

unsigned acm_time_total(ACMStream *acm)
{
	return pcm2time(acm, acm_pcm_total(acm));
}

unsigned acm_raw_tell(ACMStream *acm)
{
	return acm->buf_start_ofs + acm->buf_pos;
}

unsigned acm_raw_total(ACMStream *acm)
{
	return acm->data_len;<commit_msg>previous bitrate fix was broken, fix with clearer code<commit_after>/*
 * Utility functions for libacm.
 *
 * Copyright (c) 2004-2008, <NAME>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <string.h>

#include "libacm.h"

#define ACM_HEADER_LEN	14

/*
 * error strings
 */
static const char *_errlist[] = {
	"No error",
	"ACM error",
	"Cannot open file",
	"Not an ACM file",
	"Read error",
	"Bad format",
	"Corrupt file",
	"Unexcpected EOF",
	"Stream not seekable"
};

const char *acm_strerror(int err)
{
	int nerr = sizeof(_errlist) / sizeof(char *);
	if ((-err) < 0 || (-err) >= nerr)
		return "Unknown error";
	return _errlist[-err];
}

/*
 * File IO using stdio
 */

static int _read_file(void *ptr, int size, int n, void *arg)
{
	FILE *f = (FILE *)arg;
	return fread(ptr, size, n, f);
}
                                                                                
static int _close_file(void *arg)
{
	FILE *f = (FILE *)arg;
	return fclose(f);
}
                                                                                
static int _seek_file(void *arg, int offset, int whence)
{
	FILE *f = (FILE *)arg;
	return fseek(f, offset, whence);
}

static int _get_length_file(void *arg)
{
	FILE *f = (FILE *)arg;
	int res, pos, len = -1;

	pos = ftell(f);
	if (pos < 0)
		return -1;

	res = fseek(f, 0, SEEK_END);
	if (res >= 0) {
		len = ftell(f);
		fseek(f, pos, SEEK_SET);
	}
	return len;
}

int acm_open_file(ACMStream **res, const char *filename)
{
	int err;
	FILE *f;
	acm_io_callbacks io;
	ACMStream *acm;

	if ((f = fopen(filename, "rb")) == NULL)
       		return ACM_ERR_OPEN;

	memset(&io, 0, sizeof(io));
	io.read_func = _read_file;
	io.seek_func = _seek_file;
	io.close_func = _close_file;
	io.get_length_func = _get_length_file;

	if ((err = acm_open_decoder(&acm, f, io)) < 0) {
		fclose(f);
		return err;
	}
	*res = acm;
	return 0;
}

/*
 * utility functions
 */

static unsigned pcm2time(ACMStream *acm, unsigned long long pcm)
{
	return pcm * 1000 / acm->info.rate;
	/* return ((10 * pcm) / acm->info.rate) * 100; */
}

static unsigned time2pcm(ACMStream *acm, unsigned long long time_ms)
{
	return time_ms * acm->info.rate / 1000;
	/* return (time_ms / 100) * (acm->info.rate / 10); */
}

/*
 * info functions
 */

const ACMInfo *acm_info(ACMStream *acm)
{
	return &acm->info;
}

unsigned acm_rate(ACMStream *acm)
{
	return acm->info.rate;
}

unsigned acm_channels(ACMStream *acm)
{
	return acm->info.channels;
}

int acm_seekable(ACMStream *acm)
{
	return acm->data_len > 0;
}

unsigned acm_bitrate(ACMStream *acm)
{
	unsigned long long bits, time, bitrate = 0;

	if (acm_raw_total(acm) == 0)
		return 13000;

	time = acm_time_total(acm);
	if (time > 0) {
		bits = 8 * acm_raw_total(acm);
		bitrate = 1000 * bits / time;
	}
	return bitrate;
}

unsigned acm_pcm_tell(ACMStream *acm)
{
	return acm->stream_pos / acm->info.channels;
}

unsigned acm_pcm_total(ACMStream *acm)
{
	return acm->total_values / acm->info.channels;
}

unsigned acm_time_tell(ACMStream *acm)
{
	return pcm2time(acm, acm_pcm_tell(acm));
}

unsigned acm_time_total(ACMStream *acm)
{
	return pcm2time(acm, acm_pcm_total(acm));
}

unsigned acm_raw_tell(ACMStream *acm)
{
	return acm->buf_start_ofs + acm->buf_pos;
}

unsigned acm_raw_total(ACMStream *acm)
{
	return acm->data_len;
{'fraction_non_alphanumeric': 0.12649700598802396, 'fraction_numerical': 0.013722554890219561, 'mean_word_length': 3.3288336933045355, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '701076', 'n_tokens_mistral': 3196, 'n_tokens_neox': 2945, 'n_words': 869}