diff options
Diffstat (limited to 'apps/codecs/libgme/blip_buffer.h')
-rw-r--r-- | apps/codecs/libgme/blip_buffer.h | 342 |
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 | 9 | typedef unsigned blip_resampled_time_t; |
10 | #include "blargg_common.h" | 10 | typedef int blip_time_t; |
11 | #if INT_MAX >= 0x7FFFFFFF | 11 | typedef 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 | 14 | typedef 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 | 16 | static int const blip_default_length = 1000 / 4; // Default Blip_Buffer length (1/4 second) |
20 | typedef 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 | 31 | static int const blip_res = 1 << BLIP_PHASE_BITS; |
36 | typedef short blip_sample_t; | 32 | static int const blip_buffer_extra_ = BLIP_MAX_QUALITY + 2; |
37 | enum { blip_sample_max = 32767 }; | 33 | |
38 | enum { blip_widest_impulse_ = 16 }; | 34 | // Properties of fixed-point sample position |
39 | enum { blip_buffer_extra_ = blip_widest_impulse_ + 2 }; | 35 | typedef unsigned ufixed_t; // unsigned for more range, optimized shifts |
40 | enum { blip_res = 1 << BLIP_PHASE_BITS }; | 36 | enum { fixed_bits = BLIP_BUFFER_ACCURACY }; // bits in fraction |
41 | enum { blip_max_length = 0 }; | 37 | enum { fixed_unit = 1 << fixed_bits }; // 1.0 samples |
42 | enum { blip_default_length = 250 }; | 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; | ||
43 | 45 | ||
44 | // Maximun buffer size (48Khz, 50 ms) | 46 | // Maximun buffer size (48Khz, 50 ms) |
45 | enum { blip_buffer_max = 2466 }; | 47 | 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 | 48 | ||
52 | struct Blip_Buffer { | 49 | struct 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 |
68 | void Blip_set_modified( struct Blip_Buffer* this ); | 66 | static inline ufixed_t to_fixed( struct Blip_Buffer *this, clocks_t t ) |
69 | int Blip_clear_modified( struct Blip_Buffer* this ); | 67 | { |
70 | void Blip_remove_silence( struct Blip_Buffer* this, long count ); | 68 | return t * this->factor_ + this->offset_; |
71 | blip_resampled_time_t Blip_resampled_duration( struct Blip_Buffer* this, int t ); | 69 | } |
72 | blip_resampled_time_t Blip_resampled_time( struct Blip_Buffer* this, blip_time_t t ); | ||
73 | blip_resampled_time_t Blip_clock_rate_factor( struct Blip_Buffer* this, long clock_rate ); | ||
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 | 70 | ||
81 | // Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults | 71 | static 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_ ); |
84 | blargg_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() |
87 | static inline void Blip_set_clock_rate( struct Blip_Buffer* this, long cps ) | 78 | static 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 | 83 | static 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 |
95 | void 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 | 90 | void 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. | ||
101 | long 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 |
93 | blargg_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 |
106 | static inline long Blip_sample_rate( struct Blip_Buffer* this ) | 96 | static 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 |
112 | static inline int Blip_length( struct Blip_Buffer* this ) | 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 ) | ||
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 |
118 | static inline long Blip_clock_rate( struct Blip_Buffer* this ) | 109 | static 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 | ||
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; } | ||
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 |
125 | void Blip_bass_freq( struct Blip_Buffer* this, int frequency ); | 142 | void Blip_bass_freq( struct Blip_Buffer* this, int frequency ); |
126 | 143 | ||
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 | 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. | ||
135 | void 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 |
138 | static inline long Blip_samples_avail( struct Blip_Buffer* this ) | 148 | void 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. | ||
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; | ||
142 | 160 | ||
143 | // Remove 'count' samples from those waiting to be read | ||
144 | void 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. | ||
151 | blip_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 |
154 | long Blip_count_samples( struct Blip_Buffer* this, blip_time_t duration ); | 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 | } | ||
155 | 177 | ||
156 | // Mix 'count' samples from 'buf' into buffer. | ||
157 | void 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 | ||
183 | typedef char coeff_t; | ||
184 | |||
163 | struct Blip_Synth { | 185 | struct 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_ | ||
192 | void volume_unit( struct Blip_Synth* this, int new_unit ); | ||
193 | |||
169 | // Initializes Blip_Synth structure | 194 | // Initializes Blip_Synth structure |
170 | void Synth_init( struct Blip_Synth* this ); | 195 | void Synth_init( struct Blip_Synth* this ); |
171 | 196 | ||
172 | // Set overall volume of waveform | 197 | // Sets volume of amplitude delta unit |
173 | void Synth_volume( struct Blip_Synth* this, int v ); | 198 | static 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 | ||
176 | const 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. | ||
187 | static inline void Synth_offset_resampled( struct Blip_Synth* this, blip_resampled_time_t time, | 216 | static 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) | ||
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 ) | 257 | static 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 | ||
268 | static 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 | ||
282 | static 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 |