1211 lines
52 KiB
C
1211 lines
52 KiB
C
/*
|
|
syn123: some audio signal synthesis and format conversion
|
|
|
|
copyright 2017-2023 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
|
|
|
|
Consider defining SYN123_PORTABLE_API to limit the definitions to
|
|
a safer subset without some problematic features (mainly off_t usage).
|
|
*/
|
|
|
|
#ifndef SYN123_H
|
|
#define SYN123_H
|
|
|
|
/** \file syn123.h The header file for the libsyn123 library. */
|
|
|
|
/* Common audio encoding specification. */
|
|
#include "fmt123.h"
|
|
|
|
/** A macro to check at compile time which set of API functions to expect.
|
|
* This must be incremented at least each time a new symbol is added
|
|
* to the header.
|
|
*/
|
|
#define SYN123_API_VERSION 2
|
|
/** library patch level at client build time */
|
|
#define SYN123_PATCHLEVEL 3
|
|
|
|
#ifndef MPG123_EXPORT
|
|
/** Defines needed for MS Visual Studio(tm) DLL builds.
|
|
* Every public function must be prefixed with MPG123_EXPORT. When building
|
|
* the DLL ensure to define BUILD_MPG123_DLL. This makes the function accessible
|
|
* for clients and includes it in the import library which is created together
|
|
* with the DLL. When consuming the DLL ensure to define LINK_MPG123_DLL which
|
|
* imports the functions from the DLL.
|
|
*/
|
|
#ifdef BUILD_MPG123_DLL
|
|
/* The dll exports. */
|
|
#define MPG123_EXPORT __declspec(dllexport)
|
|
#else
|
|
#ifdef LINK_MPG123_DLL
|
|
/* The exe imports. */
|
|
#define MPG123_EXPORT __declspec(dllimport)
|
|
#else
|
|
/* Nothing on normal/UNIX builds */
|
|
#define MPG123_EXPORT
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
/** Support the restrict keyword for handed-in pointers. Defined to
|
|
'restrict' if available.
|
|
*/
|
|
#ifndef MPG123_RESTRICT
|
|
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
|
#define MPG123_RESTRICT restrict
|
|
#else
|
|
#define MPG123_RESTRICT
|
|
#endif
|
|
#endif
|
|
|
|
// for off_t and ssize_t
|
|
#ifndef SYN123_PORTABLE_API
|
|
#include <sys/types.h>
|
|
#endif
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/** \defgroup syn123_api syn123 library API
|
|
* I wanted to create some test signals in different encodings for testing
|
|
* libout123. Also, they shall serve to verify the decoding of libmpg123
|
|
* in automated testing. Then, the awful drop-sample resampling inside the
|
|
* latter needed replacement. As digital filtering is part of the resampler
|
|
* dance, a chain of those can also be configured and applied. I hope I can
|
|
* avoid adding yet more functionality. It's a little utility library to
|
|
* accompany libmpg123 and libout123, OK?
|
|
*
|
|
* This is what libsyn123 offers:
|
|
*
|
|
* - signal generation (mix of differing wave shapes, noise, a simulated
|
|
* Geiger counter for fun)
|
|
* - format conversion and channel mixing and amplification, with hard and
|
|
* soft clipping, also optional dithering
|
|
* - near-zero-latency good-enough quite-fast resampling
|
|
* - applying digital filters with user-provided coefficients
|
|
*
|
|
* The usage model for signal generation is this:
|
|
*
|
|
* 1. Create handle with desired output format.
|
|
* 2. Set up synthesis mode with parameters.
|
|
* 3. Repeatedly extract buffers with PCM samples.
|
|
*
|
|
* If your hardware is slow on floating point operations, you may benefit
|
|
* from the period buffer in the handle that only needs actual computation
|
|
* once in the setup function. The frequencies of a wave mix may be fudged
|
|
* a bit to make for a configured period size.
|
|
*
|
|
* The usage model for resampling is this:
|
|
*
|
|
* 1. Create handle with any format or re-use a signal generation handle.
|
|
* 2. Set up resampling (rate ratio, channels, dirty mode).
|
|
* 3. Use predictor functions to work out matching sizes of input and
|
|
* output buffers.
|
|
* 4. Call the resampler on chunks of input, immediately producing matching
|
|
* chunks of output.
|
|
*
|
|
* The resampler works on 32 bit float, exclusively. This is what is required
|
|
* and appropriate for the provided quality.
|
|
*
|
|
* The usage model for filtering is this:
|
|
*
|
|
* 1. Create or re-use a handle.
|
|
* 2. Set up the filter chain for single or double precision floating point.
|
|
* 3. Apply the filter to chunks of input in succession.
|
|
*
|
|
* Computations are generally done in floating point, either 32 bit or 64
|
|
* bit (single or double precision). The functions for encoding conversion,
|
|
* (de-)interleaving, and interleaved mixing can work without a handle and
|
|
* only use the buffers you hand in. Some support using a syn123 handle to
|
|
* provide the temporary buffers for encoding conversion on the fly to apply
|
|
* flotating-point processing to integer encodings.
|
|
*
|
|
* Only the functions that are able to return a success code do check
|
|
* arguments for obvious trouble like NULL pointers. You are supposed to
|
|
* act responsibly when calling.
|
|
*
|
|
* The size of buffers is either counted in bytes or samples, which,
|
|
* depending on the context, refer to individual PCM samples or to what is
|
|
* more strictly called a frame (one sample for each channel counted
|
|
* together).
|
|
@{
|
|
*/
|
|
|
|
/** Opaque structure for the libsyn123 handle.
|
|
*
|
|
* Simple context-free API functions do not need a handle, while
|
|
* others require it. Those that require it want it as first argument.
|
|
* Functions taking a handle as last argument after others make optional
|
|
* use of it (if non-NULL) to enable advanced functionality like
|
|
* on-the-fly encoding conversion that needs temporary storage.
|
|
*/
|
|
struct syn123_struct;
|
|
/** Typedef shortcut as preferrend name for the handle type. */
|
|
typedef struct syn123_struct syn123_handle;
|
|
|
|
/** Get version of the mpg123 distribution this library build came with.
|
|
* (optional means non-NULL)
|
|
* \param major optional address to store major version number
|
|
* \param minor optional address to store minor version number
|
|
* \param patch optional address to store patchlevel version number
|
|
* \return full version string (like "1.2.3-beta4 (experimental)")
|
|
*/
|
|
MPG123_EXPORT
|
|
const char *syn123_distversion(unsigned int *major, unsigned int *minor, unsigned int *patch);
|
|
|
|
/** Get API version of library build.
|
|
* \param patch optional address to store patchlevel
|
|
* \return API version of library
|
|
*/
|
|
MPG123_EXPORT
|
|
unsigned int syn123_libversion(unsigned int *patch);
|
|
|
|
/** Functions that return an integer success code either return
|
|
* SYN123_OK if everything went fine, or one of the other detailed
|
|
* error codes.
|
|
*/
|
|
enum syn123_error
|
|
{
|
|
SYN123_OK = 0 /**< no error */
|
|
, SYN123_BAD_HANDLE /**< bad handle given (NULL) */
|
|
, SYN123_BAD_FMT /**< bad format (rate/channels) */
|
|
, SYN123_BAD_ENC /**< bad encoding given */
|
|
, SYN123_BAD_CONV /**< unsupported conversion */
|
|
, SYN123_BAD_SIZE /**< buffer size bad (too small) */
|
|
, SYN123_BAD_BUF /**< bad buffer pointer (NULL) */
|
|
, SYN123_BAD_CHOP /**< byte buffer not cut at sample boundaries */
|
|
, SYN123_DOOM /**< Disaster, Out Of Memory. */
|
|
, SYN123_WEIRD /**< An internal error that should never occur. */
|
|
, SYN123_BAD_FREQ /**< Invalid wave frequency given. */
|
|
, SYN123_BAD_SWEEP /**< Invalid sweep curve given. */
|
|
, SYN123_OVERFLOW /**< Some fatal (integer) overflow that prevents proper operation. */
|
|
, SYN123_NO_DATA /**< Not enough data to do something. */
|
|
, SYN123_BAD_DATA /**< Data present, but not usable. */
|
|
};
|
|
|
|
/** Give a short phrase explaining an error code.
|
|
* \param errcode the code returned by an API function
|
|
* \return error phrase
|
|
*/
|
|
const char* syn123_strerror(int errcode);
|
|
|
|
/** Create new handle with specified output format.
|
|
* \param rate sampling rate
|
|
* \param channels channel count (duplicated mono channels)
|
|
* \param encoding sample encoding (see enum mpg123_enc_enum)
|
|
* \param maxbuf maximum buffer size in bytes to allow for caching periodic
|
|
* signals. When this is given, it is attempted to fit any configured signal
|
|
* into this buffer in the hope it will work being played periodically. Maybe
|
|
* there will be tricks with non-periodic signals.
|
|
* A buffer size of zero turns off buffering and signals are always generated
|
|
* during extraction.
|
|
* \param err address to store error code, non-NULL if you care
|
|
* \return Pointer to allocated handle structure or NULL on error.
|
|
*/
|
|
MPG123_EXPORT
|
|
syn123_handle* syn123_new( long rate, int channels, int encoding
|
|
, size_t maxbuf, int *err );
|
|
|
|
/** Delete a handle.
|
|
* \param sh the handle to delete
|
|
*/
|
|
MPG123_EXPORT
|
|
void syn123_del(syn123_handle *sh);
|
|
|
|
/** Enable/disable dithering for conversions.
|
|
*
|
|
* The default is no dither for conversions to integer encodings. You can
|
|
* enable dithering after handle creation, or disable it, as you wish.
|
|
* Enabling the dither resets the random number generator seed to the provided
|
|
* value or an internal default if the provided value is zero. The dither noise
|
|
* is unfiltered with triangular distribution (TPDF), as a sensible common
|
|
* choice. No further filtering of questionable benefit.
|
|
*
|
|
* \param sh handle to work on
|
|
* \param dither Disable (0) or enable (1, actually nonzero) dithering.
|
|
* Positive values > 1 may trigger differing dither modes in future, but not
|
|
* now.
|
|
* \param seed optional address to read the initial seed value from (if non-zero)
|
|
* and to write the current value to
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_dither(syn123_handle *sh, int dither, unsigned long *seed);
|
|
|
|
/** Extract desired amount of data from the generator.
|
|
* \param sh handle
|
|
* \param dst destination buffer
|
|
* \param dst_bytes number of bytes to extract
|
|
* \return actual number of extracted bytes
|
|
* (might differ if dst_bytes is no multiple of the PCM frame size)
|
|
*/
|
|
MPG123_EXPORT
|
|
size_t syn123_read(syn123_handle *sh, void *dst, size_t dst_bytes);
|
|
|
|
/** Wave types */
|
|
enum syn123_wave_id
|
|
{
|
|
SYN123_WAVE_INVALID = -1 /**< invalid wave pattern */
|
|
, SYN123_WAVE_FLAT = 0 /**< flat line, silence */
|
|
, SYN123_WAVE_SINE /**< sinusodial wave*/
|
|
, SYN123_WAVE_SQUARE /**< square wave */
|
|
, SYN123_WAVE_TRIANGLE /**< triangle wave */
|
|
, SYN123_WAVE_SAWTOOTH /**< sawtooth wave */
|
|
, SYN123_WAVE_GAUSS /**< Gaussian bell shape */
|
|
, SYN123_WAVE_PULSE /**< pulse shape, x^2 exp(-A x^2)/S */
|
|
, SYN123_WAVE_SHOT /**< shot (sharper pulse), x^2 exp(-A x)/S
|
|
* (different values for A and S) */
|
|
, SYN123_WAVE_LIMIT /**< valid IDs below that. A newer release of
|
|
* the library might support more. */
|
|
};
|
|
|
|
/** Setup periodic wave generator.
|
|
* This sets up a series of oscillators with differing wave shapes.
|
|
* They are multiplied/scaled with each other instead of mixed
|
|
* in a sum of signals. It's more fun this way to generate interesting
|
|
* sounds. If you want to mix differing streams with differing volumes,
|
|
* channel balance and phase shifts, just create multiple single-channel
|
|
* generators with a convenient format (float encoding comes to mind)
|
|
* and mix to your heart's desire. You can then still use this library
|
|
* to get your channel buffers interleaved and converted to something
|
|
* your output device likes.
|
|
*
|
|
* You can ensure strict periodicity without possible shifts in phases
|
|
* due to floating point rounding errors with the buffered variant.
|
|
* That may adjust your chosen frequencies to be able to keep the limit
|
|
* on buffer size, but the resulting data is then strictly periodic
|
|
* without any further computations that may introduce timing errors.
|
|
* Apart from possibly saving computing time via the precomputed table,
|
|
* this is the reason to pre-mix multiple waves into a common buffer at
|
|
* all.
|
|
*
|
|
* The adjustments of the wave frequencies also include limiting them
|
|
* between some minimal value and the Nyquist frequency. Without the
|
|
* buffer, you can happily choose waves that are not resolved at all
|
|
* by the sampling rate and get the nasty results. Things get nasty
|
|
* inside the buffer, too, when you approach the Nyquist limit, but that
|
|
* is life (and mathematics).
|
|
*
|
|
* The default wave is a 440 Hz sine without phase offset. If any setting
|
|
* is missing, the default is taken from that.
|
|
*
|
|
* \param sh handle
|
|
* \param count number of waves (if zero, one default wave is configured)
|
|
* \param id array of wave IDs (enum syn123_wave_id), may be NULL
|
|
* \param freq array of wave frequencies, may be NULL
|
|
* Your provided frequencies are overwritten with the actual
|
|
* values if the periodic buffer is chosen.
|
|
* \param phase array of wave phases, may be NULL
|
|
* \param backwards array of true (non-zero) or false (zero), indicating
|
|
whether the wave is being inverted in time, may be NULL
|
|
* \param period address to store the size of the period buffer
|
|
* in samples (zero if not using the buffer), ignored if NULL
|
|
* \return success code
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_setup_waves( syn123_handle* sh, size_t count
|
|
, int *id, double *freq, double *phase, int* backwards
|
|
, size_t *period );
|
|
|
|
/** Query current wave generator setup and state.
|
|
*
|
|
* This lets you extract the setup of the wave generator and
|
|
* the current phases to be able to re-create it and continue
|
|
* seamlessly, or maybe intentionally in some tweaked form with
|
|
* slight phase or frequency shifts.
|
|
*
|
|
* You only need to set target pointers to non-NULL where you
|
|
* want the corresponding values extracted. You need to have
|
|
* the storage prepared for the correct wave count. A common
|
|
* mode of usage might be to make a first call to only query
|
|
* the count, allocate storage, then a do a second call for the
|
|
* wave data.
|
|
*
|
|
* \param sh handle
|
|
* \param count address to store number of waves
|
|
* \param id storage for array of wave IDs
|
|
* \param freq storage for array of wave frequencies
|
|
* \param phase storage for array of wave phases
|
|
* \param backwards storage for array of true (non-zero) or false (zero),
|
|
* indicating whether the wave is being inverted in time
|
|
* \param period address to store the size of the period buffer
|
|
* in samples (zero if not using the buffer)
|
|
* \return success code
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_query_waves( syn123_handle* sh, size_t *count
|
|
, int *id, double *freq, double *phase, int* backwards
|
|
, size_t *period );
|
|
|
|
/** Return the name of the indicated wave pattern.
|
|
* \param id The numerical ID of the wave pattern
|
|
* (out of enum syn123_wave_id).
|
|
* \return The name string, guaranteed to be non-NULL.
|
|
* Invalid codes yield the string "???".
|
|
*/
|
|
MPG123_EXPORT
|
|
const char* syn123_wave_name(int id);
|
|
|
|
/** Return the wave pattern id given a name string.
|
|
* \param name The name string.
|
|
* \return The numerical id (out of enum syn123_wave_id).
|
|
*
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_wave_id(const char *name);
|
|
|
|
/** Types of frequency sweeps.
|
|
* There are no functions mapping those to/from strings,
|
|
* as this list is supposed to be fixed and small.
|
|
* There are only so many types of sweeps that make sense.
|
|
*/
|
|
enum syn123_sweep_id
|
|
{
|
|
SYN123_SWEEP_LIN = 0 /**< linear frequency change */
|
|
, SYN123_SWEEP_QUAD /**< quadratic frequency change */
|
|
, SYN123_SWEEP_EXP /**< exponential (octave per time unit) */
|
|
, SYN123_SWEEP_LIMIT /**< valid IDs less than that */
|
|
};
|
|
|
|
/** Frequency sweep generator.
|
|
* This generates a sweep from one frequency to another with one
|
|
* of the available wave shapes over a given time.
|
|
* While you can just extract your single sweep by exactly reading
|
|
* the requestet duration, the generator is set up to run the sweep
|
|
* a bit longer until the beginning phase is reached again
|
|
* (one sample before that, of course). That way, reasonably smooth
|
|
* periodic playback from the buffer is possible without that nasty jump.
|
|
* Still, a large freqency difference will result in an audible pop,
|
|
* but at least that is not whole spectrum due to a phase jump.
|
|
* \param sh handle
|
|
* \param wave_id wave ID (enum syn123_wave_id)
|
|
* \param f1 pointer to beginning frequency in Hz (>= 1e-4, please,
|
|
* a value <= 0 being replaced by the standard frequency and stored for you)
|
|
* \param f2 ending frequency in Hz (>= 1e-4, please,
|
|
* in case of exponential sweep: f2-f1 >= 1e-4, too,
|
|
* a value <= 0 being replaced by the standard frequency and stored for you)
|
|
* \param sweep_id choice of sweep curve (enum syn123_sweep_id)
|
|
* \param smooth enable the periodic smoothing, if sensible
|
|
* (extending signal beyond the sweep to avoid phase jumps, a continuing
|
|
* starting at given start phase, not the returned endphase)
|
|
* \param duration duration of sweep in samples (> 1, please)
|
|
* This theoretically should be an off_t relating to the size of a
|
|
* file you produce, but off_t in API headers causes headaches.
|
|
* A 32 bit size_t still gives you over 24 hours of sweeping with 44100 kHz
|
|
* rate. On top of that, you can use the returned endphase to chop
|
|
* your monster sweep into pieces.
|
|
* \param phase initial phase of the sweep
|
|
* \param backwards invert the waveform in time if true
|
|
* \param endphase address to store the normal phase that would
|
|
* smoothly continue the signal without the period correction
|
|
* (You can create a following sweep that continues smoothly to a new
|
|
* target frequency by handing in this endphase as initial phase. Combine
|
|
* that with phases of constant tone and you could simulate a Theremin
|
|
* player by approximating the reaction to hand movements via sweeps.)
|
|
* \param period address to store the periodic sample count, usually
|
|
* being a bit bigger than the duration for getting the phase
|
|
* back down; does not imply use of the internal period buffer
|
|
* \param buffer_period address to store the period count only if the
|
|
* period buffer is actually in use
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_setup_sweep( syn123_handle* sh
|
|
, int wave_id, double phase, int backwards
|
|
, int sweep_id, double *f1, double *f2, int smooth, size_t duration
|
|
, double *endphase, size_t *period, size_t *buffer_period );
|
|
|
|
/** Set up pink noise generator.
|
|
* This employs the Gardner/McCartney method to the approximate
|
|
* the real thing. The number of rows in the tree pattern is tunable.
|
|
* The result is pink noise with around 2.5 dB/octave. Do not expect
|
|
* more than 32 bits of randomness (or anything;-).
|
|
* \param sh handle
|
|
* \param rows rows for the generator algorithm
|
|
* It maxes out at 30 rows. Below 1 chooses a default.
|
|
* \param seed a 32 bit seed value for the pseudo-random number generator
|
|
* \param period optional address to store the size of the enforced period
|
|
* (zero for endlessly freshly generated signal)
|
|
* \return success code
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_setup_pink( syn123_handle *sh, int rows, unsigned long seed
|
|
, size_t *period );
|
|
|
|
/** Set up white noise generator.
|
|
* A simple white noise source using some cheap pseudo RNG. Do not
|
|
* expect more than 32 bits of randomness (or anything;-).
|
|
* \param sh handle
|
|
* \param seed a 32 bit seed value for the pseudo-random number generator
|
|
* \param period optional address to store the size of the
|
|
* enforced period (zero for endlessly freshly generated signal)
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_setup_white(syn123_handle *sh, unsigned long seed, size_t *period);
|
|
|
|
/** Set up Geiger counter simulator.
|
|
* This models a speaker that is triggered by the pulses from
|
|
* the Geiger-Mueller counter. That creepy ticking sound.
|
|
* \param sh handle
|
|
* \param activity average events per second
|
|
* \param seed a 32 bit seed value for the pseudo-random number generator
|
|
* \param period optional address to store the size of the enforced period
|
|
* (zero for endlessly freshly generated signal)
|
|
* \return success code
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_setup_geiger( syn123_handle *sh, double activity
|
|
, unsigned long seed, size_t *period );
|
|
|
|
/** Set up silence.
|
|
* This goes back to the vanilla state.
|
|
* \return success code
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_setup_silence(syn123_handle *sh);
|
|
|
|
/** Convert between supported encodings.
|
|
* The buffers must not overlap.
|
|
* Note that syn123 converts -1.0 to -127 for 8 bit signed (and analogous for
|
|
* other encodings), but still clips asymmetrically at -128 as that is the
|
|
* range of the type. If you do explicit clipping using syn123_clip(),
|
|
* the resulting range will be symmetrical inside [-1.0:1.0] and hence
|
|
* only down to -127 for 8 bit signed encoding.
|
|
* The conversions only work directly either from anything to double/float or
|
|
* from double/float to anything. This process is wrapped in the routine if
|
|
* a handle is provided, using the fixed mixing buffer in that. Clipping
|
|
* is only handled for floating point to integer conversions. Also, NaN
|
|
* is set to zero on conversion and counted as clipped.
|
|
* The ulaw and alaw conversions use Sun's reference implementation of the
|
|
* G711 standard (differing from libmpg123's big lookup table).
|
|
*
|
|
* \param dst destination buffer
|
|
* \param dst_enc destination encoding (enum mpg123_enc_enum)
|
|
* \param dst_size size of destination buffer in bytes
|
|
* \param src source buffer
|
|
* \param src_enc source encoding
|
|
* \param src_bytes source buffer size in bytes
|
|
* \param dst_bytes optional address to store the written byte count to
|
|
* \param clipped optional address to store number of clipped samples to
|
|
* \param sh an optional syn123_handle which enables arbitrary encoding
|
|
* conversions by utilizing the contained buffer as intermediate storage,
|
|
* can be NULL, disabling any conversion not involving floating point
|
|
* input or output
|
|
* \return success code
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_conv( void * MPG123_RESTRICT dst, int dst_enc, size_t dst_size
|
|
, void * MPG123_RESTRICT src, int src_enc, size_t src_bytes
|
|
, size_t *dst_bytes, size_t *clipped, syn123_handle * sh );
|
|
|
|
/** The range of decibel values handled by syn123 goes from
|
|
* -SYN123_DB_LIMIT to +SYN123_DB_LIMIT
|
|
* This value ensures that a resulting linear volume can still
|
|
* be expressed using single-precision float.
|
|
* The resulting amplitude from -500 dB is still small enough
|
|
* to drive a 32 bit integer sample value orders of magnitude below
|
|
* 1, so it is effectively a zero. Note that physical volume controls
|
|
* typically give a range as small as 60 dB. You might want to present
|
|
* a tighter range to the user than +/- 500 dB!
|
|
*/
|
|
#define SYN123_DB_LIMIT 500
|
|
|
|
/** Convert decibels to linear volume (amplitude factor).
|
|
* This just returns pow(10, db/20) in the supported range.
|
|
* The dB value is limited according to SYN123_DB_LIMIT, with
|
|
* NaN being put at the lower end of the range. Better silent
|
|
* than insanely loud.
|
|
* \param db relative volume in dB
|
|
* \return linear volume factor
|
|
*/
|
|
MPG123_EXPORT double syn123_db2lin(double db);
|
|
|
|
/** Convert linear volume (amplitude factor) to decibels.
|
|
* This just returns 20*log10(volume) in the supported range.
|
|
* The returned value is limited according to SYN123_DB_LIMIT, with
|
|
* NaN being put at the lower end of the range. Better silent
|
|
* than insanely loud.
|
|
* \param volume linear volume factor
|
|
* \return relative volume in dB
|
|
*/
|
|
MPG123_EXPORT double syn123_lin2db(double volume);
|
|
|
|
/** Amplify given buffer.
|
|
* This multiplies all samples by the given floating point value
|
|
* (possibly converting to/from floating point on the fly, if a
|
|
* handle with the included working buffer is given).
|
|
* Also an offset correction is provided.
|
|
*
|
|
* \param buf the buffer to work on
|
|
* \param encoding the sample encoding
|
|
* \param samples number of samples
|
|
* \param volume linear volume factor (use syn123_db2lin() for
|
|
* applying a change in dB)
|
|
* \param offset offset to add to the sample values before
|
|
* multiplication
|
|
* \param clipped optional address to store number of clipped samples to
|
|
* \param sh optional handle to enable work on non-float
|
|
* encodings
|
|
* \return success code (e.g. bad encoding without handle)
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_amp( void* buf, int encoding, size_t samples
|
|
, double volume, double offset, size_t *clipped, syn123_handle *sh );
|
|
|
|
/** Clip samples in buffer to default range.
|
|
* This only does anything with floating point encoding, but you can always
|
|
* call it without damage as a no-op on other encodings. After this, the
|
|
* samples are guaranteed to be in the range [-1,+1]. NaNs are mapped
|
|
* to zero (and counted as clipped), so they will still sound bad.
|
|
* If you want to hard clip to a smaller range, use syn123_soft_clip() with
|
|
* a width of zero.
|
|
* \param buf buffer to work on
|
|
* \param encoding sample encoding
|
|
* \param samples total number of samples
|
|
* \return number of clipped samples
|
|
*/
|
|
MPG123_EXPORT
|
|
size_t syn123_clip(void *buf, int encoding, size_t samples);
|
|
|
|
/** Soft clipping / cheap limiting.
|
|
* This limits the samples above the threshold of limit-width with a
|
|
* smooth curve, dampening the high-frequency content of the clipping.
|
|
* This is no proper frequency filter, but just an independent function on
|
|
* each sample value, also ignorant of the channel count. This can
|
|
* directly work on float encodings and does nothing on others unless
|
|
* a handle is provided for on-line conversion.
|
|
* \param buf buffer to work on
|
|
* \param encoding sample encoding
|
|
* \param samples total number of samples
|
|
* \param limit the limit to clip to (normally 1 for full scale)
|
|
* \param width smoothing range
|
|
* \param sh optional handle to work on non-float encodings
|
|
* \return number of clipped samples
|
|
*/
|
|
MPG123_EXPORT
|
|
size_t syn123_soft_clip( void *buf, int encoding, size_t samples
|
|
, double limit, double width, syn123_handle *sh );
|
|
|
|
/** Interleave given number of channels into one stream.
|
|
* A rather trivial functionality, here for completeness. As the
|
|
* algorithm is agnostic to what is actually stored as a "sample",
|
|
* the parameter types are so generic that you could use these
|
|
* functions to arrange huge structs (hence samplesize as size_t)
|
|
* or whatever. If that makes sense is up to you.
|
|
* The buffers shall not overlap!
|
|
* \param dst destination buffer
|
|
* \param src source buffer array (one per channel)
|
|
* \param channels channel count
|
|
* \param samplesize size of one sample
|
|
* \param samplecount count of samples per channel
|
|
*/
|
|
MPG123_EXPORT
|
|
void syn123_interleave( void * MPG123_RESTRICT dst, void** MPG123_RESTRICT src
|
|
, int channels, size_t samplesize, size_t samplecount );
|
|
|
|
/** Deinterleave given number of channels out of one stream.
|
|
* A rather trivial functionality, here for completeness. As the
|
|
* algorithm is agnostic to what is actually stored as a "sample",
|
|
* the parameter types are so generic that you could use these
|
|
* functions to arrange huge structs (hence samplesize as size_t)
|
|
* or whatever. If that makes sense is up to you.
|
|
* The buffers must not overlap!
|
|
* \param dst destination buffer array (one per channel)
|
|
* \param src source buffer
|
|
* \param channels channel count
|
|
* \param samplesize size of one sample (see MPG123_SAMPLESIZE)
|
|
* \param samplecount count of samples per channel
|
|
*/
|
|
MPG123_EXPORT
|
|
void syn123_deinterleave( void ** MPG123_RESTRICT dst, void * MPG123_RESTRICT src
|
|
, int channels, size_t samplesize, size_t samplecount );
|
|
|
|
/** Simply copies mono samples into an interleaved stream.
|
|
* This might be implemented by a call to syn123_interleave(), it might
|
|
* be optimized to something different. You could have fun measuring that.
|
|
* \param dst destination buffer
|
|
* \param src source buffer
|
|
* \param channels channel count
|
|
* \param samplesize size of one sample (see MPG123_SAMPLESIZE)
|
|
* \param samplecount count of samples per channel
|
|
*/
|
|
MPG123_EXPORT
|
|
void syn123_mono2many( void * MPG123_RESTRICT dst, void * MPG123_RESTRICT src
|
|
, int channels, size_t samplesize, size_t samplecount );
|
|
|
|
/** A little helper/reminder on how interleaved format works:
|
|
* Produce the offset of the given sample for the given channel.
|
|
*/
|
|
#define SYN123_IOFF(sample, channel, channels) ((sample)*(channels)+(channel))
|
|
|
|
/** Specify floating point encoding to use for preserving precision in
|
|
* intermediate computations for given source and destination encoding.
|
|
* This should return either MPG123_ENC_FLOAT_32 or MPG123_ENC_FLOAT_64,
|
|
* unless an uncertain future adds things like 16 bit fp ...
|
|
* This is what syn123_conv() and syn123_mix() will use internally if
|
|
* intermediate conversion is necessary.
|
|
* Note that 64 bit floating point material will be mixed in 32 bit if the
|
|
* destination encoding does not need more precision.
|
|
* \param src_enc source/input encoding
|
|
* \param dst_enc destination/output encoding
|
|
* \return encoding value, zero if none can be chosen (invalid parameters)
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_mixenc(int src_enc, int dst_enc);
|
|
|
|
/** Mix n input channels on top of m output channels.
|
|
* This takes an interleaved input stream and mixes its channels
|
|
* into the output stream given a channel matrix (m,n) where
|
|
* each of the m rows contains the n volume factors (weights)
|
|
* to apply when summing the samples from the n input channels.
|
|
* Sample values are added to what is already present unless
|
|
* initial silence is explicitly requested.
|
|
* This works directly with identical floating point encodings. It
|
|
* may have some optimization to work faster with mono or stereo on
|
|
* either side and slower generic code for arbitrary channel counts.
|
|
* You can use syn123_conv() to convert from/to input/output encodings
|
|
* or provide a syn123_handle to do it on the fly.
|
|
* There are no optimizations for special cases of mixing factors, so
|
|
* you should always be able to predict the number of floating point
|
|
* operations being executed.
|
|
* For fun, you could give the same problem to a BLAS implementation
|
|
* of your choice and compare the performance;-)
|
|
* \param dst destination buffer
|
|
* \param dst_enc output sample encoding, must be MPG123_ENC_FLOAT_32 or
|
|
* MPG123_ENC_FLOAT_64 unless a syn123_handle is provided
|
|
* \param dst_channels destination channel count (m)
|
|
* \param src source buffer
|
|
* \param src_enc input sample encoding, must be MPG123_ENC_FLOAT_32 or
|
|
* MPG123_ENC_FLOAT_64 unless a syn123_handle is provided
|
|
* \param src_channels source channel count (n)
|
|
* \param mixmatrix mixing factors ((m,n) matrix), same encoding as
|
|
* the audio data
|
|
* \param samples count of samples (PCM frames) to work on
|
|
* \param silence Set to non-zero value to intialize the output
|
|
* to a silent signal before adding the input.
|
|
* \param clipped optional address to store number of clipped samples to
|
|
* (in case of mixing to an integer encoding)
|
|
* \param sh an optional syn123_handle which enables work on non-float
|
|
* encodings by utilizing the contained buffer as intermediate storage,
|
|
* converting to/from float transparently; Note that this may limit
|
|
* the amount of channels depending on the fixed internal buffer space.
|
|
* As long as you have up to 128 channels, you should not worry.
|
|
* \return success code (e.g. bad encoding, channel counts ...)
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_mix( void * MPG123_RESTRICT dst, int dst_enc, int dst_channels
|
|
, void * MPG123_RESTRICT src, int src_enc, int src_channels
|
|
, const double * mixmatrix
|
|
, size_t samples, int silence, size_t *clipped, syn123_handle *sh );
|
|
|
|
/** Set up a generic digital filter.
|
|
*
|
|
* This takes a filter order N and coefficient set to prepare
|
|
* the internal state of a digital filter defined by the transfer
|
|
* function
|
|
* \f[
|
|
*
|
|
* H(z) = \frac
|
|
* {b_0 + b_1 z^{-1} + ... + b_N z^{-N}}
|
|
* {1 + a_1 z^{-1} + ... + a_N z^{-N}}
|
|
* \f]
|
|
* It is your task to come up with fun values for the coefficients
|
|
* b_n and a_n to implement various FIR and IIR filters.
|
|
*
|
|
* Since it is easy to do and useful, this configures not only a single
|
|
* filter but a chain of them. If you do configure a chain, the choice
|
|
* of mixenc and channels must match. No conversion between filters.
|
|
*
|
|
* \param sh mandatory handle
|
|
* \param append if true, append a filter to the chain, fresh chain otherwise
|
|
* \param order filter order N (filter length minus one)
|
|
* \param b nominator coefficients, starting with b_0 (order+1 elements)
|
|
* \param a denominator coefficients, starting with a_0=1 (order+1 elements).
|
|
* It is an error to provide a sequence that does not start with 1.
|
|
* For a non-recursive (FIR) filter, you can set all following
|
|
* values from a_1 on to zero or choose to provide a NULL pointer.
|
|
* \param mixenc either MPG123_ENC_FLOAT_32 or MPG123_ENC_FLOAT_64 for
|
|
* computation in single or double precision, can be zero to refer to
|
|
* the value demanded by an already present filter
|
|
* \param channels number of channels in the audio signal, can be zero
|
|
* to refer to the value demanded by an already present filter
|
|
* \param init_firstval If non-zero, initialize the filter history with
|
|
* a constant stream of the first encountered sample instead of zero.
|
|
* \return success code
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_setup_filter( syn123_handle *sh
|
|
, int append, unsigned int order, double *b, double *a
|
|
, int mixenc, int channels, int init_firstval );
|
|
|
|
/** init_firstval is the effective setting (extreme coefficients may remove the distinction) */
|
|
|
|
MPG123_EXPORT
|
|
int syn123_query_filter( syn123_handle *sh, size_t position
|
|
, size_t *count, unsigned int *order, double *b, double *a
|
|
, int *mixenc, int *channels, int *init_firstval );
|
|
|
|
/** drop the n last filters */
|
|
MPG123_EXPORT
|
|
void syn123_drop_filter(syn123_handle *sh, size_t count);
|
|
|
|
/** Apply a prepared digital filter.
|
|
*
|
|
* This applies the filter prepared by syn123_setup_filter to yur
|
|
* provided buffer in single or double precision float.
|
|
* Handing in a non-float encoding is an error. You are supposed
|
|
* to convert and clip before/after applying the filters.
|
|
*
|
|
* If you got no filters configured, this always succeeds and
|
|
* does nothing.
|
|
*
|
|
* \param sh handle
|
|
* \param buf audio data to work on (channel count matching what
|
|
* was given to mpg123_setup_filter())
|
|
* \param encoding audio encoding
|
|
* \param samples count of samples (PCM frames) in the buffer
|
|
* \return success code
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_filter( syn123_handle *sh
|
|
, void* buf, int encoding, size_t samples );
|
|
|
|
/** Set up the resampler.
|
|
*
|
|
* This works independently of the signal generators. You can combine
|
|
* syn123_setup_resample() with syn123_setup_geiger(), for example.
|
|
*
|
|
* People can get worked up a lot about differing algorithms for resampling,
|
|
* while many folks can actually bear the simple drop/repeat method and most
|
|
* probably do not bother about the distortions from linear resampling.
|
|
* A testament to this is that in the 18 years of me maintaining mpg123, I
|
|
* got bugged about the missing dithering and on subtle bias in shuffling
|
|
* a playlist, but people seem to insist on using the NtoM resampoler inside
|
|
* libmpg123, despite me warning about its horrible consequences for audio
|
|
* quality. It is a plain drop-sample implementation. The only good things to
|
|
* say about it is that it is cheap and is embedded with the sample-accurate
|
|
* decoder so that you do not have to worry about offsets in terms of input
|
|
* and output samples.
|
|
*
|
|
* Anyhow, this is my take on a reasonably good and efficient resampler that is
|
|
* neither the best-sounding, nor the fastest in terms of CPU time, but gets
|
|
* by without significant latency. It needs far less computation than usual
|
|
* high-quality windowed-sinc resampling (libsamplerate), but cannot beat
|
|
* libsoxr with its FFT-based approach. The less stringent dirty mode (using
|
|
* only a 72 dB lowpass filter, in practice still close to CD-DA quality)
|
|
* comes quite close, though.
|
|
*
|
|
* The selling point is that it produces output samples as soon as you start
|
|
* feeding, without any buffering of future samples to fill a window for the
|
|
* FIR filter or the Fourier transform. It employs IIR filters for low-passing,
|
|
* possibly in multiple stages for decimation, and optimized interpolation
|
|
* formulas using up to 6 points. These formulas, based on research by
|
|
* Olli Niemitalo using using Differential Evolution, are what enables a
|
|
* dynamic range of 108 dB, well above 16 bit CD-DA quality. Simple
|
|
* cubic splines after low-passing distort up to around -40 dB in my tests.
|
|
*
|
|
* There is some effective signal delay well below 10 samples. The impulse
|
|
* response is about 3 samples late, so this is well inside the realm of
|
|
* (nonlinear) phase shift. The phase distortion looks bad on paper but does
|
|
* not matter much in the intended domain of application: the final change in
|
|
* sampling rate before playback on audio hardware, the last filter that is
|
|
* applied before the sound hits the speakers (or all the other filters
|
|
* implemented in your audio harware, that you can choose to be ignorant
|
|
* about). Use better resamplers for mixing in the studio. Use better
|
|
* resamplers for converting files on disk. For live playback, consider this
|
|
* one because it is good enough, fast enough, cheap enough.
|
|
*
|
|
* Note that if you call this function repeatedly, the internal history
|
|
* is only cleared if you change anything besides the sampling rates. If
|
|
* only the rates change, the state of the resampler is kept to enable
|
|
* you to continue on prior data. This means you can vary the resampling
|
|
* ratio during operation, somewhat smoothly depending on your buffer size.
|
|
*
|
|
* Also note that even on identical input and output rates, the resampler
|
|
* will apply the full filtering as for any ratio close to that, including
|
|
* oversampling. No special shortcuts.
|
|
*
|
|
* A returned error guarantees that the internal resampler setup has
|
|
* been cleared (frees a little bit of memory). You can provide zero
|
|
* inrate, outrate, and channel count at the same time to that effect
|
|
* without an error message being produced (but still SYN123_BAD_FMT
|
|
* being returned).
|
|
*
|
|
* \param sh mandatory handle
|
|
* \param inrate input sample rate (nominator of ratio)
|
|
* \param outrate output sample rate (denominator of ratio)
|
|
* \param channels number of interleaved channels
|
|
* \param dirty Enable (!= 0) the dirty mode for even more 'good enough'
|
|
* resampling with less computing time. Offers -72 dB low pass attentuation,
|
|
* worst-case distortion around that, too, and 85% worst-case bandwidth.
|
|
* With this set to zero, the normal mode is used, offering at least 108 dB
|
|
* dynamic range and worst-case bandwidth above 84%.
|
|
* \param smooth Enable (!=0) extra code smoothing the resampler response to
|
|
* on-the-fly changes of sampling rate ratio. This involves keeping
|
|
* some per-stage history to bootstrap additional decimation filters and the
|
|
* changed final lowpass/interpolation.
|
|
* \return success code
|
|
*/
|
|
MPG123_EXPORT
|
|
int syn123_setup_resample( syn123_handle *sh, long inrate, long outrate
|
|
, int channels, int dirty, int smooth );
|
|
|
|
/** Return the maximum allowed value for sample rates given to the resampler.
|
|
*
|
|
* Not every possible value of the underlying data type is a valid sample
|
|
* rate for the resampler. It needs some headroom for computations. This
|
|
* function returns the maximal rate you can specify. For 32-bit long, this
|
|
* will be above 1e9, for 64-bit long above 4e18. The minimum is 1, of course.
|
|
* So, with 32 bit, you can speed up/down by a factor of one million if you
|
|
* want to keep 0.1% precision in the rates.
|
|
*
|
|
* \return upper sample rate limit
|
|
*/
|
|
MPG123_EXPORT
|
|
long syn123_resample_maxrate(void);
|
|
|
|
/** Give upper limit for output sample count from the resampler.
|
|
*
|
|
* Since there is some rounding involved, the exact number of output samples
|
|
* from the resampler, being given a certain amount of input samples, can
|
|
* vary (one more or less than expected). This function is here to give you
|
|
* a safe output buffer size given a certain input buffer size. If you intend
|
|
* to vary the output rate for a fixed input rate, you may compute the output
|
|
* buffer size for the largest intended output rate and use that throughout.
|
|
* The same applies to the input sample count.
|
|
* A return value of zero indicates an error (zero, negative, or too large
|
|
* rate given) unless the given input sample count is also zero.
|
|
* The resampler only produces output when given new input.
|
|
* \param inrate input sample rate
|
|
* \param outrate output sample rate
|
|
* \param ins input sample count for one buffer
|
|
* \return number of maximum output samples for one buffer, or zero
|
|
* if no sensible value exists
|
|
*/
|
|
MPG123_EXPORT
|
|
size_t syn123_resample_count(long inrate, long outrate, size_t ins);
|
|
|
|
/** Return the amount of input samples needed to recreate resample filter state.
|
|
*
|
|
* This returns a number of input samples that should fill the internal
|
|
* filter states good enough for output being close to that produced from
|
|
* the full input since the beginning. Since recursive filters are employed,
|
|
* there is no exact number that recreates a state apart from the full sequence
|
|
* that created it the first time. This number here shall be more than the
|
|
* non-recursive history, but not by a huge factor. For extreme cases, this
|
|
* value may be saturated at SIZE_MAX and thus smaller than what is demanded
|
|
* by the above definition. It is assumed that you define a maximal practical
|
|
* size of history to consider for your application, anyway.
|
|
*
|
|
* \param inrate input sample rate
|
|
* \param outrate output sample rate
|
|
* \param dirty switch for dirty resampling mode (see syn123_setup_resample())
|
|
* \return number of input samples to fill history, zero on error
|
|
*/
|
|
MPG123_EXPORT
|
|
size_t syn123_resample_history(long inrate, long outrate, int dirty);
|
|
|
|
/** Compute the minimal input sample count needed for given output sample count.
|
|
*
|
|
* The reverse of syn123_resample_count(), in a way. This gives you the
|
|
* minimum amount of input samples to guarantee at least the desired amount
|
|
* of output samples. Once you got that, ensure to call syn123_resample_count()
|
|
* to get a safe buffer size for that amount of input and prepare accordingly.
|
|
* With this approach, you can ensure that you get your realtime output device
|
|
* buffer filled with each loop run fetching a bit of input, at the expense
|
|
* of handling some additional buffering for the returned sample counts above
|
|
* the minimum.
|
|
*
|
|
* \param input_rate input sample rate
|
|
* \param output_rate output sample rate
|
|
* \param outs desired minimal output sample count for one input buffer
|
|
* \return number of minimal input samples in one buffer, or zero if no
|
|
* sensible value exists (invalid input parameters, or zero outs)
|
|
*/
|
|
MPG123_EXPORT
|
|
size_t syn123_resample_incount(long input_rate, long output_rate, size_t outs);
|
|
|
|
/** Compute the input sample count needed for close to given output sample
|
|
* count, but never more.
|
|
*
|
|
* Call this to get a safe fixed count of input samples to make best use
|
|
* of a preallocated output buffer, filling it as much as safely possible.
|
|
* This can also be achieved by calling syn123_resample_incount() and reducing
|
|
* the value until syn123_resample_count() fits into your buffer.
|
|
*
|
|
* \param input_rate input sample rate
|
|
* \param output_rate output sample rate
|
|
* \param outs desired output sample count for one input buffer
|
|
* \return number of input samples in one buffer, or zero if no
|
|
* sensible value exists (invalid input parameters, or zero outs)
|
|
*/
|
|
MPG123_EXPORT
|
|
size_t syn123_resample_fillcount(long input_rate, long output_rate, size_t outs);
|
|
|
|
|
|
/** Compute the maximum number of input samples for a resampling buffer.
|
|
*
|
|
* Upsampling means that you will get more output samples than input samples.
|
|
* This larger number still needs to fit into the data type for sample
|
|
* counts. So please don't feed more than the value returned here.
|
|
*
|
|
* \param input_rate input sample rate
|
|
* \param output_rate output sample rate
|
|
* \return maximum safe input sample count
|
|
*/
|
|
MPG123_EXPORT
|
|
size_t syn123_resample_maxincount(long input_rate, long output_rate);
|
|
|
|
/** Give exact output sample count for feeding given input now.
|
|
*
|
|
* This gives you the exact number of samples you will get returned
|
|
* when feeding the resampler the given additional input samples now,
|
|
* given the current resampler state contained in the handle.
|
|
*
|
|
* On error, zero is returned and the error code is set to a nonzero
|
|
* syn123 error code.
|
|
*
|
|
* \param sh syn123 handle
|
|
* \param ins input sample count
|
|
* \param err location to store error code
|
|
* \return output sample count
|
|
*/
|
|
MPG123_EXPORT
|
|
size_t syn123_resample_out(syn123_handle *sh, size_t ins, int *err);
|
|
|
|
/** Give minimum input sample count needed now for given output.
|
|
*
|
|
* This give you the minimal number of input samples needed right
|
|
* now to yield at least the specified amount of output samples.
|
|
* Since one input sample can result in several output sampels in one
|
|
* go, you have to check using syn123_resample_out() how many
|
|
* output samples to really expect.
|
|
*
|
|
* On error, zero is returned and the error code is set to a nonzero
|
|
* syn123 error code.
|
|
*
|
|
* \param sh syn123 handle
|
|
* \param outs output sample count
|
|
* \param err location to store error code
|
|
* \return minimal input sample count
|
|
*/
|
|
MPG123_EXPORT
|
|
size_t syn123_resample_in(syn123_handle *sh, size_t outs, int *err);
|
|
|
|
/** Give exact output sample count for total input sample count.
|
|
*
|
|
* Use this to determine the total length of your output stream
|
|
* given the length of the input stream. The computation is exact.
|
|
* But: It is only valid for a constant sampling rate ratio. If you
|
|
* play with that during runtime, you need to figure out your output
|
|
* offset yourself.
|
|
*
|
|
* \param inrate input sample rate
|
|
* \param outrate output sample rate
|
|
* \param ins input sample count for the whole stream
|
|
* \return number of output samples or -1 if the computation fails
|
|
* (bad/too large sampling rates, integer overflow)
|
|
*/
|
|
MPG123_EXPORT
|
|
int64_t syn123_resample_total64(long inrate, long outrate, int64_t ins);
|
|
|
|
/** Give minimum input sample count for total output sample count.
|
|
*
|
|
* You need to feed at least that amount of input samples to get
|
|
* the desired amount of output samples from the resampler. Depending
|
|
* on the resampling ratio, you may in fact get more than the desired
|
|
* amount (one input sample being worth multiple output samples during
|
|
* upsampling) so make sure to call syn123_resample_total() to get
|
|
* the exact number of samples you need to prepare for.
|
|
* Again, the output offset is only meaninful for a constant sampling
|
|
* rate ratio.
|
|
*
|
|
* \param inrate input sample rate
|
|
* \param outrate output sample rate
|
|
* \param outs output sample count for the whole stream
|
|
* \return number of input samples or -1 if the computation fails
|
|
* (bad/too large sampling rates, integer overflow)
|
|
*/
|
|
MPG123_EXPORT
|
|
int64_t syn123_resample_intotal64(long inrate, long outrate, int64_t outs);
|
|
|
|
/** Resample input buffer to output buffer.
|
|
*
|
|
* This executes the resampling configured by syn123_setup_resample(). The
|
|
* input and output encoding is fixed at single-precision float
|
|
* (MPG123_ENC_FLOAT_32) and multiple channels are interleaved. There
|
|
* is no implicit conversion of other encodings since the fixed internal
|
|
* buffers for that may not fit your chosen extreme resampling ratios. Also,
|
|
* dealing with double precision does not make sense with the mathematical
|
|
* limitations of the employed filters.
|
|
*
|
|
* You are responsible for having your buffers prepared with the correct sizes.
|
|
* Use syn123_resample_count() to ensure that you are prepared for the correct
|
|
* number of output samples given your input sample count.
|
|
*
|
|
* Also, ensuring a minimal number of input samples using
|
|
* syn123_resample_incount() helps to identify an error situation where zero
|
|
* samples are returned (which would be valid for low input sample count).
|
|
* The only error apart from handing in an invalid/unprepared handle is
|
|
* a too large number of input samples. Check syn123_resample_maxincount().
|
|
*
|
|
* \param sh handle with prepared resampling method
|
|
* If this is NULL or if the resampler has not been initialized before, the
|
|
* function returns zero instead of crashing randomly.
|
|
* \param dst destination buffer
|
|
* \param src source buffer
|
|
* \param samples input samples (PCM frames) in source buffer
|
|
* \return number of output samples (PCM frames)
|
|
*/
|
|
MPG123_EXPORT
|
|
size_t syn123_resample( syn123_handle *sh,
|
|
float * MPG123_RESTRICT dst, float * MPG123_RESTRICT src, size_t samples );
|
|
|
|
/** Swap byte order between little/big endian.
|
|
* \param buf buffer to work on
|
|
* \param samplesize size of one sample (see MPG123_SAMPLESIZE)
|
|
* \param samplecount count of samples
|
|
*/
|
|
MPG123_EXPORT
|
|
void syn123_swap_bytes(void* buf, size_t samplesize, size_t samplecount);
|
|
|
|
/* Wrappers over the above to convert to/from syn123's native byte order
|
|
from/to little or big endian. */
|
|
|
|
/** Convert from host order to little endian.
|
|
* \param buf buffer to work on
|
|
* \param samplesize size of one sample (see MPG123_SAMPLESIZE)
|
|
* \param samplecount count of samples
|
|
*/
|
|
MPG123_EXPORT
|
|
void syn123_host2le(void *buf, size_t samplesize, size_t samplecount);
|
|
|
|
/** Convert from host order to big endian.
|
|
* \param buf buffer to work on
|
|
* \param samplesize size of one sample (see MPG123_SAMPLESIZE)
|
|
* \param samplecount count of samples
|
|
*/
|
|
MPG123_EXPORT
|
|
void syn123_host2be(void *buf, size_t samplesize, size_t samplecount);
|
|
|
|
/** Convert from little endian to host order.
|
|
* \param buf buffer to work on
|
|
* \param samplesize size of one sample (see MPG123_SAMPLESIZE)
|
|
* \param samplecount count of samples
|
|
*/
|
|
MPG123_EXPORT
|
|
void syn123_le2host(void *buf, size_t samplesize, size_t samplecount);
|
|
|
|
/** Convert from big endian to host order.
|
|
* \param buf buffer to work on
|
|
* \param samplesize size of one sample (see MPG123_SAMPLESIZE)
|
|
* \param samplecount count of samples
|
|
*/
|
|
MPG123_EXPORT
|
|
void syn123_be2host(void *buf, size_t samplesize, size_t samplecount);
|
|
|
|
// You are invited to defined SYN123_PORTABLE_API to avoid seeing shape-shifting off_t
|
|
// anywhere, also to avoid using non-standard types like ssize_t.
|
|
#if !defined(SYN123_PORTABLE_API) && !defined(SYN123_NO_LARGEFUNC)
|
|
|
|
/* A little hack to help MSVC not having ssize_t, duplicated in internal header. */
|
|
#ifdef _MSC_VER
|
|
#include <stddef.h>
|
|
typedef ptrdiff_t syn123_ssize_t;
|
|
#else
|
|
typedef ssize_t syn123_ssize_t;
|
|
#endif
|
|
|
|
/** Give exact output sample count for feeding given input now.
|
|
*
|
|
* Old variant of syn123_resample_out() that (ab)uses ssize_t.
|
|
*
|
|
* \deprecated Use syn123_resample_out() instead.
|
|
* The return of errors (integer overflow in
|
|
* calculation)is broken, as both the error codes and the valid results
|
|
* are positive integers. I screwed up.
|
|
*
|
|
* \param sh syn123 handle
|
|
* \param ins input sample count
|
|
* \return output sample count or error code, hard to distinguish
|
|
*/
|
|
MPG123_EXPORT
|
|
syn123_ssize_t syn123_resample_expect(syn123_handle *sh, size_t ins);
|
|
|
|
/** Give minimum input sample count needed now for given output.
|
|
*
|
|
* Old variant of syn123_resample_in() that (ab)uses ssize_t.
|
|
*
|
|
* \deprecated Use syn123_resample_in() instead.
|
|
* The return of errors (integer overflow in
|
|
* calculation)is broken, as both the error codes and the valid results
|
|
* are positive integers. I screwed up.
|
|
*
|
|
* \param sh syn123 handle
|
|
* \param outs output sample count
|
|
* \return minimal input sample count or error code, hard to distinguish
|
|
*/
|
|
MPG123_EXPORT
|
|
syn123_ssize_t syn123_resample_inexpect(syn123_handle *sh, size_t outs);
|
|
|
|
/* Lightweight large file hackery to enable worry-reduced use of off_t.
|
|
Depending on the size of off_t in your client build, the corresponding
|
|
library function needs to be chosen. */
|
|
|
|
#if defined(_FILE_OFFSET_BITS) && !defined(MPG123_NO_LARGENAME)
|
|
# if _FILE_OFFSET_BITS+0 == 32
|
|
# define syn123_resample_total syn123_resample_total_32
|
|
# define syn123_resample_intotal syn123_resample_intotal_32
|
|
# elif _FILE_OFFSET_BITS+0 == 64
|
|
# define syn123_resample_total syn123_resample_total_64
|
|
# define syn123_resample_intotal syn123_resample_intotal_64
|
|
# else
|
|
# error "Unpredicted _FILE_OFFSET_BITS value."
|
|
# endif
|
|
#endif
|
|
|
|
/** Give exact output sample count for total input sample count.
|
|
*
|
|
* This is syn123_resample_total64() with shape-shifting off_t,
|
|
* possibly renamed by macro. For type safety, use the former.
|
|
*
|
|
* \deprecated Use syn123_resample_total64() instead.
|
|
*
|
|
* \param inrate input sample rate
|
|
* \param outrate output sample rate
|
|
* \param ins input sample count for the whole stream
|
|
* \return number of output samples or -1 if the computation fails
|
|
* (bad/too large sampling rates, integer overflow)
|
|
*/
|
|
MPG123_EXPORT
|
|
off_t syn123_resample_total(long inrate, long outrate, off_t ins);
|
|
|
|
/** Give minimum input sample count for total output sample count.
|
|
*
|
|
* This is syn123_resample_intotal64() with shape-shifting off_t,
|
|
* possibly renamed by macro. For type safety, use the former.
|
|
*
|
|
* \deprecated Use syn123_resample_intotal64() instead.
|
|
*
|
|
* \param inrate input sample rate
|
|
* \param outrate output sample rate
|
|
* \param outs output sample count for the whole stream
|
|
* \return number of input samples or -1 if the computation fails
|
|
* (bad/too large sampling rates, integer overflow)
|
|
*/
|
|
MPG123_EXPORT
|
|
off_t syn123_resample_intotal(long inrate, long outrate, off_t outs);
|
|
|
|
#endif
|
|
|
|
/** @} */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|