FastLED 3.9.15
Loading...
Searching...
No Matches

◆ vorbis_decode_packet_rest()

static int32_t fl::third_party::vorbis::vorbis_decode_packet_rest ( vorb * f,
int32_t * len,
Mode * m,
int32_t left_start,
int32_t left_end,
int32_t right_start,
int32_t right_end,
int32_t * p_left )
static

Definition at line 2910 of file stb_vorbis.cpp.hpp.

2911{
2912 Mapping *map;
2913 int32_t i,j,k,n,n2;
2914 int32_t zero_channel[256];
2915 int32_t really_zero_channel[256];
2916
2917// WINDOWING
2918
2919 FL_UNUSED(left_end);
2920 n = f->blocksize[m->blockflag];
2921 map = &f->mapping[m->mapping];
2922
2923// FLOORS
2924 n2 = n >> 1;
2925
2926 FL_STBV_CHECK(f);
2927
2928 for (i=0; i < f->channels; ++i) {
2929 int32_t s = map->chan[i].mux, floor;
2930 zero_channel[i] = false;
2931 floor = map->submap_floor[s];
2932 if (f->floor_types[floor] == 0) {
2933 return error(f, VORBIS_invalid_stream);
2934 } else {
2935 Floor1 *g = &f->floor_config[floor].floor1;
2936 if (get_bits(f, 1)) {
2937 short *finalY;
2938 uint8 step2_flag[256];
2939 static int32_t range_list[4] = { 256, 128, 86, 64 };
2940 int32_t range = range_list[g->floor1_multiplier-1];
2941 int32_t offset = 2;
2942 finalY = f->finalY[i];
2943 finalY[0] = get_bits(f, ilog(range)-1);
2944 finalY[1] = get_bits(f, ilog(range)-1);
2945 for (j=0; j < g->partitions; ++j) {
2946 int32_t pclass = g->partition_class_list[j];
2947 int32_t cdim = g->class_dimensions[pclass];
2948 int32_t cbits = g->class_subclasses[pclass];
2949 int32_t csub = (1 << cbits)-1;
2950 int32_t cval = 0;
2951 if (cbits) {
2952 Codebook *c = f->codebooks + g->class_masterbooks[pclass];
2953 FL_STBV_DECODE(cval,f,c);
2954 }
2955 for (k=0; k < cdim; ++k) {
2956 int32_t book = g->subclass_books[pclass][cval & csub];
2957 cval = cval >> cbits;
2958 if (book >= 0) {
2959 int32_t temp;
2960 Codebook *c = f->codebooks + book;
2961 FL_STBV_DECODE(temp,f,c);
2962 finalY[offset++] = temp;
2963 } else
2964 finalY[offset++] = 0;
2965 }
2966 }
2967 if (f->valid_bits == INVALID_BITS) goto error; // behavior according to spec
2968 step2_flag[0] = step2_flag[1] = 1;
2969 for (j=2; j < g->values; ++j) {
2970 int32_t low, high, pred, highroom, lowroom, room, val;
2971 low = g->neighbors[j][0];
2972 high = g->neighbors[j][1];
2973 //neighbors(g->Xlist, j, &low, &high);
2974 pred = predict_point(g->Xlist[j], g->Xlist[low], g->Xlist[high], finalY[low], finalY[high]);
2975 val = finalY[j];
2976 highroom = range - pred;
2977 lowroom = pred;
2978 if (highroom < lowroom)
2979 room = highroom * 2;
2980 else
2981 room = lowroom * 2;
2982 if (val) {
2983 step2_flag[low] = step2_flag[high] = 1;
2984 step2_flag[j] = 1;
2985 if (val >= room)
2986 if (highroom > lowroom)
2987 finalY[j] = val - lowroom + pred;
2988 else
2989 finalY[j] = pred - val + highroom - 1;
2990 else
2991 if (val & 1)
2992 finalY[j] = pred - ((val+1)>>1);
2993 else
2994 finalY[j] = pred + (val>>1);
2995 } else {
2996 step2_flag[j] = 0;
2997 finalY[j] = pred;
2998 }
2999 }
3000
3001#ifdef FL_STB_VORBIS_NO_DEFER_FLOOR
3002 do_floor(f, map, i, n, f->floor_buffers[i], finalY, step2_flag);
3003#else
3004 // defer final floor computation until _after_ residue
3005 for (j=0; j < g->values; ++j) {
3006 if (!step2_flag[j])
3007 finalY[j] = -1;
3008 }
3009#endif
3010 } else {
3011 error:
3012 zero_channel[i] = true;
3013 }
3014 // So we just defer everything else to later
3015
3016 // at this point we've decoded the floor into buffer
3017 }
3018 }
3019 FL_STBV_CHECK(f);
3020 // at this point we've decoded all floors
3021
3022 if (f->alloc.alloc_buffer)
3023 FL_ASSERT(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset, "alloc_buffer_length must equal temp_offset");
3024
3025 // re-enable coupled channels if necessary
3026 memcpy(really_zero_channel, zero_channel, sizeof(really_zero_channel[0]) * f->channels);
3027 for (i=0; i < map->coupling_steps; ++i)
3028 if (!zero_channel[map->chan[i].magnitude] || !zero_channel[map->chan[i].angle]) {
3029 zero_channel[map->chan[i].magnitude] = zero_channel[map->chan[i].angle] = false;
3030 }
3031
3032 FL_STBV_CHECK(f);
3033// RESIDUE DECODE
3034 for (i=0; i < map->submaps; ++i) {
3035 float *residue_buffers[FL_STB_VORBIS_MAX_CHANNELS];
3036 int32_t r;
3037 uint8 do_not_decode[256];
3038 int32_t ch = 0;
3039 for (j=0; j < f->channels; ++j) {
3040 if (map->chan[j].mux == i) {
3041 if (zero_channel[j]) {
3042 do_not_decode[ch] = true;
3043 residue_buffers[ch] = nullptr;
3044 } else {
3045 do_not_decode[ch] = false;
3046 residue_buffers[ch] = f->channel_buffers[j];
3047 }
3048 ++ch;
3049 }
3050 }
3051 r = map->submap_residue[i];
3052 decode_residue(f, residue_buffers, ch, n2, r, do_not_decode);
3053 }
3054
3055 if (f->alloc.alloc_buffer)
3056 FL_ASSERT(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset, "alloc_buffer_length must equal temp_offset");
3057 FL_STBV_CHECK(f);
3058
3059// INVERSE COUPLING
3060 for (i = map->coupling_steps-1; i >= 0; --i) {
3061 int32_t n2 = n >> 1;
3062 float *m = f->channel_buffers[map->chan[i].magnitude];
3063 float *a = f->channel_buffers[map->chan[i].angle ];
3064 for (j=0; j < n2; ++j) {
3065 float a2,m2;
3066 if (m[j] > 0)
3067 if (a[j] > 0)
3068 m2 = m[j], a2 = m[j] - a[j];
3069 else
3070 a2 = m[j], m2 = m[j] + a[j];
3071 else
3072 if (a[j] > 0)
3073 m2 = m[j], a2 = m[j] + a[j];
3074 else
3075 a2 = m[j], m2 = m[j] - a[j];
3076 m[j] = m2;
3077 a[j] = a2;
3078 }
3079 }
3080 FL_STBV_CHECK(f);
3081
3082 // finish decoding the floors
3083#ifndef FL_STB_VORBIS_NO_DEFER_FLOOR
3084 for (i=0; i < f->channels; ++i) {
3085 if (really_zero_channel[i]) {
3086 memset(f->channel_buffers[i], 0, sizeof(*f->channel_buffers[i]) * n2);
3087 } else {
3088 do_floor(f, map, i, n, f->channel_buffers[i], f->finalY[i], nullptr);
3089 }
3090 }
3091#else
3092 for (i=0; i < f->channels; ++i) {
3093 if (really_zero_channel[i]) {
3094 memset(f->channel_buffers[i], 0, sizeof(*f->channel_buffers[i]) * n2);
3095 } else {
3096 for (j=0; j < n2; ++j)
3097 f->channel_buffers[i][j] *= f->floor_buffers[i][j];
3098 }
3099 }
3100#endif
3101
3102// INVERSE MDCT
3103 FL_STBV_CHECK(f);
3104 for (i=0; i < f->channels; ++i)
3105 inverse_mdct(f->channel_buffers[i], n, f, m->blockflag);
3106 FL_STBV_CHECK(f);
3107
3108 // this shouldn't be necessary, unless we exited on an error
3109 // and want to flush to get to the next packet
3110 flush_packet(f);
3111
3112 if (f->first_decode) {
3113 // assume we start so first non-discarded sample is sample 0
3114 // this isn't to spec, but spec would require us to read ahead
3115 // and decode the size of all current frames--could be done,
3116 // but presumably it's not a commonly used feature
3117 f->current_loc = 0u - n2; // start of first frame is positioned for discard (NB this is an intentional unsigned overflow/wrap-around)
3118 // we might have to discard samples "from" the next frame too,
3119 // if we're lapping a large block then a small at the start?
3120 f->discard_samples_deferred = n - right_end;
3121 f->current_loc_valid = true;
3122 f->first_decode = false;
3123 } else if (f->discard_samples_deferred) {
3124 if (f->discard_samples_deferred >= right_start - left_start) {
3125 f->discard_samples_deferred -= (right_start - left_start);
3126 left_start = right_start;
3127 *p_left = left_start;
3128 } else {
3129 left_start += f->discard_samples_deferred;
3130 *p_left = left_start;
3132 }
3133 } else if (f->previous_length == 0 && f->current_loc_valid) {
3134 // we're recovering from a seek... that means we're going to discard
3135 // the samples from this packet even though we know our position from
3136 // the last page header, so we need to update the position based on
3137 // the discarded samples here
3138 // but wait, the code below is going to add this in itself even
3139 // on a discard, so we don't need to do it here...
3140 }
3141
3142 // check if we have ogg information about the sample # for this packet
3144 // if we have a valid current loc, and this is final:
3146 uint32 current_end = f->known_loc_for_packet;
3147 // then let's infer the size of the (probably) short final frame
3148 if (current_end < f->current_loc + (right_end-left_start)) {
3149 if (current_end < f->current_loc) {
3150 // negative truncation, that's impossible!
3151 *len = 0;
3152 } else {
3153 *len = current_end - f->current_loc;
3154 }
3155 *len += left_start; // this doesn't seem right, but has no ill effect on my test files
3156 if (*len > right_end) *len = right_end; // this should never happen
3157 f->current_loc += *len;
3158 return true;
3159 }
3160 }
3161 // otherwise, just set our sample loc
3162 // guess that the ogg granule pos refers to the _middle_ of the
3163 // last frame?
3164 // set f->current_loc to the position of left_start
3165 f->current_loc = f->known_loc_for_packet - (n2-left_start);
3166 f->current_loc_valid = true;
3167 }
3168 if (f->current_loc_valid)
3169 f->current_loc += (right_start - left_start);
3170
3171 if (f->alloc.alloc_buffer)
3172 FL_ASSERT(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset, "alloc_buffer_length must equal temp_offset");
3173 *len = right_end; // ignore samples after the window goes to 0
3174 FL_STBV_CHECK(f);
3175
3176 return true;
3177}
#define FL_ASSERT(x, MSG)
Definition assert.h:6
fl::UISlider offset("Offset", 0.0f, 0.0f, 1.0f, 0.01f)
void * memcpy(void *dest, const void *src, size_t n) FL_NOEXCEPT
static void flush_packet(vorb *f) FL_NOEXCEPT
static void inverse_mdct(float *buffer, int32_t n, vorb *f, int32_t blocktype) FL_NOEXCEPT
static int32_t ilog(int32 n) FL_NOEXCEPT
static constexpr int32_t INVALID_BITS
static int32_t predict_point(int32_t x, int32_t x0, int32_t x1, int32_t y0, int32_t y1) FL_NOEXCEPT
static int32_t do_floor(vorb *f, Mapping *map, int32_t i, int32_t n, float *target, YTYPE *finalY, uint8 *step2_flag) FL_NOEXCEPT
static int32_t error(vorb *f, enum STBVorbisError e) FL_NOEXCEPT
static constexpr uint8_t PAGEFLAG_last_page
void * memset(void *s, int c, size_t n) FL_NOEXCEPT
constexpr enable_if< is_fixed_point< T >::value, T >::type floor(T x) FL_NOEXCEPT
static void decode_residue(vorb *f, float *residue_buffers[], int32_t ch, int32_t n, int32_t rn, uint8 *do_not_decode) FL_NOEXCEPT
static uint32 get_bits(vorb *f, int32_t n) FL_NOEXCEPT
int16 * finalY[FL_STB_VORBIS_MAX_CHANNELS]
float * channel_buffers[FL_STB_VORBIS_MAX_CHANNELS]
fl::i32 int32_t
Definition coder.h:220
MapRedBlackTree< Key, T, Compare, fl::allocator_slab< char > > map
Definition map.h:283
constexpr enable_if< is_fixed_point< T >::value, T >::type floor(T x) FL_NOEXCEPT
fl::i32 int32_t
Definition s16x16x4.h:220
#define FL_UNUSED(x)
#define FL_STBV_DECODE(var, f, c)
#define FL_STB_VORBIS_MAX_CHANNELS
#define FL_STBV_CHECK(f)

References fl::third_party::vorbis::Floor1::class_dimensions, fl::third_party::vorbis::Floor1::class_masterbooks, fl::third_party::vorbis::Floor1::class_subclasses, decode_residue(), do_floor(), error(), FL_ASSERT, FL_NOEXCEPT, FL_STB_VORBIS_MAX_CHANNELS, FL_STBV_CHECK, FL_STBV_DECODE, FL_UNUSED, floor(), fl::third_party::vorbis::Floor1::floor1_multiplier, flush_packet(), get_bits(), ilog(), INVALID_BITS, inverse_mdct(), memcpy(), memset(), fl::third_party::vorbis::Floor1::neighbors, offset(), PAGEFLAG_last_page, fl::third_party::vorbis::Floor1::partition_class_list, fl::third_party::vorbis::Floor1::partitions, predict_point(), fl::third_party::vorbis::Floor1::subclass_books, fl::third_party::vorbis::Floor1::values, VORBIS_invalid_stream, and fl::third_party::vorbis::Floor1::Xlist.

Referenced by vorbis_decode_packet().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: