Add flac and ogg decoder deps
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
# Copyright 2023 jacqueline <me@jacqueline.id.au>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
idf_component_register(
|
||||
SRCS "flac.c"
|
||||
INCLUDE_DIRS "include"
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* libfoxenflac -- Tiny FLAC Decoder Library
|
||||
* Copyright (C) 2018-2022 Andreas Stöckel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file flac.h
|
||||
*
|
||||
* Provides a decoder for FLAC (Free Lossless Audio Codec).
|
||||
*
|
||||
* @author Andreas Stöckel
|
||||
*/
|
||||
|
||||
#ifndef FOXEN_FLAC_H
|
||||
#define FOXEN_FLAC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef FX_EXPORT
|
||||
#if __EMSCRIPTEN__
|
||||
#import <emscripten.h>
|
||||
#define FX_EXPORT EMSCRIPTEN_KEEPALIVE
|
||||
#else
|
||||
#define FX_EXPORT
|
||||
#endif /* __EMSCRIPTEN__ */
|
||||
#endif /* FX_EXPORT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Value returned by the fx_flac_get_streaminfo() method if the given streaminfo
|
||||
* key is invalid.
|
||||
*/
|
||||
#define FLAC_INVALID_METADATA_KEY 0x7FFFFFFFFFFFFFFFULL
|
||||
|
||||
/**
|
||||
* Maximum number of channels that can be encoded in a FLAC stream.
|
||||
*/
|
||||
#define FLAC_MAX_CHANNEL_COUNT 8U
|
||||
|
||||
/**
|
||||
* Maximum block size that can be used if the stream is encoded in the FLAC
|
||||
* Subset format and the sample rate is smaller than 48000 kHz.
|
||||
*/
|
||||
#define FLAC_SUBSET_MAX_BLOCK_SIZE_48KHZ 4608U
|
||||
|
||||
/**
|
||||
* Maximum block size than can always be safely used if the stream is encoded
|
||||
* in the FLAC Subset format.
|
||||
*/
|
||||
#define FLAC_SUBSET_MAX_BLOCK_SIZE 16384U
|
||||
|
||||
/**
|
||||
* Maximum block size in samples that can be used in a FLAC stream.
|
||||
*/
|
||||
#define FLAC_MAX_BLOCK_SIZE 65535U
|
||||
|
||||
/**
|
||||
* Opaque struct representing a FLAC decoder.
|
||||
*/
|
||||
struct fx_flac;
|
||||
|
||||
/**
|
||||
* Typedef for the fx_flac struct.
|
||||
*/
|
||||
typedef struct fx_flac fx_flac_t;
|
||||
|
||||
/**
|
||||
* Enum representing the state of a FLAC decoder instance.
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* The decoder is in an error state; the decoder cannot recover from this
|
||||
* error. This error may for example occur if the data in the stream is
|
||||
* invalid, or the stream has a format that is outside the maximum specs
|
||||
* that are supported by the decoder. Call fx_flac_reset() and start anew!
|
||||
*/
|
||||
FLAC_ERR = -1,
|
||||
|
||||
/**
|
||||
* The decoder is currently in its initial state, fx_flac_process() has not
|
||||
* been called.
|
||||
*/
|
||||
FLAC_INIT = 0,
|
||||
|
||||
/**
|
||||
* The decoder found the beginning of the metadata packet!
|
||||
*/
|
||||
FLAC_IN_METADATA = 1,
|
||||
|
||||
/**
|
||||
* The decoder is done reading the current metadata block, this may be
|
||||
* followed by more metadata blocks, in which case the state is reset to
|
||||
* FLAC_IN_METADATA.
|
||||
*/
|
||||
FLAC_END_OF_METADATA = 2,
|
||||
|
||||
/**
|
||||
* The decoder is currently searching for an audio frame.
|
||||
*/
|
||||
FLAC_SEARCH_FRAME = 3,
|
||||
|
||||
/**
|
||||
* The decoder is currently inside the stream of audio frames.
|
||||
*/
|
||||
FLAC_IN_FRAME = 4,
|
||||
|
||||
/**
|
||||
* The decoder successfully decoded an entire frame. Write the data to the
|
||||
* client.
|
||||
*/
|
||||
FLAC_DECODED_FRAME = 5,
|
||||
|
||||
/**
|
||||
* The decoder reached the end of a block.
|
||||
*/
|
||||
FLAC_END_OF_FRAME = 6
|
||||
} fx_flac_state_t;
|
||||
|
||||
/**
|
||||
* Enum used in fx_flac_get_streaminfo() to query metadata about the stream.
|
||||
*/
|
||||
typedef enum {
|
||||
FLAC_KEY_MIN_BLOCK_SIZE = 0,
|
||||
FLAC_KEY_MAX_BLOCK_SIZE = 1,
|
||||
FLAC_KEY_MIN_FRAME_SIZE = 2,
|
||||
FLAC_KEY_MAX_FRAME_SIZE = 3,
|
||||
FLAC_KEY_SAMPLE_RATE = 4,
|
||||
FLAC_KEY_N_CHANNELS = 5,
|
||||
FLAC_KEY_SAMPLE_SIZE = 6,
|
||||
FLAC_KEY_N_SAMPLES = 7,
|
||||
FLAC_KEY_MD5_SUM_0 = 128,
|
||||
FLAC_KEY_MD5_SUM_1 = 129,
|
||||
FLAC_KEY_MD5_SUM_2 = 130,
|
||||
FLAC_KEY_MD5_SUM_3 = 131,
|
||||
FLAC_KEY_MD5_SUM_4 = 132,
|
||||
FLAC_KEY_MD5_SUM_5 = 133,
|
||||
FLAC_KEY_MD5_SUM_6 = 134,
|
||||
FLAC_KEY_MD5_SUM_7 = 135,
|
||||
FLAC_KEY_MD5_SUM_8 = 136,
|
||||
FLAC_KEY_MD5_SUM_9 = 137,
|
||||
FLAC_KEY_MD5_SUM_A = 138,
|
||||
FLAC_KEY_MD5_SUM_B = 139,
|
||||
FLAC_KEY_MD5_SUM_C = 140,
|
||||
FLAC_KEY_MD5_SUM_D = 141,
|
||||
FLAC_KEY_MD5_SUM_E = 142,
|
||||
FLAC_KEY_MD5_SUM_F = 143,
|
||||
} fx_flac_streaminfo_key_t;
|
||||
|
||||
/**
|
||||
* Returns the size of the FLAC decoder instance in bytes. This assumes that the
|
||||
* FLAC audio that is being decoded uses the maximum settings, i.e. the largest
|
||||
* bit depth and block size. See fx_flac_init() regarding parameters.
|
||||
*
|
||||
* @return zero if the given parameters are out of range, the number of bytes
|
||||
* required to hold the FLAC decoder structure otherwise.
|
||||
*/
|
||||
FX_EXPORT uint32_t fx_flac_size(uint32_t max_block_size, uint8_t max_channels);
|
||||
|
||||
/**
|
||||
* Initializes the FLAC decoder at the given memory location. Each decoder can
|
||||
* decode exactly one stream at a time.
|
||||
*
|
||||
* @param mem is a pointer at the memory region at which the FLAC decoder should
|
||||
* store its private data. The memory region must be at last as large as
|
||||
* indicated by fx_flac_size(). May be NULL, in which case NULL is returned.
|
||||
* @param max_block_size is the maximum block size for which the FLAC instance
|
||||
* will provide a buffer. For streams in the Subset format (which is used per
|
||||
* default in most FLAC encoders), max_block_size should can be set to 4608 if
|
||||
* the sample rate is <= 48000kHz, otherwise, for larger sample rates,
|
||||
* max_block_size must be set to 16384.
|
||||
* @param max_channels is the maximum number of channels that will be decoded.
|
||||
* @return a pointer at the FLAC decoder instance; note that this pointer may be
|
||||
* different from what was passed to mem. However, you may still pass the
|
||||
* original `mem` as `inst` parameter to other functions. Returns NULL if the
|
||||
* input pointer is NULL or the given parameters are invalid.
|
||||
*/
|
||||
FX_EXPORT fx_flac_t *fx_flac_init(void *mem, uint16_t max_block_size,
|
||||
uint8_t max_channels);
|
||||
|
||||
/**
|
||||
* Macro which calls malloc to allocate memory for a new fx_flac instance. The
|
||||
* returned pointer must be freed using free. Returns NULL if the allocation
|
||||
* fails or the given parameters are invalid.
|
||||
*
|
||||
* Note that this code is implemented as a macro to prevent explicitly having
|
||||
* a dependency on malloc while still providing a convenient allocation routine.
|
||||
*/
|
||||
#define FX_FLAC_ALLOC(max_block_size, max_channels) \
|
||||
(fx_flac_size((max_block_size), (max_channels)) == 0U) \
|
||||
? NULL \
|
||||
: fx_flac_init(malloc(fx_flac_size((max_block_size), (max_channels))), \
|
||||
(max_block_size), (max_channels))
|
||||
|
||||
/**
|
||||
* Returns a new fx_flac instance that is sufficient to decode FLAC streams in
|
||||
* the FLAC Subset format with DAT parameters, i.e. up to 48 kHz, and two
|
||||
* channels. This will allocate about 40 kiB of memory.
|
||||
*/
|
||||
#define FX_FLAC_ALLOC_SUBSET_FORMAT_DAT() \
|
||||
FX_FLAC_ALLOC(FLAC_SUBSET_MAX_BLOCK_SIZE_48KHZ, 2U)
|
||||
|
||||
/**
|
||||
* Returns a new fx_flac instance that is sufficient to decode FLAC streams in
|
||||
* the FLAC Subset format. This will allocate about 1.5 MiB of memory.
|
||||
*/
|
||||
#define FX_FLAC_ALLOC_SUBSET_FORMAT_ANY() \
|
||||
FX_FLAC_ALLOC(FLAC_SUBSET_MAX_BLOCK_SIZE, FLAC_MAX_CHANNEL_COUNT)
|
||||
|
||||
/**
|
||||
* Returns a new fx_flac instance that is sufficient to decode any valid FLAC
|
||||
* stream. Note that this will allocate between 2-3 MiB of memory.
|
||||
*/
|
||||
#define FX_FLAC_ALLOC_DEFAULT() \
|
||||
FX_FLAC_ALLOC(FLAC_MAX_BLOCK_SIZE, FLAC_MAX_CHANNEL_COUNT)
|
||||
|
||||
/**
|
||||
* Resets the FLAC decoder.
|
||||
*
|
||||
* @param inst is the FLAC decoder that should be reset.
|
||||
*/
|
||||
FX_EXPORT void fx_flac_reset(fx_flac_t *inst);
|
||||
|
||||
/**
|
||||
* Returns the current decoder state.
|
||||
*
|
||||
* @param inst is the FLAC decoder instance for which the state should be
|
||||
* returned.
|
||||
* @return the current state of the decoder.
|
||||
*/
|
||||
FX_EXPORT fx_flac_state_t fx_flac_get_state(const fx_flac_t *inst);
|
||||
|
||||
/**
|
||||
* Returns metadata about the FLAC stream that is currently being parsed. This
|
||||
* function may only be called if the decoder is in the state
|
||||
* FLAC_END_OF_METADATA or greater, otherwise the result may be undefined
|
||||
* (it will likely return zero for most of the metadata keys).
|
||||
*
|
||||
* @param inst is a pointer at the FLAC decoder instance for which the metadata
|
||||
* should be retrieved.
|
||||
* @param key is the metadata that should be retrieved.
|
||||
* @return the requested metadata value or FLAC_INVALID_METADATA_KEY if the
|
||||
* given key is unknown.
|
||||
*/
|
||||
FX_EXPORT int64_t fx_flac_get_streaminfo(const fx_flac_t *inst,
|
||||
fx_flac_streaminfo_key_t key);
|
||||
|
||||
/**
|
||||
* Decodes the given raw FLAC data; the given data must be RAW FLAC data as
|
||||
* specified in the FLAC format specification https://xiph.org/flac/format.html
|
||||
* This function will always return right after the decoder transitions to a new
|
||||
* relevant state.
|
||||
*
|
||||
* @param inst is the decoder instance.
|
||||
* @param in is a pointer at the encoded bytestream.
|
||||
* @param in_len is a pointer at a integer containing the number of valid bytes
|
||||
* in "in". After the function returns, in will contain the number of bytes that
|
||||
* were actually read. This number may be zero if the decoder is in the FLAC_ERR
|
||||
* or FLAC_STREAM_DONE state, or the internal buffers are full and need to be
|
||||
* flushed to the provided output first.
|
||||
* @param out is a pointer at a memory region that will accept the decoded
|
||||
* interleaved audio data. Samples are decoded as 32-bit signed integer; the
|
||||
* minimum and maximum value will depend on the original bit depth of the audio
|
||||
* stored in the bitstream. If this is NULL, the decoder will silently discard
|
||||
* the output.
|
||||
* @param out_len is a pointer at an integer containing the number of available
|
||||
* signed 32-bit integers at the memory address pointed at by out. After the
|
||||
* function returns, this value will contain the number of samples that were
|
||||
* written. If this is NULL, the deocder will silently discard the output.
|
||||
* @return the current state of the decoder. If the state transitions to
|
||||
* FLAC_END_OF_METADATA, FLAC_END_OF_FRAME or FLAC_END_OF_STREAM this function
|
||||
* will return immediately; only the data up to the point causing the transition
|
||||
* has been read.
|
||||
*/
|
||||
FX_EXPORT fx_flac_state_t fx_flac_process(fx_flac_t *inst, const uint8_t *in,
|
||||
uint32_t *in_len, int32_t *out,
|
||||
uint32_t *out_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* FOXEN_FLAC_H */
|
||||
@@ -0,0 +1,8 @@
|
||||
# Copyright 2023 jacqueline <me@jacqueline.id.au>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
idf_component_register(
|
||||
SRCS "stb_vorbis.c"
|
||||
INCLUDE_DIRS "include"
|
||||
)
|
||||
@@ -0,0 +1,418 @@
|
||||
// Ogg Vorbis audio decoder - v1.22 - public domain
|
||||
// http://nothings.org/stb_vorbis/
|
||||
//
|
||||
// Original version written by Sean Barrett in 2007.
|
||||
//
|
||||
// Originally sponsored by RAD Game Tools. Seeking implementation
|
||||
// sponsored by Phillip Bennefall, Marc Andersen, Aaron Baker,
|
||||
// Elias Software, Aras Pranckevicius, and Sean Barrett.
|
||||
//
|
||||
// LICENSE
|
||||
//
|
||||
// See end of file for license information.
|
||||
//
|
||||
// Limitations:
|
||||
//
|
||||
// - floor 0 not supported (used in old ogg vorbis files pre-2004)
|
||||
// - lossless sample-truncation at beginning ignored
|
||||
// - cannot concatenate multiple vorbis streams
|
||||
// - sample positions are 32-bit, limiting seekable 192Khz
|
||||
// files to around 6 hours (Ogg supports 64-bit)
|
||||
//
|
||||
// Feature contributors:
|
||||
// Dougall Johnson (sample-exact seeking)
|
||||
//
|
||||
// Bugfix/warning contributors:
|
||||
// Terje Mathisen Niklas Frykholm Andy Hill
|
||||
// Casey Muratori John Bolton Gargaj
|
||||
// Laurent Gomila Marc LeBlanc Ronny Chevalier
|
||||
// Bernhard Wodo Evan Balster github:alxprd
|
||||
// Tom Beaumont Ingo Leitgeb Nicolas Guillemot
|
||||
// Phillip Bennefall Rohit Thiago Goulart
|
||||
// github:manxorist Saga Musix github:infatum
|
||||
// Timur Gagiev Maxwell Koo Peter Waller
|
||||
// github:audinowho Dougall Johnson David Reid
|
||||
// github:Clownacy Pedro J. Estebanez Remi Verschelde
|
||||
// AnthoFoxo github:morlat Gabriel Ravier
|
||||
//
|
||||
// Partial history:
|
||||
// 1.22 - 2021-07-11 - various small fixes
|
||||
// 1.21 - 2021-07-02 - fix bug for files with no comments
|
||||
// 1.20 - 2020-07-11 - several small fixes
|
||||
// 1.19 - 2020-02-05 - warnings
|
||||
// 1.18 - 2020-02-02 - fix seek bugs; parse header comments; misc warnings etc.
|
||||
// 1.17 - 2019-07-08 - fix CVE-2019-13217..CVE-2019-13223 (by ForAllSecure)
|
||||
// 1.16 - 2019-03-04 - fix warnings
|
||||
// 1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found
|
||||
// 1.14 - 2018-02-11 - delete bogus dealloca usage
|
||||
// 1.13 - 2018-01-29 - fix truncation of last frame (hopefully)
|
||||
// 1.12 - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
|
||||
// 1.11 - 2017-07-23 - fix MinGW compilation
|
||||
// 1.10 - 2017-03-03 - more robust seeking; fix negative ilog(); clear error in open_memory
|
||||
// 1.09 - 2016-04-04 - back out 'truncation of last frame' fix from previous version
|
||||
// 1.08 - 2016-04-02 - warnings; setup memory leaks; truncation of last frame
|
||||
// 1.07 - 2015-01-16 - fixes for crashes on invalid files; warning fixes; const
|
||||
// 1.06 - 2015-08-31 - full, correct support for seeking API (Dougall Johnson)
|
||||
// some crash fixes when out of memory or with corrupt files
|
||||
// fix some inappropriately signed shifts
|
||||
// 1.05 - 2015-04-19 - don't define __forceinline if it's redundant
|
||||
// 1.04 - 2014-08-27 - fix missing const-correct case in API
|
||||
// 1.03 - 2014-08-07 - warning fixes
|
||||
// 1.02 - 2014-07-09 - declare qsort comparison as explicitly _cdecl in Windows
|
||||
// 1.01 - 2014-06-18 - fix stb_vorbis_get_samples_float (interleaved was correct)
|
||||
// 1.0 - 2014-05-26 - fix memory leaks; fix warnings; fix bugs in >2-channel;
|
||||
// (API change) report sample rate for decode-full-file funcs
|
||||
//
|
||||
// See end of file for full version history.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// HEADER BEGINS HERE
|
||||
//
|
||||
|
||||
#ifndef STB_VORBIS_INCLUDE_STB_VORBIS_H
|
||||
#define STB_VORBIS_INCLUDE_STB_VORBIS_H
|
||||
|
||||
#if defined(STB_VORBIS_NO_CRT) && !defined(STB_VORBIS_NO_STDIO)
|
||||
#define STB_VORBIS_NO_STDIO 1
|
||||
#endif
|
||||
|
||||
#ifndef STB_VORBIS_NO_STDIO
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/////////// THREAD SAFETY
|
||||
|
||||
// Individual stb_vorbis* handles are not thread-safe; you cannot decode from
|
||||
// them from multiple threads at the same time. However, you can have multiple
|
||||
// stb_vorbis* handles and decode from them independently in multiple thrads.
|
||||
|
||||
|
||||
/////////// MEMORY ALLOCATION
|
||||
|
||||
// normally stb_vorbis uses malloc() to allocate memory at startup,
|
||||
// and alloca() to allocate temporary memory during a frame on the
|
||||
// stack. (Memory consumption will depend on the amount of setup
|
||||
// data in the file and how you set the compile flags for speed
|
||||
// vs. size. In my test files the maximal-size usage is ~150KB.)
|
||||
//
|
||||
// You can modify the wrapper functions in the source (setup_malloc,
|
||||
// setup_temp_malloc, temp_malloc) to change this behavior, or you
|
||||
// can use a simpler allocation model: you pass in a buffer from
|
||||
// which stb_vorbis will allocate _all_ its memory (including the
|
||||
// temp memory). "open" may fail with a VORBIS_outofmem if you
|
||||
// do not pass in enough data; there is no way to determine how
|
||||
// much you do need except to succeed (at which point you can
|
||||
// query get_info to find the exact amount required. yes I know
|
||||
// this is lame).
|
||||
//
|
||||
// If you pass in a non-NULL buffer of the type below, allocation
|
||||
// will occur from it as described above. Otherwise just pass NULL
|
||||
// to use malloc()/alloca()
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *alloc_buffer;
|
||||
int alloc_buffer_length_in_bytes;
|
||||
} stb_vorbis_alloc;
|
||||
|
||||
|
||||
/////////// FUNCTIONS USEABLE WITH ALL INPUT MODES
|
||||
|
||||
typedef struct stb_vorbis stb_vorbis;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int sample_rate;
|
||||
int channels;
|
||||
|
||||
unsigned int setup_memory_required;
|
||||
unsigned int setup_temp_memory_required;
|
||||
unsigned int temp_memory_required;
|
||||
|
||||
int max_frame_size;
|
||||
} stb_vorbis_info;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *vendor;
|
||||
|
||||
int comment_list_length;
|
||||
char **comment_list;
|
||||
} stb_vorbis_comment;
|
||||
|
||||
// get general information about the file
|
||||
extern stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f);
|
||||
|
||||
// get ogg comments
|
||||
extern stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis *f);
|
||||
|
||||
// get the last error detected (clears it, too)
|
||||
extern int stb_vorbis_get_error(stb_vorbis *f);
|
||||
|
||||
// close an ogg vorbis file and free all memory in use
|
||||
extern void stb_vorbis_close(stb_vorbis *f);
|
||||
|
||||
// this function returns the offset (in samples) from the beginning of the
|
||||
// file that will be returned by the next decode, if it is known, or -1
|
||||
// otherwise. after a flush_pushdata() call, this may take a while before
|
||||
// it becomes valid again.
|
||||
// NOT WORKING YET after a seek with PULLDATA API
|
||||
extern int stb_vorbis_get_sample_offset(stb_vorbis *f);
|
||||
|
||||
// returns the current seek point within the file, or offset from the beginning
|
||||
// of the memory buffer. In pushdata mode it returns 0.
|
||||
extern unsigned int stb_vorbis_get_file_offset(stb_vorbis *f);
|
||||
|
||||
/////////// PUSHDATA API
|
||||
|
||||
#ifndef STB_VORBIS_NO_PUSHDATA_API
|
||||
|
||||
// this API allows you to get blocks of data from any source and hand
|
||||
// them to stb_vorbis. you have to buffer them; stb_vorbis will tell
|
||||
// you how much it used, and you have to give it the rest next time;
|
||||
// and stb_vorbis may not have enough data to work with and you will
|
||||
// need to give it the same data again PLUS more. Note that the Vorbis
|
||||
// specification does not bound the size of an individual frame.
|
||||
|
||||
extern stb_vorbis *stb_vorbis_open_pushdata(
|
||||
const unsigned char * datablock, int datablock_length_in_bytes,
|
||||
int *datablock_memory_consumed_in_bytes,
|
||||
int *error,
|
||||
const stb_vorbis_alloc *alloc_buffer);
|
||||
// create a vorbis decoder by passing in the initial data block containing
|
||||
// the ogg&vorbis headers (you don't need to do parse them, just provide
|
||||
// the first N bytes of the file--you're told if it's not enough, see below)
|
||||
// on success, returns an stb_vorbis *, does not set error, returns the amount of
|
||||
// data parsed/consumed on this call in *datablock_memory_consumed_in_bytes;
|
||||
// on failure, returns NULL on error and sets *error, does not change *datablock_memory_consumed
|
||||
// if returns NULL and *error is VORBIS_need_more_data, then the input block was
|
||||
// incomplete and you need to pass in a larger block from the start of the file
|
||||
|
||||
extern int stb_vorbis_decode_frame_pushdata(
|
||||
stb_vorbis *f,
|
||||
const unsigned char *datablock, int datablock_length_in_bytes,
|
||||
int *channels, // place to write number of float * buffers
|
||||
float ***output, // place to write float ** array of float * buffers
|
||||
int *samples // place to write number of output samples
|
||||
);
|
||||
// decode a frame of audio sample data if possible from the passed-in data block
|
||||
//
|
||||
// return value: number of bytes we used from datablock
|
||||
//
|
||||
// possible cases:
|
||||
// 0 bytes used, 0 samples output (need more data)
|
||||
// N bytes used, 0 samples output (resynching the stream, keep going)
|
||||
// N bytes used, M samples output (one frame of data)
|
||||
// note that after opening a file, you will ALWAYS get one N-bytes,0-sample
|
||||
// frame, because Vorbis always "discards" the first frame.
|
||||
//
|
||||
// Note that on resynch, stb_vorbis will rarely consume all of the buffer,
|
||||
// instead only datablock_length_in_bytes-3 or less. This is because it wants
|
||||
// to avoid missing parts of a page header if they cross a datablock boundary,
|
||||
// without writing state-machiney code to record a partial detection.
|
||||
//
|
||||
// The number of channels returned are stored in *channels (which can be
|
||||
// NULL--it is always the same as the number of channels reported by
|
||||
// get_info). *output will contain an array of float* buffers, one per
|
||||
// channel. In other words, (*output)[0][0] contains the first sample from
|
||||
// the first channel, and (*output)[1][0] contains the first sample from
|
||||
// the second channel.
|
||||
//
|
||||
// *output points into stb_vorbis's internal output buffer storage; these
|
||||
// buffers are owned by stb_vorbis and application code should not free
|
||||
// them or modify their contents. They are transient and will be overwritten
|
||||
// once you ask for more data to get decoded, so be sure to grab any data
|
||||
// you need before then.
|
||||
|
||||
extern void stb_vorbis_flush_pushdata(stb_vorbis *f);
|
||||
// inform stb_vorbis that your next datablock will not be contiguous with
|
||||
// previous ones (e.g. you've seeked in the data); future attempts to decode
|
||||
// frames will cause stb_vorbis to resynchronize (as noted above), and
|
||||
// once it sees a valid Ogg page (typically 4-8KB, as large as 64KB), it
|
||||
// will begin decoding the _next_ frame.
|
||||
//
|
||||
// if you want to seek using pushdata, you need to seek in your file, then
|
||||
// call stb_vorbis_flush_pushdata(), then start calling decoding, then once
|
||||
// decoding is returning you data, call stb_vorbis_get_sample_offset, and
|
||||
// if you don't like the result, seek your file again and repeat.
|
||||
#endif
|
||||
|
||||
|
||||
////////// PULLING INPUT API
|
||||
|
||||
#ifndef STB_VORBIS_NO_PULLDATA_API
|
||||
// This API assumes stb_vorbis is allowed to pull data from a source--
|
||||
// either a block of memory containing the _entire_ vorbis stream, or a
|
||||
// FILE * that you or it create, or possibly some other reading mechanism
|
||||
// if you go modify the source to replace the FILE * case with some kind
|
||||
// of callback to your code. (But if you don't support seeking, you may
|
||||
// just want to go ahead and use pushdata.)
|
||||
|
||||
#if !defined(STB_VORBIS_NO_STDIO) && !defined(STB_VORBIS_NO_INTEGER_CONVERSION)
|
||||
extern int stb_vorbis_decode_filename(const char *filename, int *channels, int *sample_rate, short **output);
|
||||
#endif
|
||||
#if !defined(STB_VORBIS_NO_INTEGER_CONVERSION)
|
||||
extern int stb_vorbis_decode_memory(const unsigned char *mem, int len, int *channels, int *sample_rate, short **output);
|
||||
#endif
|
||||
// decode an entire file and output the data interleaved into a malloc()ed
|
||||
// buffer stored in *output. The return value is the number of samples
|
||||
// decoded, or -1 if the file could not be opened or was not an ogg vorbis file.
|
||||
// When you're done with it, just free() the pointer returned in *output.
|
||||
|
||||
extern stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len,
|
||||
int *error, const stb_vorbis_alloc *alloc_buffer);
|
||||
// create an ogg vorbis decoder from an ogg vorbis stream in memory (note
|
||||
// this must be the entire stream!). on failure, returns NULL and sets *error
|
||||
|
||||
#ifndef STB_VORBIS_NO_STDIO
|
||||
extern stb_vorbis * stb_vorbis_open_filename(const char *filename,
|
||||
int *error, const stb_vorbis_alloc *alloc_buffer);
|
||||
// create an ogg vorbis decoder from a filename via fopen(). on failure,
|
||||
// returns NULL and sets *error (possibly to VORBIS_file_open_failure).
|
||||
|
||||
extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close,
|
||||
int *error, const stb_vorbis_alloc *alloc_buffer);
|
||||
// create an ogg vorbis decoder from an open FILE *, looking for a stream at
|
||||
// the _current_ seek point (ftell). on failure, returns NULL and sets *error.
|
||||
// note that stb_vorbis must "own" this stream; if you seek it in between
|
||||
// calls to stb_vorbis, it will become confused. Moreover, if you attempt to
|
||||
// perform stb_vorbis_seek_*() operations on this file, it will assume it
|
||||
// owns the _entire_ rest of the file after the start point. Use the next
|
||||
// function, stb_vorbis_open_file_section(), to limit it.
|
||||
|
||||
extern stb_vorbis * stb_vorbis_open_file_section(FILE *f, int close_handle_on_close,
|
||||
int *error, const stb_vorbis_alloc *alloc_buffer, unsigned int len);
|
||||
// create an ogg vorbis decoder from an open FILE *, looking for a stream at
|
||||
// the _current_ seek point (ftell); the stream will be of length 'len' bytes.
|
||||
// on failure, returns NULL and sets *error. note that stb_vorbis must "own"
|
||||
// this stream; if you seek it in between calls to stb_vorbis, it will become
|
||||
// confused.
|
||||
#endif
|
||||
|
||||
extern int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number);
|
||||
extern int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number);
|
||||
// these functions seek in the Vorbis file to (approximately) 'sample_number'.
|
||||
// after calling seek_frame(), the next call to get_frame_*() will include
|
||||
// the specified sample. after calling stb_vorbis_seek(), the next call to
|
||||
// stb_vorbis_get_samples_* will start with the specified sample. If you
|
||||
// do not need to seek to EXACTLY the target sample when using get_samples_*,
|
||||
// you can also use seek_frame().
|
||||
|
||||
extern int stb_vorbis_seek_start(stb_vorbis *f);
|
||||
// this function is equivalent to stb_vorbis_seek(f,0)
|
||||
|
||||
extern unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f);
|
||||
extern float stb_vorbis_stream_length_in_seconds(stb_vorbis *f);
|
||||
// these functions return the total length of the vorbis stream
|
||||
|
||||
extern int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output);
|
||||
// decode the next frame and return the number of samples. the number of
|
||||
// channels returned are stored in *channels (which can be NULL--it is always
|
||||
// the same as the number of channels reported by get_info). *output will
|
||||
// contain an array of float* buffers, one per channel. These outputs will
|
||||
// be overwritten on the next call to stb_vorbis_get_frame_*.
|
||||
//
|
||||
// You generally should not intermix calls to stb_vorbis_get_frame_*()
|
||||
// and stb_vorbis_get_samples_*(), since the latter calls the former.
|
||||
|
||||
#ifndef STB_VORBIS_NO_INTEGER_CONVERSION
|
||||
extern int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts);
|
||||
extern int stb_vorbis_get_frame_short (stb_vorbis *f, int num_c, short **buffer, int num_samples);
|
||||
#endif
|
||||
// decode the next frame and return the number of *samples* per channel.
|
||||
// Note that for interleaved data, you pass in the number of shorts (the
|
||||
// size of your array), but the return value is the number of samples per
|
||||
// channel, not the total number of samples.
|
||||
//
|
||||
// The data is coerced to the number of channels you request according to the
|
||||
// channel coercion rules (see below). You must pass in the size of your
|
||||
// buffer(s) so that stb_vorbis will not overwrite the end of the buffer.
|
||||
// The maximum buffer size needed can be gotten from get_info(); however,
|
||||
// the Vorbis I specification implies an absolute maximum of 4096 samples
|
||||
// per channel.
|
||||
|
||||
// Channel coercion rules:
|
||||
// Let M be the number of channels requested, and N the number of channels present,
|
||||
// and Cn be the nth channel; let stereo L be the sum of all L and center channels,
|
||||
// and stereo R be the sum of all R and center channels (channel assignment from the
|
||||
// vorbis spec).
|
||||
// M N output
|
||||
// 1 k sum(Ck) for all k
|
||||
// 2 * stereo L, stereo R
|
||||
// k l k > l, the first l channels, then 0s
|
||||
// k l k <= l, the first k channels
|
||||
// Note that this is not _good_ surround etc. mixing at all! It's just so
|
||||
// you get something useful.
|
||||
|
||||
extern int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats);
|
||||
extern int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples);
|
||||
// gets num_samples samples, not necessarily on a frame boundary--this requires
|
||||
// buffering so you have to supply the buffers. DOES NOT APPLY THE COERCION RULES.
|
||||
// Returns the number of samples stored per channel; it may be less than requested
|
||||
// at the end of the file. If there are no more samples in the file, returns 0.
|
||||
|
||||
#ifndef STB_VORBIS_NO_INTEGER_CONVERSION
|
||||
extern int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts);
|
||||
extern int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int num_samples);
|
||||
#endif
|
||||
// gets num_samples samples, not necessarily on a frame boundary--this requires
|
||||
// buffering so you have to supply the buffers. Applies the coercion rules above
|
||||
// to produce 'channels' channels. Returns the number of samples stored per channel;
|
||||
// it may be less than requested at the end of the file. If there are no more
|
||||
// samples in the file, returns 0.
|
||||
|
||||
#endif
|
||||
|
||||
//////// ERROR CODES
|
||||
|
||||
enum STBVorbisError
|
||||
{
|
||||
VORBIS__no_error,
|
||||
|
||||
VORBIS_need_more_data=1, // not a real error
|
||||
|
||||
VORBIS_invalid_api_mixing, // can't mix API modes
|
||||
VORBIS_outofmem, // not enough memory
|
||||
VORBIS_feature_not_supported, // uses floor 0
|
||||
VORBIS_too_many_channels, // STB_VORBIS_MAX_CHANNELS is too small
|
||||
VORBIS_file_open_failure, // fopen() failed
|
||||
VORBIS_seek_without_length, // can't seek in unknown-length file
|
||||
|
||||
VORBIS_unexpected_eof=10, // file is truncated?
|
||||
VORBIS_seek_invalid, // seek past EOF
|
||||
|
||||
// decoding errors (corrupt/invalid stream) -- you probably
|
||||
// don't care about the exact details of these
|
||||
|
||||
// vorbis errors:
|
||||
VORBIS_invalid_setup=20,
|
||||
VORBIS_invalid_stream,
|
||||
|
||||
// ogg errors:
|
||||
VORBIS_missing_capture_pattern=30,
|
||||
VORBIS_invalid_stream_structure_version,
|
||||
VORBIS_continued_packet_flag_invalid,
|
||||
VORBIS_incorrect_stream_serial_number,
|
||||
VORBIS_invalid_first_page,
|
||||
VORBIS_bad_packet_type,
|
||||
VORBIS_cant_find_last_page,
|
||||
VORBIS_seek_failed,
|
||||
VORBIS_ogg_skeleton_not_supported
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // STB_VORBIS_INCLUDE_STB_VORBIS_H
|
||||
//
|
||||
// HEADER ENDS HERE
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user