Commit 2bd2be83 authored by Unicorn369's avatar Unicorn369 Committed by fallenstardust

add mpg123

parent 5987d94e
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libmpg123
#LOCAL_LDLIBS := -llog
LOCAL_C_INCLUDES := $(LOCAL_PATH)/android \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/src \
$(LOCAL_PATH)/src/compat \
$(LOCAL_PATH)/src/libmpg123
DECODER_CFLAGS_NEON := -DOPT_NEON -DREAL_IS_FLOAT
DECODER_SRC_NEON := \
src/libmpg123/stringbuf.c \
src/libmpg123/icy.c \
src/libmpg123/icy2utf8.c \
src/libmpg123/ntom.c \
src/libmpg123/synth.c \
src/libmpg123/synth_8bit.c \
src/libmpg123/layer1.c \
src/libmpg123/layer2.c \
src/libmpg123/layer3.c \
src/libmpg123/dct36_neon.S \
src/libmpg123/dct64_neon_float.S \
src/libmpg123/synth_neon_float.S \
src/libmpg123/synth_neon_s32.S \
src/libmpg123/synth_stereo_neon_float.S \
src/libmpg123/synth_stereo_neon_s32.S \
src/libmpg123/dct64_neon.S \
src/libmpg123/synth_neon.S \
src/libmpg123/synth_stereo_neon.S \
src/libmpg123/synth_s32.c \
src/libmpg123/synth_real.c \
src/libmpg123/feature.c \
DECODER_CFLAGS_NEON64 := -DOPT_MULTI -DOPT_GENERIC -DOPT_GENERIC_DITHER -DOPT_NEON64 -DREAL_IS_FLOAT
DECODER_SRC_NEON64 := \
src/libmpg123/stringbuf.c \
src/libmpg123/icy.c \
src/libmpg123/icy2utf8.c \
src/libmpg123/ntom.c \
src/libmpg123/synth.c \
src/libmpg123/synth_8bit.c \
src/libmpg123/layer1.c \
src/libmpg123/layer2.c \
src/libmpg123/layer3.c \
src/libmpg123/dct36_neon64.S \
src/libmpg123/dct64_neon64_float.S \
src/libmpg123/synth_neon64_float.S \
src/libmpg123/synth_neon64_s32.S \
src/libmpg123/synth_stereo_neon64_float.S \
src/libmpg123/synth_stereo_neon64_s32.S \
src/libmpg123/dct64_neon64.S \
src/libmpg123/synth_neon64.S \
src/libmpg123/synth_stereo_neon64.S \
src/libmpg123/synth_s32.c \
src/libmpg123/synth_real.c \
src/libmpg123/dither.c \
src/libmpg123/getcpuflags_arm.c \
src/libmpg123/check_neon.S \
src/libmpg123/feature.c \
# Unfortunately the assembly isn't relocatable so doesn't work on modern
# Android devices
DECODER_CFLAGS_X86 := -DOPT_GENERIC -DREAL_IS_FLOAT
DECODER_CFLAGS_X86_ASM := -DOPT_MULTI -DOPT_GENERIC -DOPT_GENERIC_DITHER -DOPT_I386 -DOPT_I586 -DOPT_I586_DITHER -DOPT_MMX -DOPT_3DNOW -DOPT_3DNOW_VINTAGE -DOPT_3DNOWEXT -DOPT_3DNOWEXT_VINTAGE -DOPT_SSE -DOPT_SSE_VINTAGE -DREAL_IS_FLOAT
DECODER_SRC_X86 := \
src/libmpg123/feature.c \
src/libmpg123/icy2utf8.c \
src/libmpg123/icy.c \
src/libmpg123/layer1.c \
src/libmpg123/layer2.c \
src/libmpg123/layer3.c \
src/libmpg123/ntom.c \
src/libmpg123/stringbuf.c \
src/libmpg123/synth_8bit.c \
src/libmpg123/synth.c \
src/libmpg123/synth_real.c \
src/libmpg123/synth_s32.c \
src/libmpg123/dither.c \
DECODER_SRC_X86_ASM := \
src/libmpg123/stringbuf.c \
src/libmpg123/icy.c \
src/libmpg123/icy2utf8.c \
src/libmpg123/ntom.c \
src/libmpg123/synth.c \
src/libmpg123/synth_8bit.c \
src/libmpg123/layer1.c \
src/libmpg123/layer2.c \
src/libmpg123/layer3.c \
src/libmpg123/synth_s32.c \
src/libmpg123/synth_real.c \
src/libmpg123/dct64_i386.c \
src/libmpg123/synth_i586.S \
src/libmpg123/synth_i586_dither.S \
src/libmpg123/dct64_mmx.S \
src/libmpg123/tabinit_mmx.S \
src/libmpg123/synth_mmx.S \
src/libmpg123/synth_3dnow.S \
src/libmpg123/dct64_3dnow.S \
src/libmpg123/equalizer_3dnow.S \
src/libmpg123/dct36_3dnow.S \
src/libmpg123/dct64_3dnowext.S \
src/libmpg123/synth_3dnowext.S \
src/libmpg123/dct36_3dnowext.S \
src/libmpg123/dct64_sse_float.S \
src/libmpg123/synth_sse_float.S \
src/libmpg123/synth_stereo_sse_float.S \
src/libmpg123/synth_sse_s32.S \
src/libmpg123/synth_stereo_sse_s32.S \
src/libmpg123/dct36_sse.S \
src/libmpg123/dct64_sse.S \
src/libmpg123/synth_sse.S \
src/libmpg123/getcpuflags.S \
src/libmpg123/dither.c \
src/libmpg123/feature.c \
DECODER_CFLAGS_X64 := -DOPT_MULTI -DOPT_X86_64 -DOPT_GENERIC -DOPT_GENERIC_DITHER -DREAL_IS_FLOAT -DOPT_AVX
DECODER_SRC_X64 := \
src/libmpg123/stringbuf.c \
src/libmpg123/icy.c \
src/libmpg123/icy.h \
src/libmpg123/icy2utf8.c \
src/libmpg123/icy2utf8.h \
src/libmpg123/ntom.c \
src/libmpg123/synth.c \
src/libmpg123/synth.h \
src/libmpg123/synth_8bit.c \
src/libmpg123/synth_8bit.h \
src/libmpg123/layer1.c \
src/libmpg123/layer2.c \
src/libmpg123/layer3.c \
src/libmpg123/synth_s32.c \
src/libmpg123/synth_real.c \
src/libmpg123/dct36_x86_64.S \
src/libmpg123/dct64_x86_64_float.S \
src/libmpg123/synth_x86_64_float.S \
src/libmpg123/synth_x86_64_s32.S \
src/libmpg123/synth_stereo_x86_64_float.S \
src/libmpg123/synth_stereo_x86_64_s32.S \
src/libmpg123/synth_x86_64.S \
src/libmpg123/dct64_x86_64.S \
src/libmpg123/synth_stereo_x86_64.S \
src/libmpg123/dither.c \
src/libmpg123/dither.h \
src/libmpg123/getcpuflags_x86_64.S \
src/libmpg123/dct36_avx.S \
src/libmpg123/dct64_avx_float.S \
src/libmpg123/synth_stereo_avx_float.S \
src/libmpg123/synth_stereo_avx_s32.S \
src/libmpg123/dct64_avx.S \
src/libmpg123/synth_stereo_avx.S \
src/libmpg123/feature.c
DECODER_CFLAGS_MIPS := -DOPT_GENERIC -DREAL_IS_FLOAT
DECODER_SRC_MIPS := \
src/libmpg123/stringbuf.c \
src/libmpg123/icy.c \
src/libmpg123/icy2utf8.c \
src/libmpg123/ntom.c \
src/libmpg123/synth.c \
src/libmpg123/synth_8bit.c \
src/libmpg123/layer1.c \
src/libmpg123/layer2.c \
src/libmpg123/layer3.c \
src/libmpg123/synth_s32.c \
src/libmpg123/synth_real.c \
src/libmpg123/feature.c
ifeq ($(TARGET_ARCH_ABI),armeabi)
DECODER_CFLAGS := $(DECODER_CFLAGS_NEON)
DECODER_SRC := $(DECODER_SRC_NEON)
endif
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
DECODER_CFLAGS := $(DECODER_CFLAGS_NEON)
DECODER_SRC := $(DECODER_SRC_NEON)
endif
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
DECODER_CFLAGS := $(DECODER_CFLAGS_NEON64)
DECODER_SRC := $(DECODER_SRC_NEON64)
endif
ifeq ($(TARGET_ARCH_ABI),x86)
DECODER_CFLAGS := $(DECODER_CFLAGS_X86)
DECODER_SRC := $(DECODER_SRC_X86)
endif
ifeq ($(TARGET_ARCH_ABI),x86_64)
DECODER_CFLAGS := $(DECODER_CFLAGS_X64)
DECODER_SRC := $(DECODER_SRC_X64)
endif
ifeq ($(TARGET_ARCH_ABI),mips)
DECODER_CFLAGS := $(DECODER_CFLAGS_MIPS)
DECODER_SRC := $(DECODER_SRC_MIPS)
endif
ifeq ($(TARGET_ARCH_ABI),mips64)
DECODER_CFLAGS := $(DECODER_CFLAGS_MIPS)
DECODER_SRC := $(DECODER_SRC_MIPS)
endif
LOCAL_CFLAGS := $(DECODER_CFLAGS)
LOCAL_SRC_FILES := \
src/libmpg123/parse.c \
src/libmpg123/frame.c \
src/libmpg123/format.c \
src/libmpg123/dct64.c \
src/libmpg123/equalizer.c \
src/libmpg123/id3.c \
src/libmpg123/optimize.c \
src/libmpg123/readers.c \
src/libmpg123/tabinit.c \
src/libmpg123/libmpg123.c \
src/libmpg123/index.c \
src/compat/compat_str.c \
src/compat/compat.c \
$(DECODER_SRC)
LOCAL_EXPORT_C_INCLUDES += $(LOCAL_C_INCLUDES)
include $(BUILD_STATIC_LIBRARY)
This diff is collapsed.
/*
libmpg123: MPEG Audio Decoder library
separate header just for audio format definitions not tied to
library code
copyright 1995-2015 by the mpg123 project
free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
*/
#ifndef MPG123_ENC_H
#define MPG123_ENC_H
/** \file fmt123.h Audio format definitions. */
/** \defgroup mpg123_enc mpg123 PCM sample encodings
* These are definitions for audio formats used by libmpg123 and
* libout123.
*
* @{
*/
/** An enum over all sample types possibly known to mpg123.
* The values are designed as bit flags to allow bitmasking for encoding
* families.
* This is also why the enum is not used as type for actual encoding variables,
* plain integers (at least 16 bit, 15 bit being used) cover the possible
* combinations of these flags.
*
* Note that (your build of) libmpg123 does not necessarily support all these.
* Usually, you can expect the 8bit encodings and signed 16 bit.
* Also 32bit float will be usual beginning with mpg123-1.7.0 .
* What you should bear in mind is that (SSE, etc) optimized routines may be
* absent for some formats. We do have SSE for 16, 32 bit and float, though.
* 24 bit integer is done via postprocessing of 32 bit output -- just cutting
* the last byte, no rounding, even. If you want better, do it yourself.
*
* All formats are in native byte order. If you need different endinaness, you
* can simply postprocess the output buffers (libmpg123 wouldn't do anything
* else). The macro MPG123_SAMPLESIZE() can be helpful there.
*/
enum mpg123_enc_enum
{
/* 0000 0000 0000 1111 Some 8 bit integer encoding. */
MPG123_ENC_8 = 0x00f
/* 0000 0000 0100 0000 Some 16 bit integer encoding. */
, MPG123_ENC_16 = 0x040
/* 0100 0000 0000 0000 Some 24 bit integer encoding. */
, MPG123_ENC_24 = 0x4000
/* 0000 0001 0000 0000 Some 32 bit integer encoding. */
, MPG123_ENC_32 = 0x100
/* 0000 0000 1000 0000 Some signed integer encoding. */
, MPG123_ENC_SIGNED = 0x080
/* 0000 1110 0000 0000 Some float encoding. */
, MPG123_ENC_FLOAT = 0xe00
/* 0000 0000 1101 0000 signed 16 bit */
, MPG123_ENC_SIGNED_16 = (MPG123_ENC_16|MPG123_ENC_SIGNED|0x10)
/* 0000 0000 0110 0000 unsigned 16 bit */
, MPG123_ENC_UNSIGNED_16 = (MPG123_ENC_16|0x20)
/* 0000 0000 0000 0001 unsigned 8 bit */
, MPG123_ENC_UNSIGNED_8 = 0x01
/* 0000 0000 1000 0010 signed 8 bit */
, MPG123_ENC_SIGNED_8 = (MPG123_ENC_SIGNED|0x02)
/* 0000 0000 0000 0100 ulaw 8 bit */
, MPG123_ENC_ULAW_8 = 0x04
/* 0000 0000 0000 1000 alaw 8 bit */
, MPG123_ENC_ALAW_8 = 0x08
/* 0001 0001 1000 0000 signed 32 bit */
, MPG123_ENC_SIGNED_32 = MPG123_ENC_32|MPG123_ENC_SIGNED|0x1000
/* 0010 0001 0000 0000 unsigned 32 bit */
, MPG123_ENC_UNSIGNED_32 = MPG123_ENC_32|0x2000
/* 0101 0000 1000 0000 signed 24 bit */
, MPG123_ENC_SIGNED_24 = MPG123_ENC_24|MPG123_ENC_SIGNED|0x1000
/* 0110 0000 0000 0000 unsigned 24 bit */
, MPG123_ENC_UNSIGNED_24 = MPG123_ENC_24|0x2000
/* 0000 0010 0000 0000 32bit float */
, MPG123_ENC_FLOAT_32 = 0x200
/* 0000 0100 0000 0000 64bit float */
, MPG123_ENC_FLOAT_64 = 0x400
/* Any possibly known encoding from the list above. */
, MPG123_ENC_ANY = ( MPG123_ENC_SIGNED_16 | MPG123_ENC_UNSIGNED_16
| MPG123_ENC_UNSIGNED_8 | MPG123_ENC_SIGNED_8
| MPG123_ENC_ULAW_8 | MPG123_ENC_ALAW_8
| MPG123_ENC_SIGNED_32 | MPG123_ENC_UNSIGNED_32
| MPG123_ENC_SIGNED_24 | MPG123_ENC_UNSIGNED_24
| MPG123_ENC_FLOAT_32 | MPG123_ENC_FLOAT_64 )
};
/** Get size of one PCM sample with given encoding.
* This is included both in libmpg123 and libout123. Both offer
* an API function to provide the macro results from library
* compile-time, not that of you application. This most likely
* does not matter as I do not expect any fresh PCM sample
* encoding to appear. But who knows? Perhaps the encoding type
* will be abused for funny things in future, not even plain PCM.
* And, by the way: Thomas really likes the ?: operator.
* \param enc the encoding (mpg123_enc_enum value)
* \return size of one sample in bytes
*/
#define MPG123_SAMPLESIZE(enc) ( \
(enc) & MPG123_ENC_8 \
? 1 \
: ( (enc) & MPG123_ENC_16 \
? 2 \
: ( (enc) & MPG123_ENC_24 \
? 3 \
: ( ( (enc) & MPG123_ENC_32 \
|| (enc) == MPG123_ENC_FLOAT_32 ) \
? 4 \
: ( (enc) == MPG123_ENC_FLOAT_64 \
? 8 \
: 0 \
) ) ) ) )
/** Structure defining an audio format.
* Providing the members as individual function arguments to define a certain
* output format is easy enough. This struct makes is more comfortable to deal
* with a list of formats.
* Negative values for the members might be used to communicate use of default
* values.
*/
struct mpg123_fmt
{
long rate; /**< sampling rate in Hz */
int channels; /**< channel count */
/** encoding code, can be single value or bitwise or of members of
* mpg123_enc_enum */
int encoding;
};
/* @} */
#endif
This diff is collapsed.
/*
audio: audio output interface
copyright ?-2016 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
#include <errno.h>
#include "mpg123app.h"
#include "audio.h"
#include "out123.h"
#include "common.h"
#include "sysutil.h"
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#include "debug.h"
mpg123_string* audio_enclist(void)
{
int i;
mpg123_string *list;
size_t enc_count = 0;
const int *enc_codes = NULL;
/* Only the encodings supported by libmpg123 build
Those returned by out123_enc_list() are a superset. */
mpg123_encodings(&enc_codes, &enc_count);
if((list = malloc(sizeof(*list))))
mpg123_init_string(list);
/* Further calls to mpg123 string lib are hardened against NULL. */
for(i=0;i<enc_count;++i)
{
if(i>0)
mpg123_add_string(list, " ");
mpg123_add_string(list, out123_enc_name(enc_codes[i]));
}
return list;
}
static void capline(mpg123_handle *mh, long rate)
{
int enci;
const int *encs;
size_t num_encs;
mpg123_encodings(&encs, &num_encs);
fprintf(stderr," %5ld |", pitch_rate(rate));
for(enci=0; enci<num_encs; ++enci)
{
switch(mpg123_format_support(mh, rate, encs[enci]))
{
case MPG123_MONO: fprintf(stderr, " M |"); break;
case MPG123_STEREO: fprintf(stderr, " S |"); break;
case MPG123_MONO|MPG123_STEREO: fprintf(stderr, " M/S |"); break;
default: fprintf(stderr, " |");
}
}
fprintf(stderr, "\n");
}
void print_capabilities(out123_handle *ao, mpg123_handle *mh)
{
int r,e;
const long *rates;
size_t num_rates;
const int *encs;
size_t num_encs;
char *name;
char *dev;
out123_driver_info(ao, &name, &dev);
mpg123_rates(&rates, &num_rates);
mpg123_encodings(&encs, &num_encs);
fprintf(stderr,"\nAudio driver: %s\nAudio device: %s\nAudio capabilities:\n(matrix of [S]tereo or [M]ono support for sample format and rate in Hz)\n |", name, dev);
for(e=0;e<num_encs;e++)
{
const char *encname = out123_enc_name(encs[e]);
fprintf(stderr," %5s |", encname ? encname : "???");
}
fprintf(stderr,"\n ------|");
for(e=0;e<num_encs;e++) fprintf(stderr,"-------|");
fprintf(stderr, "\n");
for(r=0; r<num_rates; ++r) capline(mh, rates[r]);
if(param.force_rate) capline(mh, param.force_rate);
fprintf(stderr,"\n");
}
/* Quick-shot paired table setup with remembering search in it.
this is for storing pairs of output sampling rate and decoding
sampling rate. */
struct ratepair { long a; long b; };
long brate(struct ratepair *table, long arate, int count, int *last)
{
int i = 0;
int j;
for(j=0; j<2; ++j)
{
i = i ? 0 : *last;
for(; i<count; ++i) if(table[i].a == arate)
{
*last = i;
return table[i].b;
}
}
return 0;
}
/* This uses the currently opened audio device, queries its caps.
In case of buffered playback, this works _once_ by querying the buffer for the caps before entering the main loop. */
void audio_capabilities(out123_handle *ao, mpg123_handle *mh)
{
int force_fmt = 0;
size_t ri;
/* Pitching introduces a difference between decoder rate and playback rate. */
long decode_rate;
const long *rates;
long *outrates;
struct ratepair *unpitch;
struct mpg123_fmt *outfmts = NULL;
int fmtcount;
size_t num_rates, rlimit;
debug("audio_capabilities");
mpg123_rates(&rates, &num_rates);
mpg123_format_none(mh); /* Start with nothing. */
if(param.force_encoding != NULL)
{
if(!param.quiet)
fprintf(stderr, "Note: forcing output encoding %s\n", param.force_encoding);
force_fmt = out123_enc_byname(param.force_encoding);
if(!force_fmt)
{
error1("Failed to find an encoding to match requested \"%s\"!\n"
, param.force_encoding);
return; /* No capabilities at all... */
}
else if(param.verbose > 2)
fprintf(stderr, "Note: forcing encoding code 0x%x (%s)\n"
, force_fmt, out123_enc_name(force_fmt));
}
/* Lots of preparation of rate lists. */
rlimit = param.force_rate > 0 ? num_rates+1 : num_rates;
outrates = malloc(sizeof(*rates)*rlimit);
unpitch = malloc(sizeof(*unpitch)*rlimit);
if(!outrates || !unpitch)
{
if(!param.quiet)
error("DOOM");
return;
}
for(ri = 0; ri<rlimit; ri++)
{
decode_rate = ri < num_rates ? rates[ri] : param.force_rate;
outrates[ri] = pitch_rate(decode_rate);
unpitch[ri].a = outrates[ri];
unpitch[ri].b = decode_rate;
}
/* Actually query formats possible with given rates. */
fmtcount = out123_formats(ao, outrates, rlimit, 1, 2, &outfmts);
free(outrates);
if(fmtcount > 0)
{
int fi;
int unpitch_i = 0;
if(param.verbose > 1 && outfmts[0].encoding > 0)
{
const char *encname = out123_enc_name(outfmts[0].encoding);
fprintf(stderr, "Note: default format %li Hz, %i channels, %s\n"
, outfmts[0].rate, outfmts[0].channels
, encname ? encname : "???" );
}
for(fi=1; fi<fmtcount; ++fi)
{
int fmts = outfmts[fi].encoding;
if(param.verbose > 2)
fprintf( stderr
, "Note: output support for %li Hz, %i channels: 0x%x\n"
, outfmts[fi].rate, outfmts[fi].channels, outfmts[fi].encoding );
if(force_fmt)
{ /* Filter for forced encoding. */
if((fmts & force_fmt) == force_fmt)
fmts = force_fmt;
else /* Nothing else! */
fmts = 0;
}
mpg123_format( mh
, brate(unpitch, outfmts[fi].rate, rlimit, &unpitch_i)
, outfmts[fi].channels, fmts );
}
}
free(outfmts);
free(unpitch);
if(param.verbose > 1) print_capabilities(ao, mh);
}
int set_pitch(mpg123_handle *fr, out123_handle *ao, double new_pitch)
{
double old_pitch = param.pitch;
long rate;
int channels, format;
int smode = 0;
/* Be safe, check support. */
if(mpg123_getformat(fr, &rate, &channels, &format) != MPG123_OK)
{
/* We might just not have a track handy. */
error("There is no current audio format, cannot apply pitch. This might get fixed in future.");
return 0;
}
param.pitch = new_pitch;
if(param.pitch < -0.99) param.pitch = -0.99;
if(channels == 1) smode = MPG123_MONO;
if(channels == 2) smode = MPG123_STEREO;
out123_stop(ao);
/* Remember: This takes param.pitch into account. */
audio_capabilities(ao, fr);
if(!(mpg123_format_support(fr, rate, format) & smode))
{
/* Note: When using --pitch command line parameter, you can go higher
because a lower decoder sample rate is automagically chosen.
Here, we'd need to switch decoder rate during track... good? */
error("Reached a hardware limit there with pitch!");
param.pitch = old_pitch;
audio_capabilities(ao, fr);
}
return out123_start(ao, pitch_rate(rate), channels, format);
}
/*
audio: audio output interface
This is what is left after separating out libout123.
copyright ?-2015 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
/*
* Audio 'LIB' defines
*/
#ifndef _MPG123_AUDIO_H_
#define _MPG123_AUDIO_H_
#include "compat.h"
#include "mpg123.h"
#include "out123.h"
#define pitch_rate(rate) (param.pitch == 0 ? (rate) : (long) ((param.pitch+1.0)*(rate)))
mpg123_string* audio_enclist(void);
void audio_capabilities(out123_handle *ao, mpg123_handle *mh);
void print_capabilities(out123_handle *ao, mpg123_handle *mh);
/*
Twiddle audio output rate to yield speedup/down (pitch) effect.
The actually achieved pitch value is stored in param.pitch.
Returns 1 if pitch setting succeeded, 0 otherwise.
*/
int set_pitch(mpg123_handle *fr, out123_handle *ao, double new_pitch);
#endif
This diff is collapsed.
/*
common: anything can happen here... frame reading, output, messages
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp
*/
#ifndef _MPG123_COMMON_H_
#define _MPG123_COMMON_H_
#include "mpg123app.h"
#include "out123.h"
extern int stopped;
extern int paused;
/* Return non-zero if full terminal fun is desired/possible. */
int term_have_fun(int fd);
/* Return width of terminal associated with given descriptor,
-1 when there is none. */
int term_width(int fd);
void print_header(mpg123_handle *);
void print_header_compact(mpg123_handle *);
void print_stat(mpg123_handle *fr, long offset, out123_handle *ao, int draw_bar);
void print_buf(const char* prefix, out123_handle *ao);
void clear_stat();
/* for control_generic */
extern const char* remote_header_help;
void print_remote_header(mpg123_handle *mh);
void generic_sendmsg (const char *fmt, ...);
extern const char* rva_name[3];
#endif
This diff is collapsed.
/*
compat: Some compatibility functions and header inclusions.
Basic standard C stuff, that may barely be above/around C89.
The mpg123 code is determined to keep it's legacy. A legacy of old, old UNIX.
It is envisioned to include this compat header instead of any of the "standard" headers, to catch compatibility issues.
So, don't include stdlib.h or string.h ... include compat.h.
copyright 2007-8 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis
*/
#ifndef MPG123_COMPAT_H
#define MPG123_COMPAT_H
#include "config.h"
#include "intsym.h"
/* For --nagging compilation with -std=c89, we need
to disable the inline keyword. */
#ifdef PLAIN_C89
#ifndef inline
#define inline
#endif
#endif
#include <errno.h>
#ifdef HAVE_STDLIB_H
/* realloc, size_t */
#include <stdlib.h>
#endif
#include <stdio.h>
#include <math.h>
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#else
#ifdef HAVE_SYS_SIGNAL_H
#include <sys/signal.h>
#endif
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
/* Types, types, types. */
/* Do we actually need these two in addition to sys/types.h? As replacement? */
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
/* We want SIZE_MAX, etc. */
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)-1)
#endif
#ifndef ULONG_MAX
#define ULONG_MAX ((unsigned long)-1)
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#ifdef OS2
#include <float.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
/* For select(), I need select.h according to POSIX 2001, else: sys/time.h sys/types.h unistd.h */
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
/* compat_open makes little sense without */
#include <fcntl.h>
/* To parse big numbers... */
#ifdef HAVE_ATOLL
#define atobigint atoll
#else
#define atobigint atol
#endif
typedef unsigned char byte;
#if defined(_MSC_VER) && !defined(MPG123_DEF_SSIZE_T)
#define MPG123_DEF_SSIZE_T
#include <stddef.h>
typedef ptrdiff_t ssize_t;
#endif
/* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */
void *safe_realloc(void *ptr, size_t size);
#ifndef HAVE_STRERROR
const char *strerror(int errnum);
#endif
/* Roll our own strdup() that does not depend on libc feature test macros
and returns NULL on NULL input instead of crashing. */
char* compat_strdup(const char *s);
/* If we have the size checks enabled, try to derive some sane printfs.
Simple start: Use max integer type and format if long is not big enough.
I am hesitating to use %ll without making sure that it's there... */
#if !(defined PLAIN_C89) && (defined SIZEOF_OFF_T) && (SIZEOF_OFF_T > SIZEOF_LONG) && (defined PRIiMAX)
# define OFF_P PRIiMAX
typedef intmax_t off_p;
#else
# define OFF_P "li"
typedef long off_p;
#endif
#if !(defined PLAIN_C89) && (defined SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > SIZEOF_LONG) && (defined PRIuMAX)
# define SIZE_P PRIuMAX
typedef uintmax_t size_p;
#else
# define SIZE_P "lu"
typedef unsigned long size_p;
#endif
#if !(defined PLAIN_C89) && (defined SIZEOF_SSIZE_T) && (SIZEOF_SSIZE_T > SIZEOF_LONG) && (defined PRIiMAX)
# define SSIZE_P PRIuMAX
typedef intmax_t ssize_p;
#else
# define SSIZE_P "li"
typedef long ssize_p;
#endif
/* Get an environment variable, possibly converted to UTF-8 from wide string.
The return value is a copy that you shall free. */
char *compat_getenv(const char* name);
/**
* Opening a file handle can be different.
* This function here is defined to take a path in native encoding (ISO8859 / UTF-8 / ...), or, when MS Windows Unicode support is enabled, an UTF-8 string that will be converted back to native UCS-2 (wide character) before calling the system's open function.
* @param[in] wptr Pointer to wide string.
* @param[in] mbptr Pointer to multibyte string.
* @return file descriptor (>=0) or error code.
*/
int compat_open(const char *filename, int flags);
FILE* compat_fopen(const char *filename, const char *mode);
/**
* Also fdopen to avoid having to define POSIX macros in various source files.
*/
FILE* compat_fdopen(int fd, const char *mode);
/**
* Closing a file handle can be platform specific.
* This function takes a file descriptor that is to be closed.
* @param[in] infd File descriptor to be closed.
* @return 0 if the file was successfully closed. A return value of -1 indicates an error.
*/
int compat_close(int infd);
int compat_fclose(FILE* stream);
/* Those do make sense in a separate file, but I chose to include them in compat.c because that's the one source whose object is shared between mpg123 and libmpg123 -- and both need the functionality internally. */
#ifdef WANT_WIN32_UNICODE
/**
* win32_uni2mbc
* Converts a null terminated UCS-2 string to a multibyte (UTF-8) equivalent.
* Caller is supposed to free allocated buffer.
* @param[in] wptr Pointer to wide string.
* @param[out] mbptr Pointer to multibyte string.
* @param[out] buflen Optional parameter for length of allocated buffer.
* @return status of WideCharToMultiByte conversion.
*
* WideCharToMultiByte - http://msdn.microsoft.com/en-us/library/dd374130(VS.85).aspx
*/
int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen);
/**
* win32_mbc2uni
* Converts a null terminated UTF-8 string to a UCS-2 equivalent.
* Caller is supposed to free allocated buffer.
* @param[out] mbptr Pointer to multibyte string.
* @param[in] wptr Pointer to wide string.
* @param[out] buflen Optional parameter for length of allocated buffer.
* @return status of WideCharToMultiByte conversion.
*
* MultiByteToWideChar - http://msdn.microsoft.com/en-us/library/dd319072(VS.85).aspx
*/
int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen);
#endif
/*
A little bit of path abstraction: We always work with plain char strings
that usually represent POSIX-ish UTF-8 paths (something like c:/some/file
might appear). For Windows, those are converted to wide strings with \
instead of / and possible fun is had with prefixes to get around the old
path length limit. Outside of the compat library, that stuff should not
matter, although something like //?/UNC/server/some/file could be thrown
around as UTF-8 string, to be converted to a wide \\?\UNC\server\some\file
just before handing it to Windows API.
There is a lot of unnecessary memory allocation and string copying because
of this, but this filesystem stuff is not really relevant to mpg123
performance, so the goal is to keep the code outside the compatibility layer
simple.
*/
/*
Concatenate a prefix and a path, one of them alowed to be NULL.
If the path is already absolute, the prefix is ignored. Relative
parts (like /..) are resolved if this is sensible for the platform
(meaning: for Windows), else they are preserved (on POSIX, actual
file system access would be needed because of symlinks).
*/
char* compat_catpath(const char *prefix, const char* path);
/* Return 1 if the given path indicates an existing directory,
0 otherwise. */
int compat_isdir(const char *path);
/*
Directory traversal. This talks ASCII/UTF-8 paths externally, converts
to/from wchar_t internally if the platform wants that. Returning NULL
means failure to open/end of listing.
There is no promise about sorting entries.
*/
struct compat_dir;
/* Returns NULL if either directory failed to open or listing is empty.
Listing can still be empty even if non-NULL, so always rely on the
nextfile/nextdir functions. */
struct compat_dir* compat_diropen(char *path);
void compat_dirclose(struct compat_dir*);
/* Get the next entry that is a file (or symlink to one).
The returned string is a copy that needs to be freed after use. */
char* compat_nextfile(struct compat_dir*);
/* Get the next entry that is a directory (or symlink to one).
The returned string is a copy that needs to be freed after use. */
char* compat_nextdir (struct compat_dir*);
#ifdef USE_MODULES
/*
For keeping the path mess local, a system-specific dlopen() variant
is contained in here, too. This is very thin wrapping, even sparing
definition of a handle type, just using void pointers.
Use of absolute paths is a good idea if you want to be sure which
file is openend, as default search paths vary.
*/
void *compat_dlopen (const char *path);
void *compat_dlsym (void *handle, const char* name);
void compat_dlclose(void *handle);
#endif
/* Blocking write/read of data with signal resilience.
Both continue after being interrupted by signals and always return the
amount of processed data (shortage indicating actual problem or EOF). */
size_t unintr_write(int fd, void const *buffer, size_t bytes);
size_t unintr_read (int fd, void *buffer, size_t bytes);
/* That one comes from Tellie on OS/2, needed in resolver. */
#ifdef __KLIBC__
typedef int socklen_t;
#endif
/* OSX SDK defines an enum with "normal" as value. That clashes with
optimize.h */
#ifdef __APPLE__
#define normal mpg123_normal
#endif
#include "true.h"
#if (!defined(WIN32) || defined (__CYGWIN__)) && defined(HAVE_SIGNAL_H)
void (*catchsignal(int signum, void(*handler)()))();
#endif
#endif
/*
compat: Some compatibility functions (basic memory and string stuff)
The mpg123 code is determined to keep it's legacy. A legacy of old, old UNIX.
So anything possibly somewhat advanced should be considered to be put here, with proper #ifdef;-)
copyright 2007-2016 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis, Windows Unicode stuff by JonY.
*/
#include "compat.h"
#include "debug.h"
/* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */
void *safe_realloc(void *ptr, size_t size)
{
if(ptr == NULL) return malloc(size);
else return realloc(ptr, size);
}
#ifndef HAVE_STRERROR
const char *strerror(int errnum)
{
extern int sys_nerr;
extern char *sys_errlist[];
return (errnum < sys_nerr) ? sys_errlist[errnum] : "";
}
#endif
char* compat_strdup(const char *src)
{
char *dest = NULL;
if(src)
{
size_t len;
len = strlen(src)+1;
if((dest = malloc(len)))
memcpy(dest, src, len);
}
return dest;
}
This diff is collapsed.
/*
equalizer: code for loading equalizer settings
copyright 1995-2019 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp (exported to this file by Thomas Orgis)
*/
#include "mpg123app.h"
#include "debug.h"
/* Load the settings from the path in the global variable equalfile.
If there is no file, restore equalizer defaults.
If NO_EQUALIZER is defined, it does nothing else that return zero */
int load_equalizer(mpg123_handle *mh)
{
#ifndef NO_EQUALIZER
if(equalfile != NULL)
{ /* tst; ThOr: not TRUE or FALSE: allocated or not... */
FILE *fe;
int i;
fe = fopen(equalfile,"r");
if(fe) {
char line[256];
for(i=0;i<32;i++) {
float e0 = 1.0;
float e1 = 1.0; /* %f -> float! */
do /* ignore comments */
{
line[0]=0;
if(!fgets(line,255,fe))
{
error("equalizer file read error");
return -1;
}
}
while(line[0]=='#');
/* Hm, why not use fscanf? Comments... */
sscanf(line,"%f %f",&e0,&e1);
/* If scanning failed, we have default 1.0 value. */
mpg123_eq(mh, MPG123_LEFT, i, e0);
mpg123_eq(mh, MPG123_RIGHT, i, e1);
}
fclose(fe);
}
else
{
error1("Can't open equalizer file '%s'.",equalfile);
return -1;
}
}
else mpg123_reset_eq(mh);
#endif
return 0;
}
This diff is collapsed.
/*
genre: id3 genre definition
copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Shane Wegner
*/
#ifndef _MPG123_GENRE_H_
#define _MPG123_GENRE_H_
extern char *genre_table[];
extern const int genre_count;
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
abi_align: An attempt to avoid breakage because of mixing
compilers with different alignment.
copyright 1995-2015 by the mpg123 project
free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
There used to be code that checks alignment, but it did not really
work anyway. The only straw we have is putting that alignment
attribute to API functions.
*/
#ifndef MPG123_H_ABI_ALIGN
#define MPG123_H_ABI_ALIGN
#include "config.h"
/* ABI conformance for other compilers.
mpg123 needs 16byte-aligned (or more) stack for SSE and friends.
gcc provides that, but others don't necessarily. */
#ifdef ABI_ALIGN_FUN
#ifndef attribute_align_arg
#if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__>1)
# define attribute_align_arg __attribute__((force_align_arg_pointer))
/* The gcc that can align the stack does not need the check... nor does it work with gcc 4.3+, anyway. */
#else
# define attribute_align_arg
#endif
#endif /* attribute_align_arg */
#else /* ABI_ALIGN_FUN */
#define attribute_align_arg
#endif /* ABI_ALIGN_FUN */
#endif /* MPG123_H_ABI_ALIGN */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* Hack to allow building the same code with and without libtool. */
#include "intsym.h"
#include "dither_impl.h"
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment