1 // Band-limited sound synthesis buffer 2 3 // Blip_Buffer $vers 4 #ifndef BLIP_BUFFER_H 5 #define BLIP_BUFFER_H 6 7 #include "blargg_common.h" 8 #include "Blip_Buffer_impl.h" 9 10 typedef int blip_time_t; // Source clocks in current time frame 11 typedef BOOST::int16_t blip_sample_t; // 16-bit signed output sample 12 int const blip_default_length = 1000 / 4; // Default Blip_Buffer length (1/4 second) 13 14 15 //// Sample buffer for band-limited synthesis 16 17 class Blip_Buffer : public Blip_Buffer_ { 18 public: 19 20 // Sets output sample rate and resizes and clears sample buffer 21 blargg_err_t set_sample_rate( int samples_per_sec, int msec_length = blip_default_length ); 22 23 // Sets number of source time units per second 24 void clock_rate( int clocks_per_sec ); 25 26 // Clears buffer and removes all samples 27 void clear(); 28 29 // Use Blip_Synth to add waveform to buffer 30 31 // Resamples to time t, then subtracts t from current time. Appends result of resampling 32 // to buffer for reading. 33 void end_frame( blip_time_t t ); 34 35 // Number of samples available for reading with read_samples() 36 int samples_avail() const; 37 38 // Reads at most n samples to out [0 to n-1] and returns number actually read. If stereo 39 // is true, writes to out [0], out [2], out [4] etc. instead. 40 int read_samples( blip_sample_t out [], int n, bool stereo = false ); 41 42 // More features 43 44 // Sets flag that tells some Multi_Buffer types that sound was added to buffer, 45 // so they know that it needs to be mixed in. Only needs to be called once 46 // per time frame that sound was added. Not needed if not using Multi_Buffer. set_modified()47 void set_modified() { modified_ = true; } 48 49 // Sets high-pass filter frequency, from 0 to 20000 Hz, where higher values reduce bass more 50 void bass_freq( int frequency ); 51 52 int length() const; // Length of buffer in milliseconds 53 int sample_rate() const; // Current output sample rate 54 int clock_rate() const; // Number of source time units per second 55 int output_latency() const; // Number of samples delay from offset() to read_samples() 56 57 // Low-level features 58 59 // Removes the first n samples 60 void remove_samples( int n ); 61 62 // Returns number of clocks needed until n samples will be available. 63 // If buffer cannot even hold n samples, returns number of clocks 64 // until buffer becomes full. 65 blip_time_t count_clocks( int n ) const; 66 67 // Number of samples that should be mixed before calling end_frame( t ) 68 int count_samples( blip_time_t t ) const; 69 70 // Mixes n samples into buffer 71 void mix_samples( const blip_sample_t in [], int n ); 72 73 // Resampled time (sorry, poor documentation right now) 74 75 // Resampled time is fixed-point, in terms of output samples. 76 77 // Converts clock count to resampled time resampled_duration(int t)78 blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; } 79 80 // Converts clock time since beginning of current time frame to resampled time resampled_time(blip_time_t t)81 blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; } 82 83 // Returns factor that converts clock rate to resampled time 84 blip_resampled_time_t clock_rate_factor( int clock_rate ) const; 85 86 // State save/load 87 88 // Saves state, including high-pass filter and tails of last deltas. 89 // All samples must have been read from buffer before calling this 90 // (that is, samples_avail() must return 0). 91 void save_state( blip_buffer_state_t* out ); 92 93 // Loads state. State must have been saved from Blip_Buffer with same 94 // settings during same run of program; states can NOT be stored on disk. 95 // Clears buffer before loading state. 96 void load_state( const blip_buffer_state_t& in ); 97 98 private: 99 // noncopyable 100 Blip_Buffer( const Blip_Buffer& ); 101 Blip_Buffer& operator = ( const Blip_Buffer& ); 102 103 // Implementation 104 public: 105 BLARGG_DISABLE_NOTHROW 106 Blip_Buffer(); 107 ~Blip_Buffer(); 108 void remove_silence( int n ); 109 }; 110 111 112 //// Adds amplitude changes to Blip_Buffer 113 114 template<int quality,int range> class Blip_Synth; 115 116 typedef Blip_Synth<8, 1> Blip_Synth_Fast; // faster, but less equalizer control 117 typedef Blip_Synth<12,1> Blip_Synth_Norm; // good for most things 118 typedef Blip_Synth<16,1> Blip_Synth_Good; // sharper filter cutoff 119 120 template<int quality,int range> 121 class Blip_Synth { 122 public: 123 124 // Sets volume of amplitude delta unit volume(double v)125 void volume( double v ) { impl.volume_unit( 1.0 / range * v ); } 126 127 // Configures low-pass filter treble_eq(const blip_eq_t & eq)128 void treble_eq( const blip_eq_t& eq ) { impl.treble_eq( eq ); } 129 130 // Gets/sets default Blip_Buffer output()131 Blip_Buffer* output() const { return impl.buf; } output(Blip_Buffer * b)132 void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; } 133 134 // Extends waveform to time t at current amplitude, then changes its amplitude to a 135 // Using this requires a separate Blip_Synth for each waveform. 136 void update( blip_time_t t, int a ); 137 138 // Low-level interface 139 140 // If no Blip_Buffer* is specified, uses one set by output() above 141 142 // Adds amplitude transition at time t. Delta can be positive or negative. 143 // The actual change in amplitude is delta * volume. 144 void offset( blip_time_t t, int delta, Blip_Buffer* ) const; offset(blip_time_t t,int delta)145 void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); } 146 147 // Same as offset(), except code is inlined for higher performance offset_inline(blip_time_t t,int delta,Blip_Buffer * buf)148 void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const { offset_resampled( buf->to_fixed( t ), delta, buf ); } offset_inline(blip_time_t t,int delta)149 void offset_inline( blip_time_t t, int delta ) const { offset_resampled( impl.buf->to_fixed( t ), delta, impl.buf ); } 150 151 // Works directly in terms of fractional output samples. Use resampled time functions in Blip_Buffer 152 // to convert clock counts to resampled time. 153 void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const; 154 155 // Implementation 156 public: 157 BLARGG_DISABLE_NOTHROW 158 159 private: 160 #if BLIP_BUFFER_FAST 161 Blip_Synth_Fast_ impl; 162 typedef char coeff_t; 163 #else 164 Blip_Synth_ impl; 165 typedef short coeff_t; 166 // Left halves of first difference of step response for each possible phase 167 coeff_t phases [quality / 2 * blip_res]; 168 public: 169 Blip_Synth() : impl( phases, quality ) { } 170 #endif 171 }; 172 173 174 //// Low-pass equalization parameters 175 176 class blip_eq_t { 177 double treble, kaiser; 178 int rolloff_freq, sample_rate, cutoff_freq; 179 public: 180 // Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce 181 // treble, small positive values (0 to 5.0) increase treble. 182 blip_eq_t( double treble_db = 0 ); 183 184 // See blip_buffer.txt 185 blip_eq_t( double treble, int rolloff_freq, int sample_rate, int cutoff_freq = 0, 186 double kaiser = 5.2 ); 187 188 // Generate center point and right half of impulse response 189 virtual void generate( float out [], int count ) const; ~blip_eq_t()190 virtual ~blip_eq_t() { } 191 192 enum { oversample = blip_res }; calc_count(int quality)193 static int calc_count( int quality ) { return (quality - 1) * (oversample / 2) + 1; } 194 }; 195 196 #include "Blip_Buffer_impl2.h" 197 198 #endif 199