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.h279
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
20typedef 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
36typedef short blip_sample_t;
37enum { blip_sample_max = 32767 };
38enum { blip_widest_impulse_ = 16 };
39enum { blip_buffer_extra_ = blip_widest_impulse_ + 2 };
40enum { blip_res = 1 << BLIP_PHASE_BITS };
41enum { blip_max_length = 0 };
42enum { blip_default_length = 250 };
43
44// Maximun buffer size (48Khz, 50 ms)
45enum { 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
52struct 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
68void Blip_set_modified( struct Blip_Buffer* this ) ICODE_ATTR;
69int Blip_clear_modified( struct Blip_Buffer* this ) ICODE_ATTR;
70void Blip_remove_silence( struct Blip_Buffer* this, long count ) ICODE_ATTR;
71blip_resampled_time_t Blip_resampled_duration( struct Blip_Buffer* this, int t ) ICODE_ATTR;
72blip_resampled_time_t Blip_resampled_time( struct Blip_Buffer* this, blip_time_t t ) ICODE_ATTR;
73blip_resampled_time_t Blip_clock_rate_factor( struct Blip_Buffer* this, long clock_rate ) ICODE_ATTR;
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
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.
84blargg_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
87static 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.
95void 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.
101long 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
106static inline long Blip_sample_rate( struct Blip_Buffer* this )
107{
108 return this->sample_rate_;
109}
110
111// Length of buffer, in milliseconds
112static inline int Blip_length( struct Blip_Buffer* this )
113{
114 return this->length_;
115}
116
117// Number of source time units per second
118static 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
125void Blip_bass_freq( struct Blip_Buffer* this, int frequency );
126
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
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.
135void Blip_clear( struct Blip_Buffer* this, int entire_buffer );
136
137// Number of samples available for reading with read_samples()
138static 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
144void 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.
151blip_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.
154long Blip_count_samples( struct Blip_Buffer* this, blip_time_t duration ) ICODE_ATTR;
155
156// Mix 'count' samples from 'buf' into buffer.
157void 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
163struct Blip_Synth {
164 struct Blip_Buffer* buf;
165 int last_amp;
166 int delta_factor;
167};
168
169// Initializes Blip_Synth structure
170void Synth_init( struct Blip_Synth* this );
171
172// Set overall volume of waveform
173void Synth_volume( struct Blip_Synth* this, double v ) ICODE_ATTR;
174
175// Get/set Blip_Buffer used for output
176const 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.
187static 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.
212static 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)
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 )
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