cog/Frameworks/GME/gme/Blip_Buffer_impl.h

136 lines
3.2 KiB
C++

// Internal stuff here to keep public header uncluttered
// Blip_Buffer $vers
#ifndef BLIP_BUFFER_IMPL_H
#define BLIP_BUFFER_IMPL_H
typedef unsigned blip_resampled_time_t;
#ifndef BLIP_MAX_QUALITY
#define BLIP_MAX_QUALITY 32
#endif
#ifndef BLIP_BUFFER_ACCURACY
#define BLIP_BUFFER_ACCURACY 16
#endif
#ifndef BLIP_PHASE_BITS
#define BLIP_PHASE_BITS 6
#endif
class blip_eq_t;
class Blip_Buffer;
#if BLIP_BUFFER_FAST
// linear interpolation needs 8 bits
#undef BLIP_PHASE_BITS
#define BLIP_PHASE_BITS 8
#undef BLIP_MAX_QUALITY
#define BLIP_MAX_QUALITY 2
#endif
int const blip_res = 1 << BLIP_PHASE_BITS;
int const blip_buffer_extra_ = BLIP_MAX_QUALITY + 2;
class Blip_Buffer_ {
public:
// Writer
typedef int clocks_t;
// Properties of fixed-point sample position
typedef unsigned fixed_t; // unsigned for more range, optimized shifts
enum { fixed_bits = BLIP_BUFFER_ACCURACY }; // bits in fraction
enum { fixed_unit = 1 << fixed_bits }; // 1.0 samples
// Converts clock count to fixed-point sample position
fixed_t to_fixed( clocks_t t ) const { return t * factor_ + offset_; }
// Deltas in buffer are fixed-point with this many fraction bits.
// Less than 16 for extra range.
enum { delta_bits = 14 };
// Pointer to first committed delta sample
typedef int delta_t;
// Pointer to delta corresponding to fixed-point sample position
delta_t* delta_at( fixed_t );
// Reader
delta_t* read_pos() { return buffer_; }
void clear_modified() { modified_ = false; }
int highpass_shift() const { return bass_shift_; }
int integrator() const { return reader_accum_; }
void set_integrator( int n ) { reader_accum_ = n; }
public: //friend class Tracked_Blip_Buffer; private:
bool modified() const { return modified_; }
void remove_silence( int count );
private:
unsigned factor_;
fixed_t offset_;
delta_t* buffer_center_;
int buffer_size_;
int reader_accum_;
int bass_shift_;
delta_t* buffer_;
int sample_rate_;
int clock_rate_;
int bass_freq_;
int length_;
bool modified_;
friend class Blip_Buffer;
};
class Blip_Synth_Fast_ {
public:
int delta_factor;
int last_amp;
Blip_Buffer* buf;
void volume_unit( double );
void treble_eq( blip_eq_t const& ) { }
Blip_Synth_Fast_();
};
class Blip_Synth_ {
public:
int delta_factor;
int last_amp;
Blip_Buffer* buf;
void volume_unit( double );
void treble_eq( blip_eq_t const& );
Blip_Synth_( short phases [], int width );
private:
double volume_unit_;
short* const phases;
int const width;
int kernel_unit;
void adjust_impulse();
void rescale_kernel( int shift );
int impulses_size() const { return blip_res / 2 * width; }
};
class blip_buffer_state_t
{
blip_resampled_time_t offset_;
int reader_accum_;
int buf [blip_buffer_extra_];
friend class Blip_Buffer;
};
inline Blip_Buffer_::delta_t* Blip_Buffer_::delta_at( fixed_t f )
{
assert( (f >> fixed_bits) < (unsigned) buffer_size_ );
return buffer_center_ + (f >> fixed_bits);
}
#endif