#pragma once //#pragma GCC optimize ("O3") //#pragma GCC diagnostic ignored "-Wnarrowing" /******************************************************************** * * * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * * by the Xiph.Org Foundation https://xiph.org/ * * * ********************************************************************/ /* * vorbis_decoder.h * based on Xiph.Org Foundation vorbis decoder * adapted for the ESP32 by schreibfaul1 * * Created on: 13.02.2023 * Updated on: 03.04.2024 */ #include "Arduino.h" #include using namespace std; #define VI_FLOORB 2 #define VIF_POSIT 63 #define LSP_FRACBITS 14 #define OV_EREAD -128 #define OV_EFAULT -129 #define OV_EIMPL -130 #define OV_EINVAL -131 #define OV_ENOTVORBIS -132 #define OV_EBADHEADER -133 #define OV_EVERSION -134 #define OV_ENOTAUDIO -135 #define OV_EBADPACKET -136 #define OV_EBADLINK -137 #define OV_ENOSEEK -138 #define INVSQ_LOOKUP_I_SHIFT 10 #define INVSQ_LOOKUP_I_MASK 1023 #define COS_LOOKUP_I_SHIFT 9 #define COS_LOOKUP_I_MASK 511 #define COS_LOOKUP_I_SZ 128 #define cPI3_8 (0x30fbc54d) #define cPI2_8 (0x5a82799a) #define cPI1_8 (0x7641af3d) enum : int8_t {VORBIS_CONTINUE = 110, VORBIS_PARSE_OGG_DONE = 100, ERR_VORBIS_NONE = 0, ERR_VORBIS_CHANNELS_OUT_OF_RANGE = -1, ERR_VORBIS_INVALID_SAMPLERATE = -2, ERR_VORBIS_EXTRA_CHANNELS_UNSUPPORTED = -3, ERR_VORBIS_DECODER_ASYNC = -4, ERR_VORBIS_OGG_SYNC_NOT_FOUND = - 5, ERR_VORBIS_BAD_HEADER = -6, ERR_VORBIS_NOT_AUDIO = -7, ERR_VORBIS_BAD_PACKET = -8 }; typedef struct _codebook{ uint8_t dim; /* codebook dimensions (elements per vector) */ int16_t entries; /* codebook entries */ uint16_t used_entries; /* populated codebook entries */ uint32_t dec_maxlength; void *dec_table; uint32_t dec_nodeb; uint32_t dec_leafw; uint32_t dec_type; /* 0 = entry number 1 = packed vector of values 2 = packed vector of column offsets, maptype 1 3 = scalar offset into value array, maptype 2 */ int32_t q_min; int32_t q_minp; int32_t q_del; int32_t q_delp; int32_t q_seq; int32_t q_bits; uint8_t q_pack; void *q_val; } codebook_t; typedef struct{ char class_dim; /* 1 to 8 */ char class_subs; /* 0,1,2,3 (bits: 1<> 15) | ((magic.halves.hi) << 17); } inline int32_t MULT31(int32_t x, int32_t y) { return MULT32(x, y) << 1; } inline void XPROD31(int32_t a, int32_t b, int32_t t, int32_t v, int32_t *x, int32_t *y) { *x = MULT31(a, t) + MULT31(b, v); *y = MULT31(b, t) - MULT31(a, v); } inline void XNPROD31(int32_t a, int32_t b, int32_t t, int32_t v, int32_t *x, int32_t *y) { *x = MULT31(a, t) - MULT31(b, v); *y = MULT31(b, t) + MULT31(a, v); } inline int32_t CLIP_TO_15(int32_t x) { int32_t ret = x; ret -= ((x <= 32767) - 1) & (x - 32767); ret -= ((x >= -32768) - 1) & (x + 32768); return (ret); } //---------------------------------------------------------------------------------------------------------------------- // ogg impl bool VORBISDecoder_AllocateBuffers(); void VORBISDecoder_FreeBuffers(); void VORBISDecoder_ClearBuffers(); void VORBISsetDefaults(); void clearGlobalConfigurations(); int32_t VORBISDecode(uint8_t* inbuf, int32_t* bytesLeft, int16_t* outbuf); uint8_t VORBISGetChannels(); uint32_t VORBISGetSampRate(); uint32_t VORBISGetAudioDataStart(); uint8_t VORBISGetBitsPerSample(); uint32_t VORBISGetBitRate(); uint16_t VORBISGetOutputSamps(); char* VORBISgetStreamTitle(); vector VORBISgetMetadataBlockPicture(); int32_t VORBISFindSyncWord(unsigned char* buf, int32_t nBytes); int32_t VORBISparseOGG(uint8_t* inbuf, int32_t* bytesLeft); int32_t vorbisDecodePage1(uint8_t* inbuf, int32_t* bytesLeft, uint32_t segmentLength); int32_t vorbisDecodePage2(uint8_t* inbuf, int32_t* bytesLeft, uint32_t segmentLength); int32_t vorbisDecodePage3(uint8_t* inbuf, int32_t* bytesLeft, uint32_t segmentLength); int32_t vorbisDecodePage4(uint8_t* inbuf, int32_t* bytesLeft, uint32_t segmentLength, int16_t* outbuf); int32_t parseVorbisComment(uint8_t* inbuf, int16_t nBytes); int32_t parseVorbisCodebook(); int32_t parseVorbisFirstPacket(uint8_t* inbuf, int16_t nBytes); uint16_t continuedOggPackets(uint8_t* inbuf); int32_t vorbis_book_unpack(codebook_t* s); uint32_t decpack(int32_t entry, int32_t used_entry, uint8_t quantvals, codebook_t* b, int32_t maptype); int32_t oggpack_eop(); vorbis_info_floor_t* floor0_info_unpack(); vorbis_info_floor_t* floor1_info_unpack(); int32_t res_unpack(vorbis_info_residue_t* info); int32_t mapping_info_unpack(vorbis_info_mapping_t* info); void vorbis_mergesort(uint8_t* index, uint16_t* vals, uint16_t n); void floor_free_info(vorbis_info_floor_t* i); void res_clear_info(vorbis_info_residue_t* info); void mapping_clear_info(vorbis_info_mapping_t* info); // vorbis decoder impl int32_t vorbis_dsp_synthesis(uint8_t* inbuf, uint16_t len, int16_t* outbuf); vorbis_dsp_state_t* vorbis_dsp_create(); void vorbis_dsp_destroy(vorbis_dsp_state_t* v); void mdct_shift_right(int32_t n, int32_t* in, int32_t* right); int32_t mapping_inverse(vorbis_info_mapping_t* info); int32_t floor0_memosize(vorbis_info_floor_t* i); int32_t floor1_memosize(vorbis_info_floor_t* i); int32_t* floor0_inverse1(vorbis_info_floor_t* i, int32_t* lsp); int32_t* floor1_inverse1(vorbis_info_floor_t* in, int32_t* fit_value); int32_t vorbis_book_decode(codebook_t* book); int32_t decode_packed_entry_number(codebook_t* book); int32_t render_point(int32_t x0, int32_t x1, int32_t y0, int32_t y1, int32_t x); int32_t vorbis_book_decodev_set(codebook_t* book, int32_t* a, int32_t n, int32_t point); int32_t decode_map(codebook_t* s, int32_t* v, int32_t point); int32_t res_inverse(vorbis_info_residue_t* info, int32_t** in, int32_t* nonzero, uint8_t ch); int32_t vorbis_book_decodev_add(codebook_t* book, int32_t* a, int32_t n, int32_t point); int32_t vorbis_book_decodevs_add(codebook_t* book, int32_t* a, int32_t n, int32_t point); int32_t floor0_inverse2(vorbis_info_floor_t* i, int32_t* lsp, int32_t* out); int32_t floor1_inverse2(vorbis_info_floor_t* in, int32_t* fit_value, int32_t* out); void render_line(int32_t n, int32_t x0, int32_t x1, int32_t y0, int32_t y1, int32_t* d); void vorbis_lsp_to_curve(int32_t* curve, int32_t n, int32_t ln, int32_t* lsp, int32_t m, int32_t amp, int32_t ampoffset, int32_t nyq); int32_t toBARK(int32_t n); int32_t vorbis_coslook_i(int32_t a); int32_t vorbis_coslook2_i(int32_t a); int32_t vorbis_fromdBlook_i(int32_t a); int32_t vorbis_invsqlook_i(int32_t a, int32_t e); void mdct_backward(int32_t n, int32_t* in); void presymmetry(int32_t* in, int32_t n2, int32_t step); void mdct_butterflies(int32_t* x, int32_t points, int32_t shift); void mdct_butterfly_generic(int32_t* x, int32_t points, int32_t step); void mdct_butterfly_32(int32_t* x); void mdct_butterfly_16(int32_t* x); void mdct_butterfly_8(int32_t* x); void mdct_bitreverse(int32_t* x, int32_t n, int32_t shift); int32_t bitrev12(int32_t x); void mdct_step7(int32_t* x, int32_t n, int32_t step); void mdct_step8(int32_t* x, int32_t n, int32_t step); int32_t vorbis_book_decodevv_add(codebook_t* book, int32_t** a, int32_t offset, uint8_t ch, int32_t n, int32_t point); int32_t vorbis_dsp_pcmout(int16_t* outBuff, int32_t outBuffSize); void mdct_unroll_lap(int32_t n0, int32_t n1, int32_t lW, int32_t W, int32_t* in, int32_t* right, const int32_t* w0, const int32_t* w1, int16_t* out, int32_t step, int32_t start, /* samples, this frame */ int32_t end /* samples, this frame */); // some helper functions int32_t VORBIS_specialIndexOf(uint8_t* base, const char* str, int32_t baselen, bool exact = false); void bitReader_clear(); void bitReader_setData(uint8_t *buff, uint16_t buffSize); int32_t bitReader(uint16_t bits); int32_t bitReader_look(uint16_t nBits); int8_t bitReader_adv(uint16_t bits); uint8_t _ilog(uint32_t v); int32_t ilog(uint32_t v); int32_t _float32_unpack(int32_t val, int32_t *point); int32_t _determine_node_bytes(uint32_t used, uint8_t leafwidth); int32_t _determine_leaf_words(int32_t nodeb, int32_t leafwidth); int32_t _make_decode_table(codebook_t *s, char *lengthlist, uint8_t quantvals, int32_t maptype); int32_t _make_words(char *l, uint16_t n, uint32_t *r, uint8_t quantvals, codebook_t *b, int32_t maptype); uint8_t _book_maptype1_quantvals(codebook_t *b); void vorbis_book_clear(codebook_t *b); int32_t *_vorbis_window(int32_t left);