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 | |