Unverified Commit 4fbfe730 authored by Wolle's avatar Wolle Committed by GitHub

impl. VORBIS decoder

tested:
http://play.global.audio/bgradio_low.ogg
http://play.global.audio/veronika_low.ogg
http://play.global.audio/nrj_low.ogg
http://icecast.ithost.it:8000/radiosei.ogg // (mp3)
http://icecast.ithost.it:8000/retesport.ogg // (mp3)
http://play.global.audio/radio1rock_low.ogg
http://play.global.audio/city_low.ogg
http://amp1.cesnet.cz:8000/cro1-256.ogg
http://stream2.dancewave.online:8080/dance.ogg
http://stream.lazaradio.com:8100/live.ogg
http://icecast.ithost.it:8000/radioromacapitale.ogg
http://207.162.185.111:8000/kastor
http://stream.punkrockers-radio.de:8000/prr.ogg
http://stream.wuvt.vt.edu/wuvt.ogg
http://radio.el-stacja.pl:8000/elstacjaap320.ogg // EL-Stacja
http://91.121.159.124:8000/eko-des-garrigues-256k.ogg
http://stream.streamaudio.de:8000/happy-fm
http://metronom.live:8000/stream.ogg
http://listen.42fm.ru:8000/stealkill-8.0.ogg
http://amp1.cesnet.cz:8000/cro-radio-junior-256.ogg
http://streaming.domainepublic.net:8000/radioairlibre.ogg
http://www.1431am.org:8000/1431ogg
http://stream-bg-01.radiotangra.com:8000/Tangra.ogg
http://radio.madplaylist.com/stream  // Media Afro Dissident (MAD-Playlist (Radio))
http://streaming.radiodancefloor.it:8000/live.vorbis // Radio Dancefloor - 90's
http://azuracast.tilderadio.org:8000/radio.ogg
http://alex-radio.rosebud-media.de/alex-radio-low.ogg
http://amp1.cesnet.cz:8000/cro3.ogg
http://radio.streamings.gr:8003/stream
http://stream4.dancewave.online:8080/retrodance.ogg
http://168.119.74.185:9444/live.ogg  // BLACK LIVE 500 LYK
http://bitsmitter.com:8006/omr.ogg  // Offshore Music Radio
http://play.global.audio/novanews.ogg  // Nova NEWS
http://eu.ec2.powerfm.org:8000/powerfm.ogg
http://radio.it-sis.ru:8000/live // DeusEx Radio Station Chelyabinsk 
http://live.coolradio.rs/cool.ogg // 
http://amp1.cesnet.cz:8000/cro-plus-256.ogg // CRo Plus
parent 04ff609d
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
//**************************
// D U M M Y
//**************************
#pragma once
#include <stdint.h>
#define ERR_VORBIS_NONE 0
#define ERR_VORBIS_CHANNELS_OUT_OF_RANGE 1
#define ERR_VORBIS_INVALID_SAMPLERATE 2
#define ERR_VORBIS_EXTRA_CHANNELS_UNSUPPORTED 3
#define ERR_VORBIS_DECODER_ASYNC 4
#define ERR_VORBIS_OGG_SYNC_NOT_FOUND 5
#define ERR_VORBIS_BAD_HEADER 6
#define ERR_VORBIS_NOT_AUDIO 7
#define ERR_VORBIS_BAD_PACKET 8
void VORBISDecoder_FreeBuffers(){;}
int VORBISDecoder_AllocateBuffers(){return 0;}
int VORBISFindSyncWord(uint8_t* data, uint16_t len){return 0;}
int VORBISGetSampRate(){return 0;}
int VORBISGetBitsPerSample(){return 0;}
int VORBISGetBitRate(){return 0;}
int VORBISDecode(uint8_t* data, int* bytesLeft, int16_t* m_outBuff){return 0;}
int VORBISGetOutputSamps(){return 0;}
char* VORBISgetStreamTitle(){return nullptr;}
int VORBISGetChannels(){return 0;}
\ No newline at end of file
//#pragma GCC optimize ("O3")
//#pragma GCC diagnostic ignored "-Wnarrowing"
#include "Arduino.h"
#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_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};
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;
int q_minp;
int32_t q_del;
int q_delp;
int q_seq;
int 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<<n poss) */
uint8_t class_book; /* subs ^ dim entries */
uint8_t class_subbook[8]; /* [VIF_CLASS][subs] */
} floor1class_t;
typedef struct{
int order;
int32_t rate;
int32_t barkmap;
int ampbits;
int ampdB;
int numbooks; /* <= 16 */
char books[16];
floor1class_t *_class; /* [VIF_CLASS] */
uint8_t *partitionclass; /* [VIF_PARTS]; 0 to 15 */
uint16_t *postlist; /* [VIF_POSIT+2]; first two implicit */
uint8_t *forward_index; /* [VIF_POSIT+2]; */
uint8_t *hineighbor; /* [VIF_POSIT]; */
uint8_t *loneighbor; /* [VIF_POSIT]; */
int partitions; /* 0 to 31 */
int posts;
int mult; /* 1 2 3 or 4 */
} vorbis_info_floor_t;
typedef struct _vorbis_info_residue {
int type;
uint8_t *stagemasks;
uint8_t *stagebooks;
/* block-partitioned VQ coded straight residue */
uint32_t begin;
uint32_t end;
/* first stage (lossless partitioning) */
uint32_t grouping; /* group n vectors per partition */
char partitions; /* possible codebooks for a partition */
uint8_t groupbook; /* huffbook for partitioning */
char stages;
} vorbis_info_residue_t;
typedef struct _submap{
char floor;
char residue;
} submap_t;
typedef struct _coupling_step{ // Mapping backend generic
uint8_t mag;
uint8_t ang;
} coupling_step_t;
typedef struct _vorbis_info_mapping{
int submaps;
uint8_t *chmuxlist;
submap_t *submaplist;
int coupling_steps;
coupling_step_t *coupling;
} vorbis_info_mapping_t;
typedef struct { // mode
uint8_t blockflag;
uint8_t mapping;
} vorbis_info_mode_t;
typedef struct _vorbis_dsp_state{ // vorbis_dsp_state buffers the current vorbis audio analysis/synthesis state.
// vorbis_info *vi; // The DSP state be int32_ts to a specific logical bitstream
// oggpack_buffer_t opb;
int32_t **work;
int32_t **mdctright;
int out_begin;
int out_end;
int32_t lW; // last window
uint32_t W; // Window
} vorbis_dsp_state_t;
typedef struct _bitreader{
uint8_t *data;
uint8_t length;
uint16_t headbit;
uint8_t *headptr;
int headend;
} bitReader_t;
//----------------------------------------------------------------------------------------------------------------------
union magic{
struct{
int32_t lo;
int32_t hi;
} halves;
int64_t whole;
};
inline int32_t MULT32(int32_t x, int32_t y) {
union magic magic;
magic.whole = (int64_t)x * y;
return magic.halves.hi;
}
inline int32_t MULT31_SHIFT15(int32_t x, int32_t y) {
union magic magic;
magic.whole = (int64_t)x * y;
return ((uint32_t)(magic.halves.lo) >> 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) {
int 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();
int VORBISDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf);
uint8_t VORBISGetChannels();
uint32_t VORBISGetSampRate();
uint8_t VORBISGetBitsPerSample();
uint32_t VORBISGetBitRate();
uint16_t VORBISGetOutputSamps();
char *VORBISgetStreamTitle();
int VORBISFindSyncWord(unsigned char *buf, int nBytes);
int VORBISparseOGG(uint8_t *inbuf, int *bytesLeft);
int parseVorbisComment(uint8_t *inbuf, int16_t nBytes);
int parseVorbisCodebook();
int parseVorbisFirstPacket(uint8_t *inbuf, int16_t nBytes);
uint16_t continuedOggPackets(uint8_t *inbuf, int *bytesLeft);
int vorbis_book_unpack(codebook_t *s);
uint32_t decpack(int32_t entry, int32_t used_entry, uint8_t quantvals, codebook_t *b, int maptype);
int oggpack_eop();
vorbis_info_floor_t* floor0_info_unpack();
vorbis_info_floor_t* floor1_info_unpack();
int res_unpack(vorbis_info_residue_t *info);
int 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
int 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(int n, int32_t *in, int32_t *right);
int mapping_inverse(vorbis_info_mapping_t *info);
int floor0_memosize(vorbis_info_floor_t *i);
int 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);
uint32_t decode_packed_entry_number(codebook_t *book);
int render_point(int x0, int x1, int y0, int y1, int x);
int32_t vorbis_book_decodev_set(codebook_t *book, int32_t *a, int n, int point);
int decode_map(codebook_t *s, int32_t *v, int point);
int res_inverse(vorbis_info_residue_t *info, int32_t **in, int *nonzero, uint8_t ch);
int32_t vorbis_book_decodev_add(codebook_t *book, int32_t *a, int n, int point);
int32_t vorbis_book_decodevs_add(codebook_t *book, int32_t *a, int n, int point);
int floor0_inverse2(vorbis_info_floor_t *i, int32_t *lsp, int32_t *out);
int floor1_inverse2(vorbis_info_floor_t *in, int32_t *fit_value, int32_t *out);
void render_line(int n, int x0, int x1, int y0, int y1, int32_t *d);
void vorbis_lsp_to_curve(int32_t *curve, int n, int ln, int32_t *lsp, int m, int32_t amp, int32_t ampoffset, int32_t nyq);
int32_t toBARK(int 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(int n, int32_t *in);
void presymmetry(int32_t *in, int n2, int step);
void mdct_butterflies(int32_t *x, int points, int shift);
void mdct_butterfly_generic(int32_t *x, int points, int 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, int n, int shift);
int bitrev12(int x);
void mdct_step7(int32_t *x, int n, int step);
void mdct_step8(int32_t *x, int n, int step);
int32_t vorbis_book_decodevv_add(codebook_t *book, int32_t **a, int32_t offset, uint8_t ch, int n, int point);
int vorbis_dsp_pcmout(int16_t *outBuff, int outBuffSize);
void mdct_unroll_lap(int n0, int n1, int lW, int W, int *in, int *right, const int *w0, const int *w1, short int *out,
int step, int start, /* samples, this frame */
int end /* samples, this frame */);
// some helper functions
int VORBIS_specialIndexOf(uint8_t* base, const char* str, int 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);
void bitReader_adv(uint16_t bits);
uint8_t _ilog(uint32_t v);
int ilog(uint32_t v);
int32_t _float32_unpack(int32_t val, int *point);
int _determine_node_bytes(uint32_t used, uint8_t leafwidth);
int _determine_leaf_words(int nodeb, int leafwidth);
int _make_decode_table(codebook_t *s, char *lengthlist, uint8_t quantvals, int maptype);
int _make_words(char *l, uint16_t n, uint32_t *r, uint8_t quantvals, codebook_t *b, int maptype);
uint8_t _book_maptype1_quantvals(codebook_t *b);
void vorbis_book_clear(codebook_t *b);
int32_t *_vorbis_window(int left);
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment