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
12class Blip_Reader;
13
14// Source time unit.
15typedef long blip_time_t;
16
17// Type of sample produced. Signed 16-bit format.
18typedef BOOST::int16_t blip_sample_t;
19
20// Make buffer as large as possible (currently about 65000 samples)
21const int blip_default_length = 0;
22
23class Blip_Buffer {
24public:
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
102private:
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)
131class blip_eq_t {
132public:
133 blip_eq_t( double treble = 0 );
134 blip_eq_t( double treble, long cutoff, long sample_rate );
135private:
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)
143class Blip_Reader {
144 const Blip_Buffer::buf_t_* buf;
145 long accum;
146 #ifdef __MWERKS__
147 void operator = ( struct foobar ); // helps optimizer
148 #endif
149public:
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
180const int blip_res_bits_ = 5;
181
182typedef BOOST::uint32_t blip_pair_t_;
183
184class 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;
198public:
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
207inline blip_eq_t::blip_eq_t( double t ) :
208 treble( t ), cutoff( 0 ), sample_rate( 44100 ) {
209}
210
211inline blip_eq_t::blip_eq_t( double t, long c, long sr ) :
212 treble( t ), cutoff( c ), sample_rate( sr ) {
213}
214
215inline int Blip_Buffer::length() const {
216 return length_;
217}
218
219inline long Blip_Buffer::samples_avail() const {
220 return long (offset_ >> BLIP_BUFFER_ACCURACY);
221}
222
223inline long Blip_Buffer::sample_rate() const {
224 return samples_per_sec;
225}
226
227inline 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
233inline 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
239inline int Blip_Buffer::output_latency() const {
240 return widest_impulse_ / 2;
241}
242
243inline long Blip_Buffer::clock_rate() const {
244 return clocks_per_sec;
245}
246
247// MSVC6 fix
248typedef Blip_Buffer::resampled_time_t blip_resampled_time_t;
249
250#include "Blip_Synth.h"
251
252#endif
253
254