Path: blob/main/misc/emulator/xnes/snes9x/apu/linear_resampler.h
28798 views
/* Simple fixed-point linear resampler by BearOso*/12#ifndef __LINEAR_RESAMPLER_H3#define __LINEAR_RESAMPLER_H45#include "resampler.h"6#include "snes9x.h"78static const int f_prec = 15;9static const uint32 f__one = (1 << f_prec);1011#define lerp(t, a, b) (((((b) - (a)) * (t)) >> f_prec) + (a))1213class LinearResampler : public Resampler14{15protected:16uint32 f__r_step;17uint32 f__inv_r_step;18uint32 f__r_frac;19int r_left, r_right;2021public:22LinearResampler (int num_samples) : Resampler (num_samples)23{24f__r_frac = 0;25}2627~LinearResampler ()28{29}3031void32time_ratio (double ratio)33{34if (ratio == 0.0)35ratio = 1.0;36f__r_step = (uint32) (ratio * f__one);37f__inv_r_step = (uint32) (f__one / ratio);38clear ();39}4041void42clear (void)43{44ring_buffer::clear ();45f__r_frac = 0;46r_left = 0;47r_right = 0;48}4950void51read (short *data, int num_samples)52{53int i_position = start >> 1;54short *internal_buffer = (short *) buffer;55int o_position = 0;56int consumed = 0;57int max_samples = (buffer_size >> 1);5859while (o_position < num_samples && consumed < buffer_size)60{61if (f__r_step == f__one)62{63data[o_position] = internal_buffer[i_position];64data[o_position + 1] = internal_buffer[i_position + 1];6566o_position += 2;67i_position += 2;68if (i_position >= max_samples)69i_position -= max_samples;70consumed += 2;7172continue;73}7475while (f__r_frac <= f__one && o_position < num_samples)76{77data[o_position] = lerp (f__r_frac,78r_left,79internal_buffer[i_position]);80data[o_position + 1] = lerp (f__r_frac,81r_right,82internal_buffer[i_position + 1]);8384o_position += 2;8586f__r_frac += f__r_step;87}8889if (f__r_frac > f__one)90{91f__r_frac -= f__one;92r_left = internal_buffer[i_position];93r_right = internal_buffer[i_position + 1];94i_position += 2;95if (i_position >= max_samples)96i_position -= max_samples;97consumed += 2;98}99}100101size -= consumed << 1;102start += consumed << 1;103if (start >= buffer_size)104start -= buffer_size;105}106107inline int108avail (void)109{110return (((size >> 2) * f__inv_r_step) - ((f__r_frac * f__inv_r_step) >> f_prec)) >> (f_prec - 1);111}112};113114#endif /* __LINEAR_RESAMPLER_H */115116117