summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libgme/blip_buffer.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libgme/blip_buffer.h')
-rw-r--r--lib/rbcodec/codecs/libgme/blip_buffer.h335
1 files changed, 335 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libgme/blip_buffer.h b/lib/rbcodec/codecs/libgme/blip_buffer.h
new file mode 100644
index 0000000000..5fe1f4b9c6
--- /dev/null
+++ b/lib/rbcodec/codecs/libgme/blip_buffer.h
@@ -0,0 +1,335 @@
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 "blargg_common.h"
8
9typedef unsigned blip_resampled_time_t;
10typedef int blip_time_t;
11typedef int clocks_t;
12
13// Output samples are 16-bit signed, with a range of -32768 to 32767
14typedef short blip_sample_t;
15
16static int const blip_default_length = 1000 / 4; // Default Blip_Buffer length (1/4 second)
17
18#ifndef BLIP_MAX_QUALITY
19 #define BLIP_MAX_QUALITY 2
20#endif
21
22#ifndef BLIP_BUFFER_ACCURACY
23 #define BLIP_BUFFER_ACCURACY 16
24#endif
25
26// linear interpolation needs 8 bits
27#ifndef BLIP_PHASE_BITS
28 #define BLIP_PHASE_BITS 8
29#endif
30
31static int const blip_res = 1 << BLIP_PHASE_BITS;
32static int const blip_buffer_extra_ = BLIP_MAX_QUALITY + 2;
33
34// Properties of fixed-point sample position
35typedef unsigned ufixed_t; // unsigned for more range, optimized shifts
36enum { fixed_bits = BLIP_BUFFER_ACCURACY }; // bits in fraction
37enum { fixed_unit = 1 << fixed_bits }; // 1.0 samples
38
39// Deltas in buffer are fixed-point with this many fraction bits.
40// Less than 16 for extra range.
41enum { delta_bits = 14 };
42
43// Pointer to first committed delta sample
44typedef int delta_t;
45
46// Maximun buffer size (48Khz, 50 ms)
47enum { blip_buffer_max = 2466 };
48
49struct Blip_Buffer {
50 unsigned factor_;
51 ufixed_t offset_;
52 delta_t* buffer_center_;
53 int buffer_size_;
54 int reader_accum_;
55 int bass_shift_;
56 int bass_freq_;
57 int sample_rate_;
58 int clock_rate_;
59 int length_;
60 bool modified;
61
62 delta_t buffer_ [blip_buffer_max];
63};
64
65// Blip_Buffer_ implementation
66static inline ufixed_t to_fixed( struct Blip_Buffer *this, clocks_t t )
67{
68 return t * this->factor_ + this->offset_;
69}
70
71static inline delta_t* delta_at( struct Blip_Buffer *this, ufixed_t f )
72{
73 assert( (f >> fixed_bits) < (unsigned) this->buffer_size_ );
74 return this->buffer_center_ + (f >> fixed_bits);
75}
76
77// Number of samples available for reading with read_samples()
78static inline int Blip_samples_avail( struct Blip_Buffer* this )
79{
80 return (int) (this->offset_ >> BLIP_BUFFER_ACCURACY);
81}
82
83static inline void Blip_remove_silence( struct Blip_Buffer* this, int count )
84{
85 assert( count <= Blip_samples_avail( this ) ); // tried to remove more samples than available
86 this->offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
87}
88
89// Initializes Blip_Buffer structure
90void Blip_init( struct Blip_Buffer* this );
91
92// Sets output sample rate and resizes and clears sample buffer
93blargg_err_t Blip_set_sample_rate( struct Blip_Buffer* this, int samples_per_sec, int msec_length );
94
95// Current output sample rate
96static inline int Blip_sample_rate( struct Blip_Buffer* this )
97{
98 return this->sample_rate_;
99}
100
101// Sets number of source time units per second
102blip_resampled_time_t Blip_clock_rate_factor( struct Blip_Buffer* this, int clock_rate );
103static inline void Blip_set_clock_rate( struct Blip_Buffer* this, int clocks_per_sec )
104{
105 this->factor_ = Blip_clock_rate_factor( this, this->clock_rate_ = clocks_per_sec );
106}
107
108// Number of source time units per second
109static inline int Blip_clock_rate( struct Blip_Buffer* this )
110{
111 return this->clock_rate_;
112}
113
114static inline int Blip_length( struct Blip_Buffer* this )
115{
116 return this->length_;
117}
118
119// Clears buffer and removes all samples
120void Blip_clear( struct Blip_Buffer* this );
121
122// Use Blip_Synth to add waveform to buffer
123
124// Resamples to time t, then subtracts t from current time. Appends result of resampling
125// to buffer for reading.
126void Blip_end_frame( struct Blip_Buffer* this, blip_time_t time ) ICODE_ATTR;
127
128
129// Reads at most n samples to out [0 to n-1] and returns number actually read. If stereo
130// is true, writes to out [0], out [2], out [4] etc. instead.
131int Blip_read_samples( struct Blip_Buffer* this, blip_sample_t out [], int n, bool stereo ) ICODE_ATTR;
132
133
134// More features
135
136// Sets flag that tells some Multi_Buffer types that sound was added to buffer,
137// so they know that it needs to be mixed in. Only needs to be called once
138// per time frame that sound was added. Not needed if not using Multi_Buffer.
139static inline void Blip_set_modified( struct Blip_Buffer* this ) { this->modified = true; }
140
141// Set frequency high-pass filter frequency, where higher values reduce bass more
142void Blip_bass_freq( struct Blip_Buffer* this, int frequency );
143
144
145// Low-level features
146
147// Removes the first n samples
148void Blip_remove_samples( struct Blip_Buffer* this, int n ) ICODE_ATTR;
149
150// Returns number of clocks needed until n samples will be available.
151// If buffer cannot even hold n samples, returns number of clocks
152// until buffer becomes full.
153blip_time_t Blip_count_clocks( struct Blip_Buffer* this, int count ) ICODE_ATTR;
154
155// Number of samples that should be mixed before calling Blip_end_frame( t )
156int Blip_count_samples( struct Blip_Buffer* this, blip_time_t t ) ICODE_ATTR;
157
158// Mixes n samples into buffer
159void Blip_mix_samples( struct Blip_Buffer* this, blip_sample_t const in [], int n ) ICODE_ATTR;
160
161
162// Resampled time (sorry, poor documentation right now)
163
164// Resampled time is fixed-point, in terms of output samples.
165
166// Converts clock count to resampled time
167static inline blip_resampled_time_t Blip_resampled_duration( struct Blip_Buffer* this, int t )
168{
169 return t * this->factor_;
170}
171
172// Converts clock time since beginning of current time frame to resampled time
173static inline blip_resampled_time_t Blip_resampled_time( struct Blip_Buffer* this, blip_time_t t )
174{
175 return t * this->factor_ + this->offset_;
176}
177
178
179// Range specifies the greatest expected change in amplitude. Calculate it
180// by finding the difference between the maximum and minimum expected
181// amplitudes (max - min).
182
183typedef char coeff_t;
184
185struct Blip_Synth {
186 int delta_factor;
187 int last_amp;
188 struct Blip_Buffer* buf;
189};
190
191// Blip_Synth_
192void volume_unit( struct Blip_Synth* this, int new_unit );
193
194// Initializes Blip_Synth structure
195void Synth_init( struct Blip_Synth* this );
196
197// Sets volume of amplitude delta unit
198static inline void Synth_volume( struct Blip_Synth* this, int v )
199{
200 volume_unit( this, v ); // new_unit = 1 / range * v
201}
202
203
204// Low-level interface
205
206// (in >> sh & mask) * mul
207#define BLIP_SH_AND_MUL( in, sh, mask, mul ) \
208((int) (in) / ((1U << (sh)) / (mul)) & (unsigned) ((mask) * (mul)))
209
210// (T*) ptr + (off >> sh)
211#define BLIP_PTR_OFF_SH( T, ptr, off, sh ) \
212 ((T*) (BLIP_SH_AND_MUL( off, sh, -1, sizeof (T) ) + (char*) (ptr)))
213
214// Works directly in terms of fractional output samples. Use resampled time functions in Blip_Buffer
215// to convert clock counts to resampled time.
216static inline void Synth_offset_resampled( struct Blip_Synth* this, blip_resampled_time_t time,
217 int delta, struct Blip_Buffer* blip_buf )
218{
219 int const half_width = 1;
220
221 delta_t* BLARGG_RESTRICT buf = delta_at( blip_buf, time );
222 delta *= this->delta_factor;
223
224 int const phase_shift = BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS;
225 int const phase = (half_width & (half_width - 1)) ?
226 (int) BLIP_SH_AND_MUL( time, phase_shift, blip_res - 1, sizeof (coeff_t) ) * half_width :
227 (int) BLIP_SH_AND_MUL( time, phase_shift, blip_res - 1, sizeof (coeff_t) * half_width );
228
229 int left = buf [0] + delta;
230
231 // Kind of crappy, but doing shift after multiply results in overflow.
232 // Alternate way of delaying multiply by delta_factor results in worse
233 // sub-sample resolution.
234 int right = (delta >> BLIP_PHASE_BITS) * phase;
235 #ifdef BLIP_BUFFER_NOINTERP
236 // TODO: remove? (just a hack to see how it sounds)
237 right = 0;
238 #endif
239 left -= right;
240 right += buf [1];
241
242 buf [0] = left;
243 buf [1] = right;
244}
245
246// Update amplitude of waveform at given time. Using this requires a separate
247// Blip_Synth for each waveform.
248static inline void Synth_update( struct Blip_Synth* this, blip_time_t t, int amp )
249{
250 int delta = amp - this->last_amp;
251 this->last_amp = amp;
252 Synth_offset_resampled( this, to_fixed(this->buf, t), delta, this->buf );
253}
254
255// Adds amplitude transition at time t. Delta can be positive or negative.
256// The actual change in amplitude is delta * volume.
257static inline void Synth_offset_inline( struct Blip_Synth* this, blip_time_t t, int delta, struct Blip_Buffer* buf )
258{
259 Synth_offset_resampled( this, to_fixed(buf, t), delta, buf );
260}
261
262#define Synth_offset( synth, time, delta, buf ) Synth_offset_inline( synth, time, delta, buf )
263
264// Number of bits in raw sample that covers normal output range. Less than 32 bits to give
265// extra amplitude range. That is,
266// +1 << (blip_sample_bits-1) = +1.0
267// -1 << (blip_sample_bits-1) = -1.0
268static int const blip_sample_bits = 30;
269
270// Optimized reading from Blip_Buffer, for use in custom sample output
271
272// Begin reading from buffer. Name should be unique to the current block.
273#define BLIP_READER_BEGIN( name, blip_buffer ) \
274 const delta_t* BLARGG_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\
275 int name##_reader_accum = (blip_buffer).reader_accum_
276
277// Get value to pass to BLIP_READER_NEXT()
278#define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_)
279
280// Constant value to use instead of BLIP_READER_BASS(), for slightly more optimal
281// code at the cost of having no bass_freq() functionality
282static int const blip_reader_default_bass = 9;
283
284// Current sample
285#define BLIP_READER_READ( name ) (name##_reader_accum >> (blip_sample_bits - 16))
286
287// Current raw sample in full internal resolution
288#define BLIP_READER_READ_RAW( name ) (name##_reader_accum)
289
290// Advance to next sample
291#define BLIP_READER_NEXT( name, bass ) \
292 (void) (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass)))
293
294// End reading samples from buffer. The number of samples read must now be removed
295// using Blip_remove_samples().
296#define BLIP_READER_END( name, blip_buffer ) \
297 (void) ((blip_buffer).reader_accum_ = name##_reader_accum)
298
299#define BLIP_READER_ADJ_( name, offset ) (name##_reader_buf += offset)
300
301#define BLIP_READER_NEXT_IDX_( name, bass, idx ) {\
302 name##_reader_accum -= name##_reader_accum >> (bass);\
303 name##_reader_accum += name##_reader_buf [(idx)];\
304}
305
306#define BLIP_READER_NEXT_RAW_IDX_( name, bass, idx ) {\
307 name##_reader_accum -= name##_reader_accum >> (bass);\
308 name##_reader_accum +=\
309 *(delta_t const*) ((char const*) name##_reader_buf + (idx));\
310}
311
312//// BLIP_CLAMP
313
314#if defined(CPU_ARM) && (ARM_ARCH >= 6)
315 #define BLIP_CLAMP( sample, out ) \
316 ({ \
317 asm ("ssat %0, #16, %1" \
318 : "=r" ( out ) : "r"( sample ) ); \
319 out; \
320 })
321#else
322 #if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \
323 defined (__x86_64__) || defined (__ia64__) || defined (__i386__)
324 #define BLIP_X86 1
325 #define BLIP_CLAMP_( in ) in < -0x8000 || 0x7FFF < in
326 #else
327 #define BLIP_CLAMP_( in ) (blip_sample_t) in != in
328 #endif
329
330 // Clamp sample to blip_sample_t range
331 #define BLIP_CLAMP( sample, out )\
332 { if ( BLIP_CLAMP_( (sample) ) ) (out) = ((sample) >> 31) ^ 0x7FFF; }
333#endif
334
335#endif