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