diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/libgme/blip_buffer.h | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/libgme/blip_buffer.h')
-rw-r--r-- | lib/rbcodec/codecs/libgme/blip_buffer.h | 335 |
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 | |||
9 | typedef unsigned blip_resampled_time_t; | ||
10 | typedef int blip_time_t; | ||
11 | typedef int clocks_t; | ||
12 | |||
13 | // Output samples are 16-bit signed, with a range of -32768 to 32767 | ||
14 | typedef short blip_sample_t; | ||
15 | |||
16 | static 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 | |||
31 | static int const blip_res = 1 << BLIP_PHASE_BITS; | ||
32 | static int const blip_buffer_extra_ = BLIP_MAX_QUALITY + 2; | ||
33 | |||
34 | // Properties of fixed-point sample position | ||
35 | typedef unsigned ufixed_t; // unsigned for more range, optimized shifts | ||
36 | enum { fixed_bits = BLIP_BUFFER_ACCURACY }; // bits in fraction | ||
37 | enum { 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. | ||
41 | enum { delta_bits = 14 }; | ||
42 | |||
43 | // Pointer to first committed delta sample | ||
44 | typedef int delta_t; | ||
45 | |||
46 | // Maximun buffer size (48Khz, 50 ms) | ||
47 | enum { blip_buffer_max = 2466 }; | ||
48 | |||
49 | struct 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 | ||
66 | static inline ufixed_t to_fixed( struct Blip_Buffer *this, clocks_t t ) | ||
67 | { | ||
68 | return t * this->factor_ + this->offset_; | ||
69 | } | ||
70 | |||
71 | static 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() | ||
78 | static inline int Blip_samples_avail( struct Blip_Buffer* this ) | ||
79 | { | ||
80 | return (int) (this->offset_ >> BLIP_BUFFER_ACCURACY); | ||
81 | } | ||
82 | |||
83 | static 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 | ||
90 | void Blip_init( struct Blip_Buffer* this ); | ||
91 | |||
92 | // Sets output sample rate and resizes and clears sample buffer | ||
93 | blargg_err_t Blip_set_sample_rate( struct Blip_Buffer* this, int samples_per_sec, int msec_length ); | ||
94 | |||
95 | // Current output sample rate | ||
96 | static 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 | ||
102 | blip_resampled_time_t Blip_clock_rate_factor( struct Blip_Buffer* this, int clock_rate ); | ||
103 | static 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 | ||
109 | static inline int Blip_clock_rate( struct Blip_Buffer* this ) | ||
110 | { | ||
111 | return this->clock_rate_; | ||
112 | } | ||
113 | |||
114 | static inline int Blip_length( struct Blip_Buffer* this ) | ||
115 | { | ||
116 | return this->length_; | ||
117 | } | ||
118 | |||
119 | // Clears buffer and removes all samples | ||
120 | void 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. | ||
126 | void 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. | ||
131 | int 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. | ||
139 | static 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 | ||
142 | void Blip_bass_freq( struct Blip_Buffer* this, int frequency ); | ||
143 | |||
144 | |||
145 | // Low-level features | ||
146 | |||
147 | // Removes the first n samples | ||
148 | void 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. | ||
153 | blip_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 ) | ||
156 | int Blip_count_samples( struct Blip_Buffer* this, blip_time_t t ) ICODE_ATTR; | ||
157 | |||
158 | // Mixes n samples into buffer | ||
159 | void 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 | ||
167 | static 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 | ||
173 | static 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 | |||
183 | typedef char coeff_t; | ||
184 | |||
185 | struct Blip_Synth { | ||
186 | int delta_factor; | ||
187 | int last_amp; | ||
188 | struct Blip_Buffer* buf; | ||
189 | }; | ||
190 | |||
191 | // Blip_Synth_ | ||
192 | void volume_unit( struct Blip_Synth* this, int new_unit ); | ||
193 | |||
194 | // Initializes Blip_Synth structure | ||
195 | void Synth_init( struct Blip_Synth* this ); | ||
196 | |||
197 | // Sets volume of amplitude delta unit | ||
198 | static 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. | ||
216 | static 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. | ||
248 | static 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. | ||
257 | static 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 | ||
268 | static 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 | ||
282 | static 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 | ||