diff options
Diffstat (limited to 'apps/codecs/libgme/blip_buffer.h')
-rw-r--r-- | apps/codecs/libgme/blip_buffer.h | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/apps/codecs/libgme/blip_buffer.h b/apps/codecs/libgme/blip_buffer.h new file mode 100644 index 0000000000..84ed6e6690 --- /dev/null +++ b/apps/codecs/libgme/blip_buffer.h | |||
@@ -0,0 +1,279 @@ | |||
1 | // Band-limited sound synthesis buffer | ||
2 | |||
3 | // Blip_Buffer 0.4.1 | ||
4 | #ifndef BLIP_BUFFER_H | ||
5 | #define BLIP_BUFFER_H | ||
6 | |||
7 | #include <assert.h> | ||
8 | |||
9 | // internal | ||
10 | #include "blargg_common.h" | ||
11 | #if INT_MAX >= 0x7FFFFFFF | ||
12 | typedef int blip_long; | ||
13 | typedef unsigned blip_ulong; | ||
14 | #else | ||
15 | typedef long blip_long; | ||
16 | typedef unsigned long blip_ulong; | ||
17 | #endif | ||
18 | |||
19 | // Time unit at source clock rate | ||
20 | typedef blip_long blip_time_t; | ||
21 | |||
22 | // Number of bits in resample ratio fraction. Higher values give a more accurate ratio | ||
23 | // but reduce maximum buffer size. | ||
24 | #ifndef BLIP_BUFFER_ACCURACY | ||
25 | #define BLIP_BUFFER_ACCURACY 16 | ||
26 | #endif | ||
27 | |||
28 | // Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in | ||
29 | // noticeable broadband noise when synthesizing high frequency square waves. | ||
30 | // Affects size of Blip_Synth objects since they store the waveform directly. | ||
31 | #ifndef BLIP_PHASE_BITS | ||
32 | #define BLIP_PHASE_BITS 8 | ||
33 | #endif | ||
34 | |||
35 | // Output samples are 16-bit signed, with a range of -32768 to 32767 | ||
36 | typedef short blip_sample_t; | ||
37 | enum { blip_sample_max = 32767 }; | ||
38 | enum { blip_widest_impulse_ = 16 }; | ||
39 | enum { blip_buffer_extra_ = blip_widest_impulse_ + 2 }; | ||
40 | enum { blip_res = 1 << BLIP_PHASE_BITS }; | ||
41 | enum { blip_max_length = 0 }; | ||
42 | enum { blip_default_length = 250 }; | ||
43 | |||
44 | // Maximun buffer size (48Khz, 50 ms) | ||
45 | enum { blip_buffer_max = 2466 }; | ||
46 | enum { blip_sample_bits = 30 }; | ||
47 | |||
48 | typedef blip_time_t buf_t_; | ||
49 | /* typedef const char* blargg_err_t; */ | ||
50 | typedef blip_ulong blip_resampled_time_t; | ||
51 | |||
52 | struct Blip_Buffer { | ||
53 | blip_ulong factor_; | ||
54 | blip_resampled_time_t offset_; | ||
55 | buf_t_ buffer_ [blip_buffer_max]; | ||
56 | blip_long buffer_size_; | ||
57 | blip_long reader_accum_; | ||
58 | int bass_shift_; | ||
59 | |||
60 | long sample_rate_; | ||
61 | long clock_rate_; | ||
62 | int bass_freq_; | ||
63 | int length_; | ||
64 | int modified_; | ||
65 | }; | ||
66 | |||
67 | // not documented yet | ||
68 | void Blip_set_modified( struct Blip_Buffer* this ) ICODE_ATTR; | ||
69 | int Blip_clear_modified( struct Blip_Buffer* this ) ICODE_ATTR; | ||
70 | void Blip_remove_silence( struct Blip_Buffer* this, long count ) ICODE_ATTR; | ||
71 | blip_resampled_time_t Blip_resampled_duration( struct Blip_Buffer* this, int t ) ICODE_ATTR; | ||
72 | blip_resampled_time_t Blip_resampled_time( struct Blip_Buffer* this, blip_time_t t ) ICODE_ATTR; | ||
73 | blip_resampled_time_t Blip_clock_rate_factor( struct Blip_Buffer* this, long clock_rate ) ICODE_ATTR; | ||
74 | |||
75 | // Initializes Blip_Buffer structure | ||
76 | void Blip_init( struct Blip_Buffer* this ); | ||
77 | |||
78 | // Stops (clear) Blip_Buffer structure | ||
79 | void Blip_stop( struct Blip_Buffer* this ); | ||
80 | |||
81 | // Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults | ||
82 | // to 1/4 second), then clear buffer. Returns NULL on success, otherwise if there | ||
83 | // isn't enough memory, returns error without affecting current buffer setup. | ||
84 | blargg_err_t Blip_set_sample_rate( struct Blip_Buffer* this, long samples_per_sec, int msec_length ); | ||
85 | |||
86 | // Set number of source time units per second | ||
87 | static inline void Blip_set_clock_rate( struct Blip_Buffer* this, long cps ) | ||
88 | { | ||
89 | this->factor_ = Blip_clock_rate_factor( this, this->clock_rate_ = cps ); | ||
90 | } | ||
91 | |||
92 | // End current time frame of specified duration and make its samples available | ||
93 | // (along with any still-unread samples) for reading with read_samples(). Begins | ||
94 | // a new time frame at the end of the current frame. | ||
95 | void Blip_end_frame( struct Blip_Buffer* this, blip_time_t time ) ICODE_ATTR; | ||
96 | |||
97 | // Read at most 'max_samples' out of buffer into 'dest', removing them from from | ||
98 | // the buffer. Returns number of samples actually read and removed. If stereo is | ||
99 | // true, increments 'dest' one extra time after writing each sample, to allow | ||
100 | // easy interleving of two channels into a stereo output buffer. | ||
101 | long Blip_read_samples( struct Blip_Buffer* this, blip_sample_t* dest, long max_samples, int stereo ) ICODE_ATTR; | ||
102 | |||
103 | // Additional optional features | ||
104 | |||
105 | // Current output sample rate | ||
106 | static inline long Blip_sample_rate( struct Blip_Buffer* this ) | ||
107 | { | ||
108 | return this->sample_rate_; | ||
109 | } | ||
110 | |||
111 | // Length of buffer, in milliseconds | ||
112 | static inline int Blip_length( struct Blip_Buffer* this ) | ||
113 | { | ||
114 | return this->length_; | ||
115 | } | ||
116 | |||
117 | // Number of source time units per second | ||
118 | static inline long Blip_clock_rate( struct Blip_Buffer* this ) | ||
119 | { | ||
120 | return this->clock_rate_; | ||
121 | } | ||
122 | |||
123 | |||
124 | // Set frequency high-pass filter frequency, where higher values reduce bass more | ||
125 | void Blip_bass_freq( struct Blip_Buffer* this, int frequency ); | ||
126 | |||
127 | // Number of samples delay from synthesis to samples read out | ||
128 | static inline int Blip_output_latency( void ) | ||
129 | { | ||
130 | return blip_widest_impulse_ / 2; | ||
131 | } | ||
132 | |||
133 | // Remove all available samples and clear buffer to silence. If 'entire_buffer' is | ||
134 | // false, just clears out any samples waiting rather than the entire buffer. | ||
135 | void Blip_clear( struct Blip_Buffer* this, int entire_buffer ); | ||
136 | |||
137 | // Number of samples available for reading with read_samples() | ||
138 | static inline long Blip_samples_avail( struct Blip_Buffer* this ) | ||
139 | { | ||
140 | return (long) (this->offset_ >> BLIP_BUFFER_ACCURACY); | ||
141 | } | ||
142 | |||
143 | // Remove 'count' samples from those waiting to be read | ||
144 | void Blip_remove_samples( struct Blip_Buffer* this, long count ) ICODE_ATTR; | ||
145 | |||
146 | // Experimental features | ||
147 | |||
148 | // Count number of clocks needed until 'count' samples will be available. | ||
149 | // If buffer can't even hold 'count' samples, returns number of clocks until | ||
150 | // buffer becomes full. | ||
151 | blip_time_t Blip_count_clocks( struct Blip_Buffer* this, long count ) ICODE_ATTR; | ||
152 | |||
153 | // Number of raw samples that can be mixed within frame of specified duration. | ||
154 | long Blip_count_samples( struct Blip_Buffer* this, blip_time_t duration ) ICODE_ATTR; | ||
155 | |||
156 | // Mix 'count' samples from 'buf' into buffer. | ||
157 | void Blip_mix_samples( struct Blip_Buffer* this, blip_sample_t const* buf, long count ) ICODE_ATTR; | ||
158 | |||
159 | // Range specifies the greatest expected change in amplitude. Calculate it | ||
160 | // by finding the difference between the maximum and minimum expected | ||
161 | // amplitudes (max - min). | ||
162 | |||
163 | struct Blip_Synth { | ||
164 | struct Blip_Buffer* buf; | ||
165 | int last_amp; | ||
166 | int delta_factor; | ||
167 | }; | ||
168 | |||
169 | // Initializes Blip_Synth structure | ||
170 | void Synth_init( struct Blip_Synth* this ); | ||
171 | |||
172 | // Set overall volume of waveform | ||
173 | void Synth_volume( struct Blip_Synth* this, double v ) ICODE_ATTR; | ||
174 | |||
175 | // Get/set Blip_Buffer used for output | ||
176 | const struct Blip_Buffer* Synth_output( struct Blip_Synth* this ) ICODE_ATTR; | ||
177 | |||
178 | // Low-level interface | ||
179 | |||
180 | #if defined (__GNUC__) || _MSC_VER >= 1100 | ||
181 | #define BLIP_RESTRICT __restrict | ||
182 | #else | ||
183 | #define BLIP_RESTRICT | ||
184 | #endif | ||
185 | |||
186 | // Works directly in terms of fractional output samples. Contact author for more info. | ||
187 | static inline void Synth_offset_resampled( struct Blip_Synth* this, blip_resampled_time_t time, | ||
188 | int delta, struct Blip_Buffer* blip_buf ) | ||
189 | { | ||
190 | // Fails if time is beyond end of Blip_Buffer, due to a bug in caller code or the | ||
191 | // need for a longer buffer as set by set_sample_rate(). | ||
192 | assert( (blip_long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ ); | ||
193 | delta *= this->delta_factor; | ||
194 | blip_long* BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY); | ||
195 | int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1)); | ||
196 | |||
197 | blip_long left = buf [0] + delta; | ||
198 | |||
199 | // Kind of crappy, but doing shift after multiply results in overflow. | ||
200 | // Alternate way of delaying multiply by delta_factor results in worse | ||
201 | // sub-sample resolution. | ||
202 | blip_long right = (delta >> BLIP_PHASE_BITS) * phase; | ||
203 | left -= right; | ||
204 | right += buf [1]; | ||
205 | |||
206 | buf [0] = left; | ||
207 | buf [1] = right; | ||
208 | } | ||
209 | |||
210 | // Update amplitude of waveform at given time. Using this requires a separate | ||
211 | // Blip_Synth for each waveform. | ||
212 | static inline void Synth_update( struct Blip_Synth* this, blip_time_t t, int amp ) | ||
213 | { | ||
214 | int delta = amp - this->last_amp; | ||
215 | this->last_amp = amp; | ||
216 | Synth_offset_resampled( this, t * this->buf->factor_ + this->buf->offset_, delta, this->buf ); | ||
217 | } | ||
218 | |||
219 | // Add an amplitude transition of specified delta, optionally into specified buffer | ||
220 | // rather than the one set with output(). Delta can be positive or negative. | ||
221 | // The actual change in amplitude is delta * (volume / range) | ||
222 | static inline void Synth_offset( struct Blip_Synth* this, blip_time_t t, int delta, struct Blip_Buffer* buf ) | ||
223 | { | ||
224 | Synth_offset_resampled( this, t * buf->factor_ + buf->offset_, delta, buf ); | ||
225 | } | ||
226 | |||
227 | // Same as offset(), except code is inlined for higher performance | ||
228 | static inline void Synth_offset_inline( struct Blip_Synth* this, blip_time_t t, int delta, struct Blip_Buffer* buf ) | ||
229 | { | ||
230 | Synth_offset_resampled( this, t * buf->factor_ + buf->offset_, delta, buf ); | ||
231 | } | ||
232 | |||
233 | // Optimized reading from Blip_Buffer, for use in custom sample output | ||
234 | |||
235 | // Begin reading from buffer. Name should be unique to the current block. | ||
236 | #define BLIP_READER_BEGIN( name, blip_buffer ) \ | ||
237 | buf_t_* BLIP_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\ | ||
238 | blip_long name##_reader_accum = (blip_buffer).reader_accum_ | ||
239 | |||
240 | // Get value to pass to BLIP_READER_NEXT() | ||
241 | #define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_) | ||
242 | |||
243 | // Current sample | ||
244 | #define BLIP_READER_READ( name ) (name##_reader_accum >> (blip_sample_bits - 16)) | ||
245 | |||
246 | // Current raw sample in full internal resolution | ||
247 | #define BLIP_READER_READ_RAW( name ) (name##_reader_accum) | ||
248 | |||
249 | // Advance to next sample | ||
250 | #define BLIP_READER_NEXT( name, bass ) \ | ||
251 | (void) (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass))) | ||
252 | |||
253 | // End reading samples from buffer. The number of samples read must now be removed | ||
254 | // using Blip_remove_samples(). | ||
255 | #define BLIP_READER_END( name, blip_buffer ) \ | ||
256 | (void) ((blip_buffer).reader_accum_ = name##_reader_accum) | ||
257 | |||
258 | #define BLIP_READER_ADJ_( name, offset ) (name##_reader_buf += offset) | ||
259 | |||
260 | #define BLIP_READER_NEXT_IDX_( name, bass, idx ) {\ | ||
261 | name##_reader_accum -= name##_reader_accum >> (bass);\ | ||
262 | name##_reader_accum += name##_reader_buf [(idx)];\ | ||
263 | } | ||
264 | |||
265 | //// BLIP_CLAMP | ||
266 | |||
267 | #if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \ | ||
268 | defined (__x86_64__) || defined (__ia64__) || defined (__i386__) | ||
269 | #define BLIP_X86 1 | ||
270 | #define BLIP_CLAMP_( in ) in < -0x8000 || 0x7FFF < in | ||
271 | #else | ||
272 | #define BLIP_CLAMP_( in ) (blip_sample_t) in != in | ||
273 | #endif | ||
274 | |||
275 | // Clamp sample to blip_sample_t range | ||
276 | #define BLIP_CLAMP( sample, out )\ | ||
277 | { if ( BLIP_CLAMP_( (sample) ) ) (out) = ((sample) >> 31) ^ 0x7FFF; } | ||
278 | |||
279 | #endif | ||