| 1 |  | 
|---|
| 2 | // Buffer of sound samples into which band-limited waveforms can be synthesized | 
|---|
| 3 | // using Blip_Wave or Blip_Synth. | 
|---|
| 4 |  | 
|---|
| 5 | // Blip_Buffer 0.3.3. Copyright (C) 2003-2005 Shay Green. GNU LGPL license. | 
|---|
| 6 |  | 
|---|
| 7 | #ifndef BLIP_BUFFER_H | 
|---|
| 8 | #define BLIP_BUFFER_H | 
|---|
| 9 |  | 
|---|
| 10 | #include "blargg_common.h" | 
|---|
| 11 |  | 
|---|
| 12 | class Blip_Reader; | 
|---|
| 13 |  | 
|---|
| 14 | // Source time unit. | 
|---|
| 15 | typedef long blip_time_t; | 
|---|
| 16 |  | 
|---|
| 17 | // Type of sample produced. Signed 16-bit format. | 
|---|
| 18 | typedef BOOST::int16_t blip_sample_t; | 
|---|
| 19 |  | 
|---|
| 20 | // Make buffer as large as possible (currently about 65000 samples) | 
|---|
| 21 | const int blip_default_length = 0; | 
|---|
| 22 |  | 
|---|
| 23 | class Blip_Buffer { | 
|---|
| 24 | public: | 
|---|
| 25 | // Construct an empty buffer. | 
|---|
| 26 | Blip_Buffer(); | 
|---|
| 27 | ~Blip_Buffer(); | 
|---|
| 28 |  | 
|---|
| 29 | // Set output sample rate and buffer length in milliseconds (1/1000 sec), | 
|---|
| 30 | // then clear buffer. If length is not specified, make as large as possible. | 
|---|
| 31 | // If there is insufficient memory for the buffer, sets the buffer length | 
|---|
| 32 | // to 0 and returns error string (or propagates exception if compiler supports it). | 
|---|
| 33 | blargg_err_t sample_rate( long samples_per_sec, int msec_length = blip_default_length ); | 
|---|
| 34 | // to do: rename to set_sample_rate | 
|---|
| 35 |  | 
|---|
| 36 | // Length of buffer, in milliseconds | 
|---|
| 37 | int length() const; | 
|---|
| 38 |  | 
|---|
| 39 | // Current output sample rate | 
|---|
| 40 | long sample_rate() const; | 
|---|
| 41 |  | 
|---|
| 42 | // Number of source time units per second | 
|---|
| 43 | void clock_rate( long ); | 
|---|
| 44 | long clock_rate() const; | 
|---|
| 45 |  | 
|---|
| 46 | // Set frequency at which high-pass filter attenuation passes -3dB | 
|---|
| 47 | void bass_freq( int frequency ); | 
|---|
| 48 |  | 
|---|
| 49 | // Remove all available samples and clear buffer to silence. If 'entire_buffer' is | 
|---|
| 50 | // false, just clear out any samples waiting rather than the entire buffer. | 
|---|
| 51 | void clear( bool entire_buffer = true ); | 
|---|
| 52 |  | 
|---|
| 53 | // to do: | 
|---|
| 54 | // Notify Blip_Buffer that synthesis has been performed until specified time | 
|---|
| 55 | //void run_until( blip_time_t ); | 
|---|
| 56 |  | 
|---|
| 57 | // End current time frame of specified duration and make its samples available | 
|---|
| 58 | // (along with any still-unread samples) for reading with read_samples(). Begin | 
|---|
| 59 | // a new time frame at the end of the current frame. All transitions must have | 
|---|
| 60 | // been added before 'time'. | 
|---|
| 61 | void end_frame( blip_time_t time ); | 
|---|
| 62 |  | 
|---|
| 63 | // Number of samples available for reading with read_samples() | 
|---|
| 64 | long samples_avail() const; | 
|---|
| 65 |  | 
|---|
| 66 | // Read at most 'max_samples' out of buffer into 'dest', removing them from from | 
|---|
| 67 | // the buffer. Return number of samples actually read and removed. If stereo is | 
|---|
| 68 | // true, increment 'dest' one extra time after writing each sample, to allow | 
|---|
| 69 | // easy interleving of two channels into a stereo output buffer. | 
|---|
| 70 | long read_samples( blip_sample_t* dest, long max_samples, bool stereo = false ); | 
|---|
| 71 |  | 
|---|
| 72 | // Remove 'count' samples from those waiting to be read | 
|---|
| 73 | void remove_samples( long count ); | 
|---|
| 74 |  | 
|---|
| 75 | // Number of samples delay from synthesis to samples read out | 
|---|
| 76 | int output_latency() const; | 
|---|
| 77 |  | 
|---|
| 78 |  | 
|---|
| 79 | // Experimental external buffer mixing support | 
|---|
| 80 |  | 
|---|
| 81 | // Number of raw samples that can be mixed within frame of specified duration | 
|---|
| 82 | long count_samples( blip_time_t duration ) const; | 
|---|
| 83 |  | 
|---|
| 84 | // Mix 'count' samples from 'buf' into buffer. | 
|---|
| 85 | void mix_samples( const blip_sample_t* buf, long count ); | 
|---|
| 86 |  | 
|---|
| 87 |  | 
|---|
| 88 | // not documented yet | 
|---|
| 89 |  | 
|---|
| 90 | void remove_silence( long count ); | 
|---|
| 91 |  | 
|---|
| 92 | typedef unsigned long resampled_time_t; | 
|---|
| 93 |  | 
|---|
| 94 | resampled_time_t resampled_time( blip_time_t t ) const { | 
|---|
| 95 | return t * resampled_time_t (factor_) + offset_; | 
|---|
| 96 | } | 
|---|
| 97 |  | 
|---|
| 98 | resampled_time_t resampled_duration( int t ) const { | 
|---|
| 99 | return t * resampled_time_t (factor_); | 
|---|
| 100 | } | 
|---|
| 101 |  | 
|---|
| 102 | private: | 
|---|
| 103 | // noncopyable | 
|---|
| 104 | Blip_Buffer( const Blip_Buffer& ); | 
|---|
| 105 | Blip_Buffer& operator = ( const Blip_Buffer& ); | 
|---|
| 106 |  | 
|---|
| 107 | // Don't use the following members. They are public only for technical reasons. | 
|---|
| 108 | public: | 
|---|
| 109 | enum { widest_impulse_ = 24 }; | 
|---|
| 110 | typedef BOOST::uint16_t buf_t_; | 
|---|
| 111 |  | 
|---|
| 112 | unsigned long factor_; | 
|---|
| 113 | resampled_time_t offset_; | 
|---|
| 114 | buf_t_* buffer_; | 
|---|
| 115 | unsigned buffer_size_; | 
|---|
| 116 | private: | 
|---|
| 117 | long reader_accum; | 
|---|
| 118 | int bass_shift; | 
|---|
| 119 | long samples_per_sec; | 
|---|
| 120 | long clocks_per_sec; | 
|---|
| 121 | int bass_freq_; | 
|---|
| 122 | int length_; | 
|---|
| 123 |  | 
|---|
| 124 | enum { accum_fract = 15 }; // less than 16 to give extra sample range | 
|---|
| 125 | enum { sample_offset = 0x7F7F }; // repeated byte allows memset to clear buffer | 
|---|
| 126 |  | 
|---|
| 127 | friend class Blip_Reader; | 
|---|
| 128 | }; | 
|---|
| 129 |  | 
|---|
| 130 | // Low-pass equalization parameters (see notes.txt) | 
|---|
| 131 | class blip_eq_t { | 
|---|
| 132 | public: | 
|---|
| 133 | blip_eq_t( double treble = 0 ); | 
|---|
| 134 | blip_eq_t( double treble, long cutoff, long sample_rate ); | 
|---|
| 135 | private: | 
|---|
| 136 | double treble; | 
|---|
| 137 | long cutoff; | 
|---|
| 138 | long sample_rate; | 
|---|
| 139 | friend class Blip_Impulse_; | 
|---|
| 140 | }; | 
|---|
| 141 |  | 
|---|
| 142 | // not documented yet (see Multi_Buffer.cpp for an example of use) | 
|---|
| 143 | class Blip_Reader { | 
|---|
| 144 | const Blip_Buffer::buf_t_* buf; | 
|---|
| 145 | long accum; | 
|---|
| 146 | #ifdef __MWERKS__ | 
|---|
| 147 | void operator = ( struct foobar ); // helps optimizer | 
|---|
| 148 | #endif | 
|---|
| 149 | public: | 
|---|
| 150 | // avoid anything which might cause optimizer to put object in memory | 
|---|
| 151 |  | 
|---|
| 152 | int begin( Blip_Buffer& blip_buf ) { | 
|---|
| 153 | buf = blip_buf.buffer_; | 
|---|
| 154 | accum = blip_buf.reader_accum; | 
|---|
| 155 | return blip_buf.bass_shift; | 
|---|
| 156 | } | 
|---|
| 157 |  | 
|---|
| 158 | int read() const { | 
|---|
| 159 | return accum >> Blip_Buffer::accum_fract; | 
|---|
| 160 | } | 
|---|
| 161 |  | 
|---|
| 162 | void next( int bass_shift = 9 ) { | 
|---|
| 163 | accum -= accum >> bass_shift; | 
|---|
| 164 | accum += ((long) *buf++ - Blip_Buffer::sample_offset) << Blip_Buffer::accum_fract; | 
|---|
| 165 | } | 
|---|
| 166 |  | 
|---|
| 167 | void end( Blip_Buffer& blip_buf ) { | 
|---|
| 168 | blip_buf.reader_accum = accum; | 
|---|
| 169 | } | 
|---|
| 170 | }; | 
|---|
| 171 |  | 
|---|
| 172 |  | 
|---|
| 173 |  | 
|---|
| 174 | // End of public interface | 
|---|
| 175 |  | 
|---|
| 176 | #ifndef BLIP_BUFFER_ACCURACY | 
|---|
| 177 | #define BLIP_BUFFER_ACCURACY 16 | 
|---|
| 178 | #endif | 
|---|
| 179 |  | 
|---|
| 180 | const int blip_res_bits_ = 5; | 
|---|
| 181 |  | 
|---|
| 182 | typedef BOOST::uint32_t blip_pair_t_; | 
|---|
| 183 |  | 
|---|
| 184 | class Blip_Impulse_ { | 
|---|
| 185 | typedef BOOST::uint16_t imp_t; | 
|---|
| 186 |  | 
|---|
| 187 | blip_eq_t eq; | 
|---|
| 188 | double  volume_unit_; | 
|---|
| 189 | imp_t*  impulses; | 
|---|
| 190 | imp_t*  impulse; | 
|---|
| 191 | int     width; | 
|---|
| 192 | int     fine_bits; | 
|---|
| 193 | int     res; | 
|---|
| 194 | bool    generate; | 
|---|
| 195 |  | 
|---|
| 196 | void fine_volume_unit(); | 
|---|
| 197 | void scale_impulse( int unit, imp_t* ) const; | 
|---|
| 198 | public: | 
|---|
| 199 | Blip_Buffer*    buf; | 
|---|
| 200 | BOOST::uint32_t offset; | 
|---|
| 201 |  | 
|---|
| 202 | void init( blip_pair_t_* impulses, int width, int res, int fine_bits = 0 ); | 
|---|
| 203 | void volume_unit( double ); | 
|---|
| 204 | void treble_eq( const blip_eq_t& ); | 
|---|
| 205 | }; | 
|---|
| 206 |  | 
|---|
| 207 | inline blip_eq_t::blip_eq_t( double t ) : | 
|---|
| 208 | treble( t ), cutoff( 0 ), sample_rate( 44100 ) { | 
|---|
| 209 | } | 
|---|
| 210 |  | 
|---|
| 211 | inline blip_eq_t::blip_eq_t( double t, long c, long sr ) : | 
|---|
| 212 | treble( t ), cutoff( c ), sample_rate( sr ) { | 
|---|
| 213 | } | 
|---|
| 214 |  | 
|---|
| 215 | inline int Blip_Buffer::length() const { | 
|---|
| 216 | return length_; | 
|---|
| 217 | } | 
|---|
| 218 |  | 
|---|
| 219 | inline long Blip_Buffer::samples_avail() const { | 
|---|
| 220 | return long (offset_ >> BLIP_BUFFER_ACCURACY); | 
|---|
| 221 | } | 
|---|
| 222 |  | 
|---|
| 223 | inline long Blip_Buffer::sample_rate() const { | 
|---|
| 224 | return samples_per_sec; | 
|---|
| 225 | } | 
|---|
| 226 |  | 
|---|
| 227 | inline void Blip_Buffer::end_frame( blip_time_t t ) { | 
|---|
| 228 | offset_ += t * factor_; | 
|---|
| 229 | assert(( "Blip_Buffer::end_frame(): Frame went past end of buffer", | 
|---|
| 230 | samples_avail() <= (long) buffer_size_ )); | 
|---|
| 231 | } | 
|---|
| 232 |  | 
|---|
| 233 | inline void Blip_Buffer::remove_silence( long count ) { | 
|---|
| 234 | assert(( "Blip_Buffer::remove_silence(): Tried to remove more samples than available", | 
|---|
| 235 | count <= samples_avail() )); | 
|---|
| 236 | offset_ -= resampled_time_t (count) << BLIP_BUFFER_ACCURACY; | 
|---|
| 237 | } | 
|---|
| 238 |  | 
|---|
| 239 | inline int Blip_Buffer::output_latency() const { | 
|---|
| 240 | return widest_impulse_ / 2; | 
|---|
| 241 | } | 
|---|
| 242 |  | 
|---|
| 243 | inline long Blip_Buffer::clock_rate() const { | 
|---|
| 244 | return clocks_per_sec; | 
|---|
| 245 | } | 
|---|
| 246 |  | 
|---|
| 247 | // MSVC6 fix | 
|---|
| 248 | typedef Blip_Buffer::resampled_time_t blip_resampled_time_t; | 
|---|
| 249 |  | 
|---|
| 250 | #include "Blip_Synth.h" | 
|---|
| 251 |  | 
|---|
| 252 | #endif | 
|---|
| 253 |  | 
|---|
| 254 |  | 
|---|