136 lines
3.2 KiB
C
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
|