* Removed a couple files that were not being used.
* Cleanups found with clang's -Weverything (and shutting it up about a
lot of things that were ridiculous, as well as ignoring some of the
warnings still coming up).
| ... | ... |
@@ -120,7 +120,7 @@ enum { BLIP_BUFFER_ACCURACY = 16 };
|
| 120 | 120 |
// Affects size of Blip_Synth objects since they store the waveform directly. |
| 121 | 121 |
enum |
| 122 | 122 |
{
|
| 123 |
-#if BLIP_BUFFER_FAST |
|
| 123 |
+#ifdef BLIP_BUFFER_FAST |
|
| 124 | 124 |
BLIP_PHASE_BITS = 8 |
| 125 | 125 |
#else |
| 126 | 126 |
BLIP_PHASE_BITS = 6 |
| ... | ... |
@@ -218,7 +218,7 @@ public: |
| 218 | 218 |
} |
| 219 | 219 |
|
| 220 | 220 |
private: |
| 221 |
-#if BLIP_BUFFER_FAST |
|
| 221 |
+#ifdef BLIP_BUFFER_FAST |
|
| 222 | 222 |
Blip_Synth_Fast_ impl; |
| 223 | 223 |
#else |
| 224 | 224 |
Blip_Synth_ impl; |
| ... | ... |
@@ -316,7 +316,7 @@ template<int quality, int range> inline void Blip_Synth<quality, range>::offset_ |
| 316 | 316 |
auto buf = &blip_buf->buffer_[time >> BLIP_BUFFER_ACCURACY]; |
| 317 | 317 |
int phase = static_cast<int>(time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1)); |
| 318 | 318 |
|
| 319 |
-#if BLIP_BUFFER_FAST |
|
| 319 |
+#ifdef BLIP_BUFFER_FAST |
|
| 320 | 320 |
int32_t left = buf[0] + delta; |
| 321 | 321 |
|
| 322 | 322 |
// Kind of crappy, but doing shift after multiply results in overflow. |
| ... | ... |
@@ -19,7 +19,7 @@ public: |
| 19 | 19 |
// Sets output sample rate and buffer length in milliseconds (1/1000 sec, defaults |
| 20 | 20 |
// to 1/4 second) and clears buffer. If there isn't enough memory, leaves buffer |
| 21 | 21 |
// untouched and returns "Out of memory", otherwise returns NULL. |
| 22 |
- void set_sample_rate(long samples_per_sec, int msec_length = 250); |
|
| 22 |
+ void set_sample_rate(long samples_per_sec, long msec_length = 250); |
|
| 23 | 23 |
|
| 24 | 24 |
// Sets number of source time units per second |
| 25 | 25 |
void clock_rate(long clocks_per_sec); |
| ... | ... |
@@ -54,7 +54,7 @@ public: |
| 54 | 54 |
long sample_rate() const; |
| 55 | 55 |
|
| 56 | 56 |
// Length of buffer in milliseconds |
| 57 |
- int length() const; |
|
| 57 |
+ int32_t length() const; |
|
| 58 | 58 |
|
| 59 | 59 |
// Number of source time units per second |
| 60 | 60 |
long clock_rate() const; |
| ... | ... |
@@ -107,7 +107,7 @@ private: |
| 107 | 107 |
long sample_rate_; |
| 108 | 108 |
long clock_rate_; |
| 109 | 109 |
int bass_freq_; |
| 110 |
- int length_; |
|
| 110 |
+ int32_t length_; |
|
| 111 | 111 |
Blip_Buffer *modified_; // non-zero = true (more optimal than using bool, heh) |
| 112 | 112 |
}; |
| 113 | 113 |
|
| ... | ... |
@@ -421,7 +421,7 @@ template<int quality, int range> inline void Blip_Synth<quality, range>::update( |
| 421 | 421 |
inline blip_eq_t::blip_eq_t(double t) : treble(t), rolloff_freq(0), sample_rate(44100), cutoff_freq(0) { }
|
| 422 | 422 |
inline blip_eq_t::blip_eq_t(double t, long rf, long sr, long cf) : treble(t), rolloff_freq(rf), sample_rate(sr), cutoff_freq(cf) { }
|
| 423 | 423 |
|
| 424 |
-inline int Blip_Buffer::length() const { return this->length_; }
|
|
| 424 |
+inline int32_t Blip_Buffer::length() const { return this->length_; }
|
|
| 425 | 425 |
inline long Blip_Buffer::samples_avail() const { return static_cast<long>(this->offset_ >> BLIP_BUFFER_ACCURACY); }
|
| 426 | 426 |
inline long Blip_Buffer::sample_rate() const { return this->sample_rate_; }
|
| 427 | 427 |
inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; }
|
| ... | ... |
@@ -1,8 +1,7 @@ |
| 1 | 1 |
// Band-limited sound synthesis buffer |
| 2 | 2 |
|
| 3 | 3 |
// Blip_Buffer 0.4.1 |
| 4 |
-#ifndef BLIP_BUFFER_H |
|
| 5 |
-#define BLIP_BUFFER_H |
|
| 4 |
+#pragma once |
|
| 6 | 5 |
|
| 7 | 6 |
#include <vector> |
| 8 | 7 |
#include <cstdint> |
| ... | ... |
@@ -11,7 +10,7 @@ |
| 11 | 10 |
typedef int32_t blip_time_t; |
| 12 | 11 |
|
| 13 | 12 |
// Output samples are 16-bit signed, with a range of -32768 to 32767 |
| 14 |
-typedef short blip_sample_t; |
|
| 13 |
+typedef int16_t blip_sample_t; |
|
| 15 | 14 |
enum { blip_sample_max = 32767 };
|
| 16 | 15 |
|
| 17 | 16 |
class Blip_Buffer |
| ... | ... |
@@ -20,7 +19,7 @@ public: |
| 20 | 19 |
// Sets output sample rate and buffer length in milliseconds (1/1000 sec, defaults |
| 21 | 20 |
// to 1/4 second) and clears buffer. If there isn't enough memory, leaves buffer |
| 22 | 21 |
// untouched and returns "Out of memory", otherwise returns NULL. |
| 23 |
- void set_sample_rate(long samples_per_sec, int msec_length = 1000 / 4); |
|
| 22 |
+ void set_sample_rate(long samples_per_sec, int msec_length = 250); |
|
| 24 | 23 |
|
| 25 | 24 |
// Sets number of source time units per second |
| 26 | 25 |
void clock_rate(long clocks_per_sec); |
| ... | ... |
@@ -89,11 +88,9 @@ public: |
| 89 | 88 |
blip_resampled_time_t resampled_duration(int t) const { return t * this->factor_; }
|
| 90 | 89 |
blip_resampled_time_t resampled_time(blip_time_t t) const { return t * this->factor_ + this->offset_; }
|
| 91 | 90 |
blip_resampled_time_t clock_rate_factor(long clock_rate) const; |
| 91 |
+ |
|
| 92 | 92 |
Blip_Buffer(); |
| 93 | 93 |
virtual ~Blip_Buffer(); |
| 94 |
- |
|
| 95 |
- // Deprecated |
|
| 96 |
- typedef blip_resampled_time_t resampled_time_t; |
|
| 97 | 94 |
private: |
| 98 | 95 |
// noncopyable |
| 99 | 96 |
Blip_Buffer(const Blip_Buffer &); |
| ... | ... |
@@ -116,22 +113,28 @@ private: |
| 116 | 113 |
|
| 117 | 114 |
// Number of bits in resample ratio fraction. Higher values give a more accurate ratio |
| 118 | 115 |
// but reduce maximum buffer size. |
| 119 |
-const int BLIP_BUFFER_ACCURACY = 16; |
|
| 116 |
+enum { BLIP_BUFFER_ACCURACY = 16 };
|
|
| 120 | 117 |
|
| 121 | 118 |
// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in |
| 122 | 119 |
// noticeable broadband noise when synthesizing high frequency square waves. |
| 123 | 120 |
// Affects size of Blip_Synth objects since they store the waveform directly. |
| 121 |
+enum |
|
| 122 |
+{
|
|
| 124 | 123 |
#if BLIP_BUFFER_FAST |
| 125 |
-const int BLIP_PHASE_BITS = 8; |
|
| 124 |
+ BLIP_PHASE_BITS = 8 |
|
| 126 | 125 |
#else |
| 127 |
-const int BLIP_PHASE_BITS = 6; |
|
| 126 |
+ BLIP_PHASE_BITS = 6 |
|
| 128 | 127 |
#endif |
| 128 |
+}; |
|
| 129 | 129 |
|
| 130 | 130 |
// Internal |
| 131 | 131 |
typedef uint32_t blip_resampled_time_t; |
| 132 |
-const int blip_widest_impulse_ = 16; |
|
| 133 |
-const int blip_buffer_extra_ = blip_widest_impulse_ + 2; |
|
| 134 |
-const int blip_res = 1 << BLIP_PHASE_BITS; |
|
| 132 |
+enum |
|
| 133 |
+{
|
|
| 134 |
+ blip_widest_impulse_ = 16, |
|
| 135 |
+ blip_buffer_extra_ = blip_widest_impulse_ + 2, |
|
| 136 |
+ blip_res = 1 << BLIP_PHASE_BITS |
|
| 137 |
+}; |
|
| 135 | 138 |
class blip_eq_t; |
| 136 | 139 |
|
| 137 | 140 |
class Blip_Synth_Fast_ |
| ... | ... |
@@ -166,9 +169,12 @@ private: |
| 166 | 169 |
}; |
| 167 | 170 |
|
| 168 | 171 |
// Quality level, better = slower. In general, use blip_good_quality. |
| 169 |
-const int blip_med_quality = 8; |
|
| 170 |
-const int blip_good_quality = 12; |
|
| 171 |
-const int blip_high_quality = 16; |
|
| 172 |
+enum |
|
| 173 |
+{
|
|
| 174 |
+ blip_med_quality = 8, |
|
| 175 |
+ blip_good_quality = 12, |
|
| 176 |
+ blip_high_quality = 16 |
|
| 177 |
+}; |
|
| 172 | 178 |
|
| 173 | 179 |
// Range specifies the greatest expected change in amplitude. Calculate it |
| 174 | 180 |
// by finding the difference between the maximum and minimum expected |
| ... | ... |
@@ -216,7 +222,7 @@ private: |
| 216 | 222 |
Blip_Synth_Fast_ impl; |
| 217 | 223 |
#else |
| 218 | 224 |
Blip_Synth_ impl; |
| 219 |
- typedef short imp_t; |
|
| 225 |
+ typedef int16_t imp_t; |
|
| 220 | 226 |
imp_t impulses[blip_res * (quality / 2) + 1]; |
| 221 | 227 |
public: |
| 222 | 228 |
Blip_Synth() : impl(impulses, quality) { }
|
| ... | ... |
@@ -243,21 +249,21 @@ private: |
| 243 | 249 |
friend class Blip_Synth_; |
| 244 | 250 |
}; |
| 245 | 251 |
|
| 246 |
-const int blip_sample_bits = 30; |
|
| 252 |
+enum { blip_sample_bits = 30 };
|
|
| 247 | 253 |
|
| 248 | 254 |
// Optimized reading from Blip_Buffer, for use in custom sample output |
| 249 | 255 |
|
| 250 | 256 |
// Begins reading from buffer. Name should be unique to the current block. |
| 251 | 257 |
#define BLIP_READER_BEGIN(name, blip_buffer) \ |
| 252 |
- auto name##_reader_buf = &(blip_buffer).buffer_[0]; \ |
|
| 258 |
+ const Blip_Buffer::buf_t_ *name##_reader_buf = &(blip_buffer).buffer_[0]; \ |
|
| 253 | 259 |
int32_t name##_reader_accum = (blip_buffer).reader_accum_ |
| 254 | 260 |
|
| 255 | 261 |
// Gets value to pass to BLIP_READER_NEXT() |
| 256 |
-inline int BLIP_READER_BASS(const Blip_Buffer &blip_buffer) { return blip_buffer.bass_shift_; }
|
|
| 262 |
+inline int BLIP_READER_BASS(const Blip_Buffer *blip_buffer) { return blip_buffer->bass_shift_; }
|
|
| 257 | 263 |
|
| 258 | 264 |
// Constant value to use instead of BLIP_READER_BASS(), for slightly more optimal |
| 259 | 265 |
// code at the cost of having no bass control |
| 260 |
-const int blip_reader_default_bass = 9; |
|
| 266 |
+enum { blip_reader_default_bass = 9 };
|
|
| 261 | 267 |
|
| 262 | 268 |
// Current sample |
| 263 | 269 |
#define BLIP_READER_READ(name) (name##_reader_accum >> (blip_sample_bits - 16)) |
| ... | ... |
@@ -283,12 +289,6 @@ const int blip_reader_default_bass = 9; |
| 283 | 289 |
name##_reader_accum += name##_reader_buf[(idx)]; \ |
| 284 | 290 |
} |
| 285 | 291 |
|
| 286 |
-#define BLIP_READER_NEXT_RAW_IDX_(name, bass, idx) \ |
|
| 287 |
-{ \
|
|
| 288 |
- name##_reader_accum -= name##_reader_accum >> (bass); \ |
|
| 289 |
- name##_reader_accum += *reinterpret_cast<const Blip_Buffer::buf_t_ *>(reinterpret_cast<const char *>(name##_reader_buf) + (idx)); \ |
|
| 290 |
-} |
|
| 291 |
- |
|
| 292 | 292 |
#if defined(_M_IX86) || defined(_M_IA64) || defined(__i486__) || defined(__x86_64__) || defined(__ia64__) || defined(__i386__) |
| 293 | 293 |
template<typename T> inline bool BLIP_CLAMP_(const T &in) { return in < -0x8000 || 0x7FFF < in; }
|
| 294 | 294 |
#else |
| ... | ... |
@@ -304,9 +304,7 @@ template<typename T1, typename T2> inline void BLIP_CLAMP(const T1 &sample, T2 & |
| 304 | 304 |
|
| 305 | 305 |
// End of public interface |
| 306 | 306 |
|
| 307 |
-#ifndef assert |
|
| 308 |
-# include <cassert> |
|
| 309 |
-#endif |
|
| 307 |
+#include <cassert> |
|
| 310 | 308 |
|
| 311 | 309 |
template<int quality, int range> inline void Blip_Synth<quality, range>::offset_resampled(blip_resampled_time_t time, int delta, Blip_Buffer *blip_buf) const |
| 312 | 310 |
{
|
| ... | ... |
@@ -316,7 +314,7 @@ template<int quality, int range> inline void Blip_Synth<quality, range>::offset_ |
| 316 | 314 |
|
| 317 | 315 |
delta *= this->impl.delta_factor; |
| 318 | 316 |
auto buf = &blip_buf->buffer_[time >> BLIP_BUFFER_ACCURACY]; |
| 319 |
- int phase = static_cast<int>((time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS)) & (blip_res - 1)); |
|
| 317 |
+ int phase = static_cast<int>(time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1)); |
|
| 320 | 318 |
|
| 321 | 319 |
#if BLIP_BUFFER_FAST |
| 322 | 320 |
int32_t left = buf[0] + delta; |
| ... | ... |
@@ -335,12 +333,12 @@ template<int quality, int range> inline void Blip_Synth<quality, range>::offset_ |
| 335 | 333 |
int rev = fwd + quality - 2; |
| 336 | 334 |
int mid = quality / 2 - 1; |
| 337 | 335 |
|
| 338 |
- auto imp = this->impulses + blip_res - phase; |
|
| 336 |
+ auto imp = &this->impulses[blip_res - phase]; |
|
| 339 | 337 |
|
| 340 | 338 |
# if defined(_M_IX86) || defined(_M_IA64) || defined(__i486__) || defined(__x86_64__) || defined(__ia64__) || defined(__i386__) |
| 341 | 339 |
// this straight forward version gave in better code on GCC for x86 |
| 342 | 340 |
|
| 343 |
- auto ADD_IMP = [&](int out, int in) { buf[out] += static_cast<int32_t>(imp[blip_res * in] * delta); };
|
|
| 341 |
+ auto ADD_IMP = [&](int out, int in) { buf[out] += static_cast<int32_t>(imp[blip_res * in]) * delta; };
|
|
| 344 | 342 |
|
| 345 | 343 |
auto BLIP_FWD = [&](int i) { ADD_IMP(fwd + i, i); ADD_IMP(fwd + 1 + i, i + 1); };
|
| 346 | 344 |
auto BLIP_REV = [&](int r) { ADD_IMP(rev - r, r + 1); ADD_IMP(rev + 1 - r, r); };
|
| ... | ... |
@@ -352,7 +350,7 @@ template<int quality, int range> inline void Blip_Synth<quality, range>::offset_ |
| 352 | 350 |
BLIP_FWD(4); |
| 353 | 351 |
ADD_IMP(fwd + mid - 1, mid - 1); |
| 354 | 352 |
ADD_IMP(fwd + mid, mid); |
| 355 |
- imp = this->impulses + phase; |
|
| 353 |
+ imp = &this->impulses[phase]; |
|
| 356 | 354 |
if (quality > 12) |
| 357 | 355 |
BLIP_REV(6); |
| 358 | 356 |
if (quality > 8) |
| ... | ... |
@@ -390,7 +388,7 @@ template<int quality, int range> inline void Blip_Synth<quality, range>::offset_ |
| 390 | 388 |
BLIP_FWD(4); |
| 391 | 389 |
int32_t t0 = i0 * delta + buf[fwd + mid - 1]; |
| 392 | 390 |
int32_t t1 = imp[blip_res * mid] * delta + buf[fwd + mid]; |
| 393 |
- imp = this->impulses + phase; |
|
| 391 |
+ imp = &this->impulses[phase]; |
|
| 394 | 392 |
i0 = imp[blip_res * mid]; |
| 395 | 393 |
buf[fwd + mid - 1] = t0; |
| 396 | 394 |
buf[fwd + mid] = t1; |
| ... | ... |
@@ -442,7 +440,8 @@ inline uint32_t Blip_Buffer::unsettled() const |
| 442 | 440 |
return this->reader_accum_ >> (blip_sample_bits - 16); |
| 443 | 441 |
} |
| 444 | 442 |
|
| 445 |
-const int blip_max_length = 0; |
|
| 446 |
-const int blip_default_length = 250; // 1/4 second |
|
| 447 |
- |
|
| 448 |
-#endif |
|
| 443 |
+enum |
|
| 444 |
+{
|
|
| 445 |
+ blip_max_length = 0, |
|
| 446 |
+ blip_default_length = 250 // 1/4 second |
|
| 447 |
+}; |
| ... | ... |
@@ -17,12 +17,10 @@ enum { blip_sample_max = 32767 };
|
| 17 | 17 |
class Blip_Buffer |
| 18 | 18 |
{
|
| 19 | 19 |
public: |
| 20 |
- typedef const char *blargg_err_t; |
|
| 21 |
- |
|
| 22 | 20 |
// Sets output sample rate and buffer length in milliseconds (1/1000 sec, defaults |
| 23 | 21 |
// to 1/4 second) and clears buffer. If there isn't enough memory, leaves buffer |
| 24 | 22 |
// untouched and returns "Out of memory", otherwise returns NULL. |
| 25 |
- blargg_err_t set_sample_rate(long samples_per_sec, int msec_length = 1000 / 4); |
|
| 23 |
+ void set_sample_rate(long samples_per_sec, int msec_length = 1000 / 4); |
|
| 26 | 24 |
|
| 27 | 25 |
// Sets number of source time units per second |
| 28 | 26 |
void clock_rate(long clocks_per_sec); |
| ... | ... |
@@ -96,8 +94,6 @@ public: |
| 96 | 94 |
|
| 97 | 95 |
// Deprecated |
| 98 | 96 |
typedef blip_resampled_time_t resampled_time_t; |
| 99 |
- blargg_err_t sample_rate(long r) { return this->set_sample_rate(r); }
|
|
| 100 |
- blargg_err_t sample_rate(long r, int msec) { return this->set_sample_rate(r, msec); }
|
|
| 101 | 97 |
private: |
| 102 | 98 |
// noncopyable |
| 103 | 99 |
Blip_Buffer(const Blip_Buffer &); |
| ... | ... |
@@ -116,7 +112,6 @@ private: |
| 116 | 112 |
int bass_freq_; |
| 117 | 113 |
int length_; |
| 118 | 114 |
Blip_Buffer *modified_; // non-zero = true (more optimal than using bool, heh) |
| 119 |
- friend class Blip_Reader; |
|
| 120 | 115 |
}; |
| 121 | 116 |
|
| 122 | 117 |
// Number of bits in resample ratio fraction. Higher values give a more accurate ratio |
| ... | ... |
@@ -282,8 +277,6 @@ const int blip_reader_default_bass = 9; |
| 282 | 277 |
// experimental |
| 283 | 278 |
#define BLIP_READER_ADJ_(name, offset) (name##_reader_buf += offset) |
| 284 | 279 |
|
| 285 |
-const int32_t blip_reader_idx_factor = sizeof(Blip_Buffer::buf_t_); |
|
| 286 |
- |
|
| 287 | 280 |
#define BLIP_READER_NEXT_IDX_(name, bass, idx) \ |
| 288 | 281 |
{ \
|
| 289 | 282 |
name##_reader_accum -= name##_reader_accum >> (bass); \ |
| ... | ... |
@@ -292,15 +285,10 @@ const int32_t blip_reader_idx_factor = sizeof(Blip_Buffer::buf_t_); |
| 292 | 285 |
|
| 293 | 286 |
#define BLIP_READER_NEXT_RAW_IDX_(name, bass, idx) \ |
| 294 | 287 |
{ \
|
| 295 |
- name##_reader_accum -= name##_reader_accum >> (bass);\ |
|
| 296 |
- name##_reader_accum += *reinterpret_cast<const Blip_Buffer::buf_t_ *>(reinterpret_cast<const char *>(name##_reader_buf) + (idx));\ |
|
| 288 |
+ name##_reader_accum -= name##_reader_accum >> (bass); \ |
|
| 289 |
+ name##_reader_accum += *reinterpret_cast<const Blip_Buffer::buf_t_ *>(reinterpret_cast<const char *>(name##_reader_buf) + (idx)); \ |
|
| 297 | 290 |
} |
| 298 | 291 |
|
| 299 |
-// Compatibility with older version |
|
| 300 |
-const long blip_unscaled = 65535; |
|
| 301 |
-const int blip_low_quality = blip_med_quality; |
|
| 302 |
-const int blip_best_quality = blip_high_quality; |
|
| 303 |
- |
|
| 304 | 292 |
#if defined(_M_IX86) || defined(_M_IA64) || defined(__i486__) || defined(__x86_64__) || defined(__ia64__) || defined(__i386__) |
| 305 | 293 |
template<typename T> inline bool BLIP_CLAMP_(const T &in) { return in < -0x8000 || 0x7FFF < in; }
|
| 306 | 294 |
#else |
| ... | ... |
@@ -338,7 +326,7 @@ template<int quality, int range> inline void Blip_Synth<quality, range>::offset_ |
| 338 | 326 |
// sub-sample resolution. |
| 339 | 327 |
int32_t right = (delta >> BLIP_PHASE_BITS) * phase; |
| 340 | 328 |
left -= right; |
| 341 |
- right += buf [1]; |
|
| 329 |
+ right += buf[1]; |
|
| 342 | 330 |
|
| 343 | 331 |
buf[0] = left; |
| 344 | 332 |
buf[1] = right; |
(As an aside, blargg's code style makes me go blarg myself.)
| ... | ... |
@@ -4,62 +4,54 @@ |
| 4 | 4 |
#ifndef BLIP_BUFFER_H |
| 5 | 5 |
#define BLIP_BUFFER_H |
| 6 | 6 |
|
| 7 |
- // internal |
|
| 8 |
- #include <limits.h> |
|
| 9 |
- #if INT_MAX < 0x7FFFFFFF || LONG_MAX == 0x7FFFFFFF |
|
| 10 |
- typedef long blip_long; |
|
| 11 |
- typedef unsigned long blip_ulong; |
|
| 12 |
- #else |
|
| 13 |
- typedef int blip_long; |
|
| 14 |
- typedef unsigned blip_ulong; |
|
| 15 |
- #endif |
|
| 7 |
+#include <vector> |
|
| 8 |
+#include <cstdint> |
|
| 16 | 9 |
|
| 17 | 10 |
// Time unit at source clock rate |
| 18 |
-typedef blip_long blip_time_t; |
|
| 11 |
+typedef int32_t blip_time_t; |
|
| 19 | 12 |
|
| 20 | 13 |
// Output samples are 16-bit signed, with a range of -32768 to 32767 |
| 21 | 14 |
typedef short blip_sample_t; |
| 22 | 15 |
enum { blip_sample_max = 32767 };
|
| 23 | 16 |
|
| 24 |
-struct blip_buffer_state_t; |
|
| 25 |
- |
|
| 26 |
-class Blip_Buffer {
|
|
| 17 |
+class Blip_Buffer |
|
| 18 |
+{
|
|
| 27 | 19 |
public: |
| 28 |
- typedef const char* blargg_err_t; |
|
| 20 |
+ typedef const char *blargg_err_t; |
|
| 29 | 21 |
|
| 30 | 22 |
// Sets output sample rate and buffer length in milliseconds (1/1000 sec, defaults |
| 31 | 23 |
// to 1/4 second) and clears buffer. If there isn't enough memory, leaves buffer |
| 32 | 24 |
// untouched and returns "Out of memory", otherwise returns NULL. |
| 33 |
- blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 ); |
|
| 25 |
+ blargg_err_t set_sample_rate(long samples_per_sec, int msec_length = 1000 / 4); |
|
| 34 | 26 |
|
| 35 | 27 |
// Sets number of source time units per second |
| 36 |
- void clock_rate( long clocks_per_sec ); |
|
| 28 |
+ void clock_rate(long clocks_per_sec); |
|
| 37 | 29 |
|
| 38 | 30 |
// Ends current time frame of specified duration and makes its samples available |
| 39 | 31 |
// (along with any still-unread samples) for reading with read_samples(). Begins |
| 40 | 32 |
// a new time frame at the end of the current frame. |
| 41 |
- void end_frame( blip_time_t time ); |
|
| 33 |
+ virtual void end_frame(blip_time_t time); |
|
| 42 | 34 |
|
| 43 | 35 |
// Reads at most 'max_samples' out of buffer into 'dest', removing them from |
| 44 | 36 |
// the buffer. Returns number of samples actually read and removed. If stereo is |
| 45 | 37 |
// true, increments 'dest' one extra time after writing each sample, to allow |
| 46 | 38 |
// easy interleving of two channels into a stereo output buffer. |
| 47 |
- long read_samples( blip_sample_t* dest, long max_samples, int stereo = 0 ); |
|
| 39 |
+ long read_samples(blip_sample_t *dest, long max_samples, bool stereo = false); |
|
| 48 | 40 |
|
| 49 |
-// Additional features |
|
| 41 |
+ // Additional features |
|
| 50 | 42 |
|
| 51 | 43 |
// Removes all available samples and clear buffer to silence. If 'entire_buffer' is |
| 52 | 44 |
// false, just clears out any samples waiting rather than the entire buffer. |
| 53 |
- void clear( int entire_buffer = 1 ); |
|
| 45 |
+ void clear(int entire_buffer = 1); |
|
| 54 | 46 |
|
| 55 | 47 |
// Number of samples available for reading with read_samples() |
| 56 | 48 |
long samples_avail() const; |
| 57 | 49 |
|
| 58 | 50 |
// Removes 'count' samples from those waiting to be read |
| 59 |
- void remove_samples( long count ); |
|
| 51 |
+ virtual void remove_samples(long count); |
|
| 60 | 52 |
|
| 61 | 53 |
// Sets frequency high-pass filter frequency, where higher values reduce bass more |
| 62 |
- void bass_freq( int frequency ); |
|
| 54 |
+ void bass_freq(int frequency); |
|
| 63 | 55 |
|
| 64 | 56 |
// Current output sample rate |
| 65 | 57 |
long sample_rate() const; |
| ... | ... |
@@ -70,16 +62,7 @@ public: |
| 70 | 62 |
// Number of source time units per second |
| 71 | 63 |
long clock_rate() const; |
| 72 | 64 |
|
| 73 |
-// Experimental features |
|
| 74 |
- |
|
| 75 |
- // Saves state, including high-pass filter and tails of last deltas. |
|
| 76 |
- // All samples must have been read from buffer before calling this. |
|
| 77 |
- void save_state( blip_buffer_state_t* out ); |
|
| 78 |
- |
|
| 79 |
- // Loads state. State must have been saved from Blip_Buffer with same |
|
| 80 |
- // settings during same run of program. States can NOT be stored on disk. |
|
| 81 |
- // Clears buffer before loading state. |
|
| 82 |
- void load_state( blip_buffer_state_t const& in ); |
|
| 65 |
+ // Experimental features |
|
| 83 | 66 |
|
| 84 | 67 |
// Number of samples delay from synthesis to samples read out |
| 85 | 68 |
int output_latency() const; |
| ... | ... |
@@ -87,113 +70,105 @@ public: |
| 87 | 70 |
// Counts number of clocks needed until 'count' samples will be available. |
| 88 | 71 |
// If buffer can't even hold 'count' samples, returns number of clocks until |
| 89 | 72 |
// buffer becomes full. |
| 90 |
- blip_time_t count_clocks( long count ) const; |
|
| 73 |
+ blip_time_t count_clocks(long count) const; |
|
| 91 | 74 |
|
| 92 | 75 |
// Number of raw samples that can be mixed within frame of specified duration. |
| 93 |
- long count_samples( blip_time_t duration ) const; |
|
| 76 |
+ long count_samples(blip_time_t duration) const; |
|
| 94 | 77 |
|
| 95 | 78 |
// Mixes in 'count' samples from 'buf_in' |
| 96 |
- void mix_samples( blip_sample_t const* buf_in, long count ); |
|
| 97 |
- |
|
| 79 |
+ void mix_samples(const blip_sample_t *buf_in, long count); |
|
| 98 | 80 |
|
| 99 | 81 |
// Signals that sound has been added to buffer. Could be done automatically in |
| 100 | 82 |
// Blip_Synth, but that would affect performance more, as you can arrange that |
| 101 | 83 |
// this is called only once per time frame rather than for every delta. |
| 102 |
- void set_modified() { modified_ = this; }
|
|
| 84 |
+ void set_modified() { this->modified_ = this; }
|
|
| 103 | 85 |
|
| 104 | 86 |
// not documented yet |
| 105 |
- blip_ulong unsettled() const; |
|
| 106 |
- Blip_Buffer* clear_modified() { Blip_Buffer* b = modified_; modified_ = 0; return b; }
|
|
| 107 |
- void remove_silence( long count ); |
|
| 108 |
- typedef blip_ulong blip_resampled_time_t; |
|
| 109 |
- blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; }
|
|
| 110 |
- blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; }
|
|
| 111 |
- blip_resampled_time_t clock_rate_factor( long clock_rate ) const; |
|
| 112 |
-public: |
|
| 87 |
+ uint32_t unsettled() const; |
|
| 88 |
+ Blip_Buffer *clear_modified() { auto b = this->modified_; this->modified_ = nullptr; return b; }
|
|
| 89 |
+ virtual void remove_silence(long count); |
|
| 90 |
+ typedef uint32_t blip_resampled_time_t; |
|
| 91 |
+ blip_resampled_time_t resampled_duration(int t) const { return t * this->factor_; }
|
|
| 92 |
+ blip_resampled_time_t resampled_time(blip_time_t t) const { return t * this->factor_ + this->offset_; }
|
|
| 93 |
+ blip_resampled_time_t clock_rate_factor(long clock_rate) const; |
|
| 113 | 94 |
Blip_Buffer(); |
| 114 |
- ~Blip_Buffer(); |
|
| 95 |
+ virtual ~Blip_Buffer(); |
|
| 115 | 96 |
|
| 116 | 97 |
// Deprecated |
| 117 | 98 |
typedef blip_resampled_time_t resampled_time_t; |
| 118 |
- blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); }
|
|
| 119 |
- blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); }
|
|
| 99 |
+ blargg_err_t sample_rate(long r) { return this->set_sample_rate(r); }
|
|
| 100 |
+ blargg_err_t sample_rate(long r, int msec) { return this->set_sample_rate(r, msec); }
|
|
| 120 | 101 |
private: |
| 121 | 102 |
// noncopyable |
| 122 |
- Blip_Buffer( const Blip_Buffer& ); |
|
| 123 |
- Blip_Buffer& operator = ( const Blip_Buffer& ); |
|
| 103 |
+ Blip_Buffer(const Blip_Buffer &); |
|
| 104 |
+ Blip_Buffer &operator=(const Blip_Buffer &); |
|
| 124 | 105 |
public: |
| 125 |
- typedef blip_long buf_t_; |
|
| 126 |
- blip_ulong factor_; |
|
| 106 |
+ typedef int32_t buf_t_; |
|
| 107 |
+ uint32_t factor_; |
|
| 127 | 108 |
blip_resampled_time_t offset_; |
| 128 |
- buf_t_* buffer_; |
|
| 129 |
- blip_long buffer_size_; |
|
| 130 |
- blip_long reader_accum_; |
|
| 109 |
+ std::vector<buf_t_> buffer_; |
|
| 110 |
+ int32_t buffer_size_; |
|
| 111 |
+ int32_t reader_accum_; |
|
| 131 | 112 |
int bass_shift_; |
| 132 | 113 |
private: |
| 133 | 114 |
long sample_rate_; |
| 134 | 115 |
long clock_rate_; |
| 135 | 116 |
int bass_freq_; |
| 136 | 117 |
int length_; |
| 137 |
- Blip_Buffer* modified_; // non-zero = true (more optimal than using bool, heh) |
|
| 118 |
+ Blip_Buffer *modified_; // non-zero = true (more optimal than using bool, heh) |
|
| 138 | 119 |
friend class Blip_Reader; |
| 139 | 120 |
}; |
| 140 | 121 |
|
| 141 |
-#ifdef HAVE_CONFIG_H |
|
| 142 |
- #include "config.h" |
|
| 143 |
-#endif |
|
| 144 |
- |
|
| 145 | 122 |
// Number of bits in resample ratio fraction. Higher values give a more accurate ratio |
| 146 | 123 |
// but reduce maximum buffer size. |
| 147 |
-#ifndef BLIP_BUFFER_ACCURACY |
|
| 148 |
- #define BLIP_BUFFER_ACCURACY 16 |
|
| 149 |
-#endif |
|
| 124 |
+const int BLIP_BUFFER_ACCURACY = 16; |
|
| 150 | 125 |
|
| 151 | 126 |
// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in |
| 152 | 127 |
// noticeable broadband noise when synthesizing high frequency square waves. |
| 153 | 128 |
// Affects size of Blip_Synth objects since they store the waveform directly. |
| 154 |
-#ifndef BLIP_PHASE_BITS |
|
| 155 |
- #if BLIP_BUFFER_FAST |
|
| 156 |
- #define BLIP_PHASE_BITS 8 |
|
| 157 |
- #else |
|
| 158 |
- #define BLIP_PHASE_BITS 6 |
|
| 159 |
- #endif |
|
| 129 |
+#if BLIP_BUFFER_FAST |
|
| 130 |
+const int BLIP_PHASE_BITS = 8; |
|
| 131 |
+#else |
|
| 132 |
+const int BLIP_PHASE_BITS = 6; |
|
| 160 | 133 |
#endif |
| 161 | 134 |
|
| 162 |
- // Internal |
|
| 163 |
- typedef blip_ulong blip_resampled_time_t; |
|
| 164 |
- int const blip_widest_impulse_ = 16; |
|
| 165 |
- int const blip_buffer_extra_ = blip_widest_impulse_ + 2; |
|
| 166 |
- int const blip_res = 1 << BLIP_PHASE_BITS; |
|
| 167 |
- class blip_eq_t; |
|
| 168 |
- |
|
| 169 |
- class Blip_Synth_Fast_ {
|
|
| 170 |
- public: |
|
| 171 |
- Blip_Buffer* buf; |
|
| 172 |
- int last_amp; |
|
| 173 |
- int delta_factor; |
|
| 174 |
- |
|
| 175 |
- void volume_unit( double ); |
|
| 176 |
- Blip_Synth_Fast_(); |
|
| 177 |
- void treble_eq( blip_eq_t const& ) { }
|
|
| 178 |
- }; |
|
| 135 |
+// Internal |
|
| 136 |
+typedef uint32_t blip_resampled_time_t; |
|
| 137 |
+const int blip_widest_impulse_ = 16; |
|
| 138 |
+const int blip_buffer_extra_ = blip_widest_impulse_ + 2; |
|
| 139 |
+const int blip_res = 1 << BLIP_PHASE_BITS; |
|
| 140 |
+class blip_eq_t; |
|
| 179 | 141 |
|
| 180 |
- class Blip_Synth_ {
|
|
| 181 |
- public: |
|
| 182 |
- Blip_Buffer* buf; |
|
| 183 |
- int last_amp; |
|
| 184 |
- int delta_factor; |
|
| 185 |
- |
|
| 186 |
- void volume_unit( double ); |
|
| 187 |
- Blip_Synth_( short* impulses, int width ); |
|
| 188 |
- void treble_eq( blip_eq_t const& ); |
|
| 189 |
- private: |
|
| 190 |
- double volume_unit_; |
|
| 191 |
- short* const impulses; |
|
| 192 |
- int const width; |
|
| 193 |
- blip_long kernel_unit; |
|
| 194 |
- int impulses_size() const { return blip_res / 2 * width + 1; }
|
|
| 195 |
- void adjust_impulse(); |
|
| 196 |
- }; |
|
| 142 |
+class Blip_Synth_Fast_ |
|
| 143 |
+{
|
|
| 144 |
+public: |
|
| 145 |
+ Blip_Buffer *buf; |
|
| 146 |
+ int last_amp; |
|
| 147 |
+ int delta_factor; |
|
| 148 |
+ |
|
| 149 |
+ void volume_unit(double); |
|
| 150 |
+ Blip_Synth_Fast_(); |
|
| 151 |
+ void treble_eq(const blip_eq_t &) { }
|
|
| 152 |
+}; |
|
| 153 |
+ |
|
| 154 |
+class Blip_Synth_ |
|
| 155 |
+{
|
|
| 156 |
+public: |
|
| 157 |
+ Blip_Buffer *buf; |
|
| 158 |
+ int last_amp; |
|
| 159 |
+ int delta_factor; |
|
| 160 |
+ |
|
| 161 |
+ void volume_unit(double); |
|
| 162 |
+ Blip_Synth_(short *impulses, int width); |
|
| 163 |
+ void treble_eq(const blip_eq_t &); |
|
| 164 |
+private: |
|
| 165 |
+ double volume_unit_; |
|
| 166 |
+ short *const impulses; |
|
| 167 |
+ const int width; |
|
| 168 |
+ int32_t kernel_unit; |
|
| 169 |
+ int impulses_size() const { return blip_res / 2 * this->width + 1; }
|
|
| 170 |
+ void adjust_impulse(); |
|
| 171 |
+}; |
|
| 197 | 172 |
|
| 198 | 173 |
// Quality level, better = slower. In general, use blip_good_quality. |
| 199 | 174 |
const int blip_med_quality = 8; |
| ... | ... |
@@ -203,40 +178,42 @@ const int blip_high_quality = 16; |
| 203 | 178 |
// Range specifies the greatest expected change in amplitude. Calculate it |
| 204 | 179 |
// by finding the difference between the maximum and minimum expected |
| 205 | 180 |
// amplitudes (max - min). |
| 206 |
-template<int quality,int range> |
|
| 207 |
-class Blip_Synth {
|
|
| 181 |
+template<int quality, int range> class Blip_Synth |
|
| 182 |
+{
|
|
| 208 | 183 |
public: |
| 209 | 184 |
// Sets overall volume of waveform |
| 210 |
- void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? -range : range)) ); }
|
|
| 185 |
+ void volume(double v) { this->impl.volume_unit(v * (1.0 / (range < 0 ? -range : range))); }
|
|
| 211 | 186 |
|
| 212 | 187 |
// Configures low-pass filter (see blip_buffer.txt) |
| 213 |
- void treble_eq( blip_eq_t const& eq ) { impl.treble_eq( eq ); }
|
|
| 188 |
+ void treble_eq(const blip_eq_t &eq) { this->impl.treble_eq(eq); }
|
|
| 214 | 189 |
|
| 215 | 190 |
// Gets/sets Blip_Buffer used for output |
| 216 |
- Blip_Buffer* output() const { return impl.buf; }
|
|
| 217 |
- void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; }
|
|
| 191 |
+ Blip_Buffer *output() const { return this->impl.buf; }
|
|
| 192 |
+ void output(Blip_Buffer *b) { this->impl.buf = b; this->impl.last_amp = 0; }
|
|
| 218 | 193 |
|
| 219 | 194 |
// Updates amplitude of waveform at given time. Using this requires a separate |
| 220 | 195 |
// Blip_Synth for each waveform. |
| 221 |
- void update( blip_time_t time, int amplitude ); |
|
| 196 |
+ void update(blip_time_t time, int amplitude); |
|
| 222 | 197 |
|
| 223 |
-// Low-level interface |
|
| 198 |
+ // Low-level interface |
|
| 224 | 199 |
|
| 225 | 200 |
// Adds an amplitude transition of specified delta, optionally into specified buffer |
| 226 | 201 |
// rather than the one set with output(). Delta can be positive or negative. |
| 227 | 202 |
// The actual change in amplitude is delta * (volume / range) |
| 228 |
- void offset( blip_time_t, int delta, Blip_Buffer* ) const; |
|
| 229 |
- void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); }
|
|
| 203 |
+ void offset(blip_time_t, int delta, Blip_Buffer *) const; |
|
| 204 |
+ void offset(blip_time_t t, int delta) const { this->offset(t, delta, this->impl.buf); }
|
|
| 230 | 205 |
|
| 231 | 206 |
// Works directly in terms of fractional output samples. Contact author for more info. |
| 232 |
- void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const; |
|
| 207 |
+ void offset_resampled(blip_resampled_time_t, int delta, Blip_Buffer *) const; |
|
| 233 | 208 |
|
| 234 | 209 |
// Same as offset(), except code is inlined for higher performance |
| 235 |
- void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const {
|
|
| 236 |
- offset_resampled( t * buf->factor_ + buf->offset_, delta, buf ); |
|
| 210 |
+ void offset_inline(blip_time_t t, int delta, Blip_Buffer *buf) const |
|
| 211 |
+ {
|
|
| 212 |
+ this->offset_resampled(t * buf->factor_ + buf->offset_, delta, buf); |
|
| 237 | 213 |
} |
| 238 |
- void offset_inline( blip_time_t t, int delta ) const {
|
|
| 239 |
- offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf ); |
|
| 214 |
+ void offset_inline(blip_time_t t, int delta) const |
|
| 215 |
+ {
|
|
| 216 |
+ this->offset_resampled(t * this->impl.buf->factor_ + this->impl.buf->offset_, delta, this->impl.buf); |
|
| 240 | 217 |
} |
| 241 | 218 |
|
| 242 | 219 |
private: |
| ... | ... |
@@ -245,312 +222,239 @@ private: |
| 245 | 222 |
#else |
| 246 | 223 |
Blip_Synth_ impl; |
| 247 | 224 |
typedef short imp_t; |
| 248 |
- imp_t impulses [blip_res * (quality / 2) + 1]; |
|
| 225 |
+ imp_t impulses[blip_res * (quality / 2) + 1]; |
|
| 249 | 226 |
public: |
| 250 |
- Blip_Synth() : impl( impulses, quality ) { }
|
|
| 227 |
+ Blip_Synth() : impl(impulses, quality) { }
|
|
| 251 | 228 |
#endif |
| 252 | 229 |
}; |
| 253 | 230 |
|
| 254 | 231 |
// Low-pass equalization parameters |
| 255 |
-class blip_eq_t {
|
|
| 232 |
+class blip_eq_t |
|
| 233 |
+{
|
|
| 256 | 234 |
public: |
| 257 | 235 |
// Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce |
| 258 | 236 |
// treble, small positive values (0 to 5.0) increase treble. |
| 259 |
- blip_eq_t( double treble_db = 0 ); |
|
| 237 |
+ blip_eq_t(double treble_db = 0); |
|
| 260 | 238 |
|
| 261 | 239 |
// See blip_buffer.txt |
| 262 |
- blip_eq_t( double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0 ); |
|
| 240 |
+ blip_eq_t(double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0); |
|
| 263 | 241 |
|
| 264 | 242 |
private: |
| 265 | 243 |
double treble; |
| 266 | 244 |
long rolloff_freq; |
| 267 | 245 |
long sample_rate; |
| 268 | 246 |
long cutoff_freq; |
| 269 |
- void generate( float* out, int count ) const; |
|
| 247 |
+ void generate(float *out, int count) const; |
|
| 270 | 248 |
friend class Blip_Synth_; |
| 271 | 249 |
}; |
| 272 | 250 |
|
| 273 |
-int const blip_sample_bits = 30; |
|
| 274 |
- |
|
| 275 |
-// Dummy Blip_Buffer to direct sound output to, for easy muting without |
|
| 276 |
-// having to stop sound code. |
|
| 277 |
-class Silent_Blip_Buffer : public Blip_Buffer {
|
|
| 278 |
- buf_t_ buf [blip_buffer_extra_ + 1]; |
|
| 279 |
-public: |
|
| 280 |
- // The following cannot be used (an assertion will fail if attempted): |
|
| 281 |
- blargg_err_t set_sample_rate( long samples_per_sec, int msec_length ); |
|
| 282 |
- blip_time_t count_clocks( long count ) const; |
|
| 283 |
- void mix_samples( blip_sample_t const* buf, long count ); |
|
| 284 |
- |
|
| 285 |
- Silent_Blip_Buffer(); |
|
| 286 |
-}; |
|
| 287 |
- |
|
| 288 |
- #if __GNUC__ >= 3 || _MSC_VER >= 1100 |
|
| 289 |
- #define BLIP_RESTRICT __restrict |
|
| 290 |
- #else |
|
| 291 |
- #define BLIP_RESTRICT |
|
| 292 |
- #endif |
|
| 251 |
+const int blip_sample_bits = 30; |
|
| 293 | 252 |
|
| 294 | 253 |
// Optimized reading from Blip_Buffer, for use in custom sample output |
| 295 | 254 |
|
| 296 | 255 |
// Begins reading from buffer. Name should be unique to the current block. |
| 297 |
-#define BLIP_READER_BEGIN( name, blip_buffer ) \ |
|
| 298 |
- const Blip_Buffer::buf_t_* BLIP_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\ |
|
| 299 |
- blip_long name##_reader_accum = (blip_buffer).reader_accum_ |
|
| 256 |
+#define BLIP_READER_BEGIN(name, blip_buffer) \ |
|
| 257 |
+ auto name##_reader_buf = &(blip_buffer).buffer_[0]; \ |
|
| 258 |
+ int32_t name##_reader_accum = (blip_buffer).reader_accum_ |
|
| 300 | 259 |
|
| 301 | 260 |
// Gets value to pass to BLIP_READER_NEXT() |
| 302 |
-#define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_) |
|
| 261 |
+inline int BLIP_READER_BASS(const Blip_Buffer &blip_buffer) { return blip_buffer.bass_shift_; }
|
|
| 303 | 262 |
|
| 304 | 263 |
// Constant value to use instead of BLIP_READER_BASS(), for slightly more optimal |
| 305 | 264 |
// code at the cost of having no bass control |
| 306 |
-int const blip_reader_default_bass = 9; |
|
| 265 |
+const int blip_reader_default_bass = 9; |
|
| 307 | 266 |
|
| 308 | 267 |
// Current sample |
| 309 |
-#define BLIP_READER_READ( name ) (name##_reader_accum >> (blip_sample_bits - 16)) |
|
| 268 |
+#define BLIP_READER_READ(name) (name##_reader_accum >> (blip_sample_bits - 16)) |
|
| 310 | 269 |
|
| 311 | 270 |
// Current raw sample in full internal resolution |
| 312 |
-#define BLIP_READER_READ_RAW( name ) (name##_reader_accum) |
|
| 271 |
+#define BLIP_READER_READ_RAW(name) (name##_reader_accum) |
|
| 313 | 272 |
|
| 314 | 273 |
// Advances to next sample |
| 315 |
-#define BLIP_READER_NEXT( name, bass ) \ |
|
| 316 |
- (void) (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass))) |
|
| 274 |
+#define BLIP_READER_NEXT(name, bass) \ |
|
| 275 |
+ (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass))) |
|
| 317 | 276 |
|
| 318 | 277 |
// Ends reading samples from buffer. The number of samples read must now be removed |
| 319 | 278 |
// using Blip_Buffer::remove_samples(). |
| 320 |
-#define BLIP_READER_END( name, blip_buffer ) \ |
|
| 321 |
- (void) ((blip_buffer).reader_accum_ = name##_reader_accum) |
|
| 322 |
- |
|
| 279 |
+#define BLIP_READER_END(name, blip_buffer) \ |
|
| 280 |
+ ((blip_buffer).reader_accum_ = name##_reader_accum) |
|
| 323 | 281 |
|
| 324 | 282 |
// experimental |
| 325 |
-#define BLIP_READER_ADJ_( name, offset ) (name##_reader_buf += offset) |
|
| 283 |
+#define BLIP_READER_ADJ_(name, offset) (name##_reader_buf += offset) |
|
| 326 | 284 |
|
| 327 |
-blip_long const blip_reader_idx_factor = sizeof (Blip_Buffer::buf_t_); |
|
| 285 |
+const int32_t blip_reader_idx_factor = sizeof(Blip_Buffer::buf_t_); |
|
| 328 | 286 |
|
| 329 |
-#define BLIP_READER_NEXT_IDX_( name, bass, idx ) {\
|
|
| 330 |
- name##_reader_accum -= name##_reader_accum >> (bass);\ |
|
| 331 |
- name##_reader_accum += name##_reader_buf [(idx)];\ |
|
| 287 |
+#define BLIP_READER_NEXT_IDX_(name, bass, idx) \ |
|
| 288 |
+{ \
|
|
| 289 |
+ name##_reader_accum -= name##_reader_accum >> (bass); \ |
|
| 290 |
+ name##_reader_accum += name##_reader_buf[(idx)]; \ |
|
| 332 | 291 |
} |
| 333 | 292 |
|
| 334 |
-#define BLIP_READER_NEXT_RAW_IDX_( name, bass, idx ) {\
|
|
| 293 |
+#define BLIP_READER_NEXT_RAW_IDX_(name, bass, idx) \ |
|
| 294 |
+{ \
|
|
| 335 | 295 |
name##_reader_accum -= name##_reader_accum >> (bass);\ |
| 336 |
- name##_reader_accum +=\ |
|
| 337 |
- *(Blip_Buffer::buf_t_ const*) ((char const*) name##_reader_buf + (idx));\ |
|
| 296 |
+ name##_reader_accum += *reinterpret_cast<const Blip_Buffer::buf_t_ *>(reinterpret_cast<const char *>(name##_reader_buf) + (idx));\ |
|
| 338 | 297 |
} |
| 339 | 298 |
|
| 340 | 299 |
// Compatibility with older version |
| 341 | 300 |
const long blip_unscaled = 65535; |
| 342 |
-const int blip_low_quality = blip_med_quality; |
|
| 301 |
+const int blip_low_quality = blip_med_quality; |
|
| 343 | 302 |
const int blip_best_quality = blip_high_quality; |
| 344 | 303 |
|
| 345 |
-// Deprecated; use BLIP_READER macros as follows: |
|
| 346 |
-// Blip_Reader r; r.begin( buf ); -> BLIP_READER_BEGIN( r, buf ); |
|
| 347 |
-// int bass = r.begin( buf ) -> BLIP_READER_BEGIN( r, buf ); int bass = BLIP_READER_BASS( buf ); |
|
| 348 |
-// r.read() -> BLIP_READER_READ( r ) |
|
| 349 |
-// r.read_raw() -> BLIP_READER_READ_RAW( r ) |
|
| 350 |
-// r.next( bass ) -> BLIP_READER_NEXT( r, bass ) |
|
| 351 |
-// r.next() -> BLIP_READER_NEXT( r, blip_reader_default_bass ) |
|
| 352 |
-// r.end( buf ) -> BLIP_READER_END( r, buf ) |
|
| 353 |
-class Blip_Reader {
|
|
| 354 |
-public: |
|
| 355 |
- int begin( Blip_Buffer& ); |
|
| 356 |
- blip_long read() const { return accum >> (blip_sample_bits - 16); }
|
|
| 357 |
- blip_long read_raw() const { return accum; }
|
|
| 358 |
- void next( int bass_shift = 9 ) { accum += *buf++ - (accum >> bass_shift); }
|
|
| 359 |
- void end( Blip_Buffer& b ) { b.reader_accum_ = accum; }
|
|
| 360 |
-private: |
|
| 361 |
- const Blip_Buffer::buf_t_* buf; |
|
| 362 |
- blip_long accum; |
|
| 363 |
-}; |
|
| 364 |
- |
|
| 365 |
-#if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \ |
|
| 366 |
- defined (__x86_64__) || defined (__ia64__) || defined (__i386__) |
|
| 367 |
- #define BLIP_CLAMP_( in ) in < -0x8000 || 0x7FFF < in |
|
| 304 |
+#if defined(_M_IX86) || defined(_M_IA64) || defined(__i486__) || defined(__x86_64__) || defined(__ia64__) || defined(__i386__) |
|
| 305 |
+template<typename T> inline bool BLIP_CLAMP_(const T &in) { return in < -0x8000 || 0x7FFF < in; }
|
|
| 368 | 306 |
#else |
| 369 |
- #define BLIP_CLAMP_( in ) (blip_sample_t) in != in |
|
| 307 |
+template<typename T> inline bool BLIP_CLAMP_(const T &in) { return static_cast<blip_sample_t>(in) != in; }
|
|
| 370 | 308 |
#endif |
| 371 | 309 |
|
| 372 | 310 |
// Clamp sample to blip_sample_t range |
| 373 |
-#define BLIP_CLAMP( sample, out )\ |
|
| 374 |
- { if ( BLIP_CLAMP_( (sample) ) ) (out) = ((sample) >> 24) ^ 0x7FFF; }
|
|
| 375 |
- |
|
| 376 |
-struct blip_buffer_state_t |
|
| 311 |
+template<typename T1, typename T2> inline void BLIP_CLAMP(const T1 &sample, T2 &out) |
|
| 377 | 312 |
{
|
| 378 |
- blip_resampled_time_t offset_; |
|
| 379 |
- blip_long reader_accum_; |
|
| 380 |
- blip_long buf [blip_buffer_extra_]; |
|
| 381 |
-}; |
|
| 313 |
+ if (BLIP_CLAMP_(sample)) |
|
| 314 |
+ out = (sample >> 24) ^ 0x7FFF; |
|
| 315 |
+} |
|
| 382 | 316 |
|
| 383 | 317 |
// End of public interface |
| 384 | 318 |
|
| 385 | 319 |
#ifndef assert |
| 386 |
- #include <assert.h> |
|
| 320 |
+# include <cassert> |
|
| 387 | 321 |
#endif |
| 388 | 322 |
|
| 389 |
-template<int quality,int range> |
|
| 390 |
-inline void Blip_Synth<quality,range>::offset_resampled( blip_resampled_time_t time, |
|
| 391 |
- int delta, Blip_Buffer* blip_buf ) const |
|
| 323 |
+template<int quality, int range> inline void Blip_Synth<quality, range>::offset_resampled(blip_resampled_time_t time, int delta, Blip_Buffer *blip_buf) const |
|
| 392 | 324 |
{
|
| 393 | 325 |
// If this assertion fails, it means that an attempt was made to add a delta |
| 394 | 326 |
// at a negative time or past the end of the buffer. |
| 395 |
- assert( (blip_long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ ); |
|
| 327 |
+ assert(static_cast<int32_t>(time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_); |
|
| 396 | 328 |
|
| 397 |
- delta *= impl.delta_factor; |
|
| 398 |
- blip_long* BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY); |
|
| 399 |
- int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1)); |
|
| 329 |
+ delta *= this->impl.delta_factor; |
|
| 330 |
+ auto buf = &blip_buf->buffer_[time >> BLIP_BUFFER_ACCURACY]; |
|
| 331 |
+ int phase = static_cast<int>((time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS)) & (blip_res - 1)); |
|
| 400 | 332 |
|
| 401 | 333 |
#if BLIP_BUFFER_FAST |
| 402 |
- blip_long left = buf [0] + delta; |
|
| 334 |
+ int32_t left = buf[0] + delta; |
|
| 403 | 335 |
|
| 404 | 336 |
// Kind of crappy, but doing shift after multiply results in overflow. |
| 405 | 337 |
// Alternate way of delaying multiply by delta_factor results in worse |
| 406 | 338 |
// sub-sample resolution. |
| 407 |
- blip_long right = (delta >> BLIP_PHASE_BITS) * phase; |
|
| 408 |
- left -= right; |
|
| 339 |
+ int32_t right = (delta >> BLIP_PHASE_BITS) * phase; |
|
| 340 |
+ left -= right; |
|
| 409 | 341 |
right += buf [1]; |
| 410 | 342 |
|
| 411 |
- buf [0] = left; |
|
| 412 |
- buf [1] = right; |
|
| 343 |
+ buf[0] = left; |
|
| 344 |
+ buf[1] = right; |
|
| 413 | 345 |
#else |
| 346 |
+ int fwd = (blip_widest_impulse_ - quality) / 2; |
|
| 347 |
+ int rev = fwd + quality - 2; |
|
| 348 |
+ int mid = quality / 2 - 1; |
|
| 414 | 349 |
|
| 415 |
- int const fwd = (blip_widest_impulse_ - quality) / 2; |
|
| 416 |
- int const rev = fwd + quality - 2; |
|
| 417 |
- int const mid = quality / 2 - 1; |
|
| 418 |
- |
|
| 419 |
- imp_t const* BLIP_RESTRICT imp = impulses + blip_res - phase; |
|
| 420 |
- |
|
| 421 |
- #if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \ |
|
| 422 |
- defined (__x86_64__) || defined (__ia64__) || defined (__i386__) |
|
| 350 |
+ auto imp = this->impulses + blip_res - phase; |
|
| 423 | 351 |
|
| 352 |
+# if defined(_M_IX86) || defined(_M_IA64) || defined(__i486__) || defined(__x86_64__) || defined(__ia64__) || defined(__i386__) |
|
| 424 | 353 |
// this straight forward version gave in better code on GCC for x86 |
| 425 | 354 |
|
| 426 |
- #define ADD_IMP( out, in ) \ |
|
| 427 |
- buf [out] += (blip_long) imp [blip_res * (in)] * delta |
|
| 428 |
- |
|
| 429 |
- #define BLIP_FWD( i ) {\
|
|
| 430 |
- ADD_IMP( fwd + i, i );\ |
|
| 431 |
- ADD_IMP( fwd + 1 + i, i + 1 );\ |
|
| 432 |
- } |
|
| 433 |
- #define BLIP_REV( r ) {\
|
|
| 434 |
- ADD_IMP( rev - r, r + 1 );\ |
|
| 435 |
- ADD_IMP( rev + 1 - r, r );\ |
|
| 436 |
- } |
|
| 437 |
- |
|
| 438 |
- BLIP_FWD( 0 ) |
|
| 439 |
- if ( quality > 8 ) BLIP_FWD( 2 ) |
|
| 440 |
- if ( quality > 12 ) BLIP_FWD( 4 ) |
|
| 441 |
- {
|
|
| 442 |
- ADD_IMP( fwd + mid - 1, mid - 1 ); |
|
| 443 |
- ADD_IMP( fwd + mid , mid ); |
|
| 444 |
- imp = impulses + phase; |
|
| 445 |
- } |
|
| 446 |
- if ( quality > 12 ) BLIP_REV( 6 ) |
|
| 447 |
- if ( quality > 8 ) BLIP_REV( 4 ) |
|
| 448 |
- BLIP_REV( 2 ) |
|
| 449 |
- |
|
| 450 |
- ADD_IMP( rev , 1 ); |
|
| 451 |
- ADD_IMP( rev + 1, 0 ); |
|
| 452 |
- |
|
| 453 |
- #undef ADD_IMP |
|
| 454 |
- |
|
| 455 |
- #else |
|
| 456 |
- |
|
| 355 |
+ auto ADD_IMP = [&](int out, int in) { buf[out] += static_cast<int32_t>(imp[blip_res * in] * delta); };
|
|
| 356 |
+ |
|
| 357 |
+ auto BLIP_FWD = [&](int i) { ADD_IMP(fwd + i, i); ADD_IMP(fwd + 1 + i, i + 1); };
|
|
| 358 |
+ auto BLIP_REV = [&](int r) { ADD_IMP(rev - r, r + 1); ADD_IMP(rev + 1 - r, r); };
|
|
| 359 |
+ |
|
| 360 |
+ BLIP_FWD(0); |
|
| 361 |
+ if (quality > 8) |
|
| 362 |
+ BLIP_FWD(2); |
|
| 363 |
+ if (quality > 12) |
|
| 364 |
+ BLIP_FWD(4); |
|
| 365 |
+ ADD_IMP(fwd + mid - 1, mid - 1); |
|
| 366 |
+ ADD_IMP(fwd + mid, mid); |
|
| 367 |
+ imp = this->impulses + phase; |
|
| 368 |
+ if (quality > 12) |
|
| 369 |
+ BLIP_REV(6); |
|
| 370 |
+ if (quality > 8) |
|
| 371 |
+ BLIP_REV(4); |
|
| 372 |
+ BLIP_REV(2); |
|
| 373 |
+ |
|
| 374 |
+ ADD_IMP(rev, 1); |
|
| 375 |
+ ADD_IMP(rev + 1, 0); |
|
| 376 |
+# else |
|
| 457 | 377 |
// for RISC processors, help compiler by reading ahead of writes |
| 458 | 378 |
|
| 459 |
- #define BLIP_FWD( i ) {\
|
|
| 460 |
- blip_long t0 = i0 * delta + buf [fwd + i];\ |
|
| 461 |
- blip_long t1 = imp [blip_res * (i + 1)] * delta + buf [fwd + 1 + i];\ |
|
| 462 |
- i0 = imp [blip_res * (i + 2)];\ |
|
| 463 |
- buf [fwd + i] = t0;\ |
|
| 464 |
- buf [fwd + 1 + i] = t1;\ |
|
| 465 |
- } |
|
| 466 |
- #define BLIP_REV( r ) {\
|
|
| 467 |
- blip_long t0 = i0 * delta + buf [rev - r];\ |
|
| 468 |
- blip_long t1 = imp [blip_res * r] * delta + buf [rev + 1 - r];\ |
|
| 469 |
- i0 = imp [blip_res * (r - 1)];\ |
|
| 470 |
- buf [rev - r] = t0;\ |
|
| 471 |
- buf [rev + 1 - r] = t1;\ |
|
| 472 |
- } |
|
| 379 |
+ int32_t i0 = *imp; |
|
| 473 | 380 |
|
| 474 |
- blip_long i0 = *imp; |
|
| 475 |
- BLIP_FWD( 0 ) |
|
| 476 |
- if ( quality > 8 ) BLIP_FWD( 2 ) |
|
| 477 |
- if ( quality > 12 ) BLIP_FWD( 4 ) |
|
| 478 |
- {
|
|
| 479 |
- blip_long t0 = i0 * delta + buf [fwd + mid - 1]; |
|
| 480 |
- blip_long t1 = imp [blip_res * mid] * delta + buf [fwd + mid ]; |
|
| 481 |
- imp = impulses + phase; |
|
| 482 |
- i0 = imp [blip_res * mid]; |
|
| 483 |
- buf [fwd + mid - 1] = t0; |
|
| 484 |
- buf [fwd + mid ] = t1; |
|
| 485 |
- } |
|
| 486 |
- if ( quality > 12 ) BLIP_REV( 6 ) |
|
| 487 |
- if ( quality > 8 ) BLIP_REV( 4 ) |
|
| 488 |
- BLIP_REV( 2 ) |
|
| 489 |
- |
|
| 490 |
- blip_long t0 = i0 * delta + buf [rev ]; |
|
| 491 |
- blip_long t1 = *imp * delta + buf [rev + 1]; |
|
| 492 |
- buf [rev ] = t0; |
|
| 493 |
- buf [rev + 1] = t1; |
|
| 494 |
- #endif |
|
| 381 |
+ auto BLIP_FWD = [&](int i) |
|
| 382 |
+ {
|
|
| 383 |
+ int32_t t0 = i0 * delta + buf[fwd + i]; |
|
| 384 |
+ int32_t t1 = imp[blip_res * (i + 1)] * delta + buf[fwd + 1 + i]; |
|
| 385 |
+ i0 = imp[blip_res * (i + 2)]; |
|
| 386 |
+ buf[fwd + i] = t0; |
|
| 387 |
+ buf[fwd + 1 + i] = t1; |
|
| 388 |
+ }; |
|
| 389 |
+ auto BLIP_REV = [&](int r) |
|
| 390 |
+ {
|
|
| 391 |
+ int32_t t0 = i0 * delta + buf[rev - r]; |
|
| 392 |
+ int32_t t1 = imp[blip_res * r] * delta + buf[rev + 1 - r]; |
|
| 393 |
+ i0 = imp[blip_res * (r - 1)]; |
|
| 394 |
+ buf[rev - r] = t0; |
|
| 395 |
+ buf[rev + 1 - r] = t1; |
|
| 396 |
+ }; |
|
| 495 | 397 |
|
| 398 |
+ BLIP_FWD(0); |
|
| 399 |
+ if (quality > 8) |
|
| 400 |
+ BLIP_FWD(2); |
|
| 401 |
+ if (quality > 12) |
|
| 402 |
+ BLIP_FWD(4); |
|
| 403 |
+ int32_t t0 = i0 * delta + buf[fwd + mid - 1]; |
|
| 404 |
+ int32_t t1 = imp[blip_res * mid] * delta + buf[fwd + mid]; |
|
| 405 |
+ imp = this->impulses + phase; |
|
| 406 |
+ i0 = imp[blip_res * mid]; |
|
| 407 |
+ buf[fwd + mid - 1] = t0; |
|
| 408 |
+ buf[fwd + mid] = t1; |
|
| 409 |
+ if (quality > 12) |
|
| 410 |
+ BLIP_REV(6); |
|
| 411 |
+ if (quality > 8) |
|
| 412 |
+ BLIP_REV(4); |
|
| 413 |
+ BLIP_REV(2); |
|
| 414 |
+ |
|
| 415 |
+ t0 = i0 * delta + buf[rev]; |
|
| 416 |
+ t1 = *imp * delta + buf[rev + 1]; |
|
| 417 |
+ buf[rev] = t0; |
|
| 418 |
+ buf[rev + 1] = t1; |
|
| 419 |
+# endif |
|
| 496 | 420 |
#endif |
| 497 | 421 |
} |
| 498 | 422 |
|
| 499 |
-#undef BLIP_FWD |
|
| 500 |
-#undef BLIP_REV |
|
| 501 |
- |
|
| 502 |
-template<int quality,int range> |
|
| 503 |
-#if BLIP_BUFFER_FAST |
|
| 504 |
- inline |
|
| 505 |
-#endif |
|
| 506 |
-void Blip_Synth<quality,range>::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const |
|
| 423 |
+template<int quality, int range> inline void Blip_Synth<quality, range>::offset(blip_time_t t, int delta, Blip_Buffer *buf) const |
|
| 507 | 424 |
{
|
| 508 |
- offset_resampled( t * buf->factor_ + buf->offset_, delta, buf ); |
|
| 425 |
+ this->offset_resampled(t * buf->factor_ + buf->offset_, delta, buf); |
|
| 509 | 426 |
} |
| 510 | 427 |
|
| 511 |
-template<int quality,int range> |
|
| 512 |
-#if BLIP_BUFFER_FAST |
|
| 513 |
- inline |
|
| 514 |
-#endif |
|
| 515 |
-void Blip_Synth<quality,range>::update( blip_time_t t, int amp ) |
|
| 428 |
+template<int quality, int range> inline void Blip_Synth<quality, range>::update(blip_time_t t, int amp) |
|
| 516 | 429 |
{
|
| 517 |
- int delta = amp - impl.last_amp; |
|
| 518 |
- impl.last_amp = amp; |
|
| 519 |
- offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf ); |
|
| 430 |
+ int delta = amp - this->impl.last_amp; |
|
| 431 |
+ this->impl.last_amp = amp; |
|
| 432 |
+ this->offset_resampled(t * this->impl.buf->factor_ + this->impl.buf->offset_, delta, this->impl.buf); |
|
| 520 | 433 |
} |
| 521 | 434 |
|
| 522 |
-inline blip_eq_t::blip_eq_t( double t ) : |
|
| 523 |
- treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { }
|
|
| 524 |
-inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) : |
|
| 525 |
- treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { }
|
|
| 435 |
+inline blip_eq_t::blip_eq_t(double t) : treble(t), rolloff_freq(0), sample_rate(44100), cutoff_freq(0) { }
|
|
| 436 |
+inline blip_eq_t::blip_eq_t(double t, long rf, long sr, long cf) : treble(t), rolloff_freq(rf), sample_rate(sr), cutoff_freq(cf) { }
|
|
| 526 | 437 |
|
| 527 |
-inline int Blip_Buffer::length() const { return length_; }
|
|
| 528 |
-inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); }
|
|
| 529 |
-inline long Blip_Buffer::sample_rate() const { return sample_rate_; }
|
|
| 530 |
-inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; }
|
|
| 531 |
-inline long Blip_Buffer::clock_rate() const { return clock_rate_; }
|
|
| 532 |
-inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); }
|
|
| 533 |
- |
|
| 534 |
-inline int Blip_Reader::begin( Blip_Buffer& blip_buf ) |
|
| 535 |
-{
|
|
| 536 |
- buf = blip_buf.buffer_; |
|
| 537 |
- accum = blip_buf.reader_accum_; |
|
| 538 |
- return blip_buf.bass_shift_; |
|
| 539 |
-} |
|
| 438 |
+inline int Blip_Buffer::length() const { return this->length_; }
|
|
| 439 |
+inline long Blip_Buffer::samples_avail() const { return static_cast<long>(this->offset_ >> BLIP_BUFFER_ACCURACY); }
|
|
| 440 |
+inline long Blip_Buffer::sample_rate() const { return this->sample_rate_; }
|
|
| 441 |
+inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; }
|
|
| 442 |
+inline long Blip_Buffer::clock_rate() const { return this->clock_rate_; }
|
|
| 443 |
+inline void Blip_Buffer::clock_rate(long cps) { this->factor_ = this->clock_rate_factor(this->clock_rate_ = cps); }
|
|
| 540 | 444 |
|
| 541 |
-inline void Blip_Buffer::remove_silence( long count ) |
|
| 445 |
+inline void Blip_Buffer::remove_silence(long count) |
|
| 542 | 446 |
{
|
| 543 | 447 |
// fails if you try to remove more samples than available |
| 544 |
- assert( count <= samples_avail() ); |
|
| 545 |
- offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY; |
|
| 448 |
+ assert(count <= this->samples_avail()); |
|
| 449 |
+ this->offset_ -= static_cast<blip_resampled_time_t>(count) << BLIP_BUFFER_ACCURACY; |
|
| 546 | 450 |
} |
| 547 | 451 |
|
| 548 |
-inline blip_ulong Blip_Buffer::unsettled() const |
|
| 452 |
+inline uint32_t Blip_Buffer::unsettled() const |
|
| 549 | 453 |
{
|
| 550 |
- return reader_accum_ >> (blip_sample_bits - 16); |
|
| 454 |
+ return this->reader_accum_ >> (blip_sample_bits - 16); |
|
| 551 | 455 |
} |
| 552 | 456 |
|
| 553 |
-int const blip_max_length = 0; |
|
| 554 |
-int const blip_default_length = 250; // 1/4 second |
|
| 457 |
+const int blip_max_length = 0; |
|
| 458 |
+const int blip_default_length = 250; // 1/4 second |
|
| 555 | 459 |
|
| 556 | 460 |
#endif |
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,556 @@ |
| 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 |
+ // internal |
|
| 8 |
+ #include <limits.h> |
|
| 9 |
+ #if INT_MAX < 0x7FFFFFFF || LONG_MAX == 0x7FFFFFFF |
|
| 10 |
+ typedef long blip_long; |
|
| 11 |
+ typedef unsigned long blip_ulong; |
|
| 12 |
+ #else |
|
| 13 |
+ typedef int blip_long; |
|
| 14 |
+ typedef unsigned blip_ulong; |
|
| 15 |
+ #endif |
|
| 16 |
+ |
|
| 17 |
+// Time unit at source clock rate |
|
| 18 |
+typedef blip_long blip_time_t; |
|
| 19 |
+ |
|
| 20 |
+// Output samples are 16-bit signed, with a range of -32768 to 32767 |
|
| 21 |
+typedef short blip_sample_t; |
|
| 22 |
+enum { blip_sample_max = 32767 };
|
|
| 23 |
+ |
|
| 24 |
+struct blip_buffer_state_t; |
|
| 25 |
+ |
|
| 26 |
+class Blip_Buffer {
|
|
| 27 |
+public: |
|
| 28 |
+ typedef const char* blargg_err_t; |
|
| 29 |
+ |
|
| 30 |
+ // Sets output sample rate and buffer length in milliseconds (1/1000 sec, defaults |
|
| 31 |
+ // to 1/4 second) and clears buffer. If there isn't enough memory, leaves buffer |
|
| 32 |
+ // untouched and returns "Out of memory", otherwise returns NULL. |
|
| 33 |
+ blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 ); |
|
| 34 |
+ |
|
| 35 |
+ // Sets number of source time units per second |
|
| 36 |
+ void clock_rate( long clocks_per_sec ); |
|
| 37 |
+ |
|
| 38 |
+ // Ends current time frame of specified duration and makes its samples available |
|
| 39 |
+ // (along with any still-unread samples) for reading with read_samples(). Begins |
|
| 40 |
+ // a new time frame at the end of the current frame. |
|
| 41 |
+ void end_frame( blip_time_t time ); |
|
| 42 |
+ |
|
| 43 |
+ // Reads at most 'max_samples' out of buffer into 'dest', removing them from |
|
| 44 |
+ // the buffer. Returns number of samples actually read and removed. If stereo is |
|
| 45 |
+ // true, increments 'dest' one extra time after writing each sample, to allow |
|
| 46 |
+ // easy interleving of two channels into a stereo output buffer. |
|
| 47 |
+ long read_samples( blip_sample_t* dest, long max_samples, int stereo = 0 ); |
|
| 48 |
+ |
|
| 49 |
+// Additional features |
|
| 50 |
+ |
|
| 51 |
+ // Removes all available samples and clear buffer to silence. If 'entire_buffer' is |
|
| 52 |
+ // false, just clears out any samples waiting rather than the entire buffer. |
|
| 53 |
+ void clear( int entire_buffer = 1 ); |
|
| 54 |
+ |
|
| 55 |
+ // Number of samples available for reading with read_samples() |
|
| 56 |
+ long samples_avail() const; |
|
| 57 |
+ |
|
| 58 |
+ // Removes 'count' samples from those waiting to be read |
|
| 59 |
+ void remove_samples( long count ); |
|
| 60 |
+ |
|
| 61 |
+ // Sets frequency high-pass filter frequency, where higher values reduce bass more |
|
| 62 |
+ void bass_freq( int frequency ); |
|
| 63 |
+ |
|
| 64 |
+ // Current output sample rate |
|
| 65 |
+ long sample_rate() const; |
|
| 66 |
+ |
|
| 67 |
+ // Length of buffer in milliseconds |
|
| 68 |
+ int length() const; |
|
| 69 |
+ |
|
| 70 |
+ // Number of source time units per second |
|
| 71 |
+ long clock_rate() const; |
|
| 72 |
+ |
|
| 73 |
+// Experimental features |
|
| 74 |
+ |
|
| 75 |
+ // Saves state, including high-pass filter and tails of last deltas. |
|
| 76 |
+ // All samples must have been read from buffer before calling this. |
|
| 77 |
+ void save_state( blip_buffer_state_t* out ); |
|
| 78 |
+ |
|
| 79 |
+ // Loads state. State must have been saved from Blip_Buffer with same |
|
| 80 |
+ // settings during same run of program. States can NOT be stored on disk. |
|
| 81 |
+ // Clears buffer before loading state. |
|
| 82 |
+ void load_state( blip_buffer_state_t const& in ); |
|
| 83 |
+ |
|
| 84 |
+ // Number of samples delay from synthesis to samples read out |
|
| 85 |
+ int output_latency() const; |
|
| 86 |
+ |
|
| 87 |
+ // Counts number of clocks needed until 'count' samples will be available. |
|
| 88 |
+ // If buffer can't even hold 'count' samples, returns number of clocks until |
|
| 89 |
+ // buffer becomes full. |
|
| 90 |
+ blip_time_t count_clocks( long count ) const; |
|
| 91 |
+ |
|
| 92 |
+ // Number of raw samples that can be mixed within frame of specified duration. |
|
| 93 |
+ long count_samples( blip_time_t duration ) const; |
|
| 94 |
+ |
|
| 95 |
+ // Mixes in 'count' samples from 'buf_in' |
|
| 96 |
+ void mix_samples( blip_sample_t const* buf_in, long count ); |
|
| 97 |
+ |
|
| 98 |
+ |
|
| 99 |
+ // Signals that sound has been added to buffer. Could be done automatically in |
|
| 100 |
+ // Blip_Synth, but that would affect performance more, as you can arrange that |
|
| 101 |
+ // this is called only once per time frame rather than for every delta. |
|
| 102 |
+ void set_modified() { modified_ = this; }
|
|
| 103 |
+ |
|
| 104 |
+ // not documented yet |
|
| 105 |
+ blip_ulong unsettled() const; |
|
| 106 |
+ Blip_Buffer* clear_modified() { Blip_Buffer* b = modified_; modified_ = 0; return b; }
|
|
| 107 |
+ void remove_silence( long count ); |
|
| 108 |
+ typedef blip_ulong blip_resampled_time_t; |
|
| 109 |
+ blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; }
|
|
| 110 |
+ blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; }
|
|
| 111 |
+ blip_resampled_time_t clock_rate_factor( long clock_rate ) const; |
|
| 112 |
+public: |
|
| 113 |
+ Blip_Buffer(); |
|
| 114 |
+ ~Blip_Buffer(); |
|
| 115 |
+ |
|
| 116 |
+ // Deprecated |
|
| 117 |
+ typedef blip_resampled_time_t resampled_time_t; |
|
| 118 |
+ blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); }
|
|
| 119 |
+ blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); }
|
|
| 120 |
+private: |
|
| 121 |
+ // noncopyable |
|
| 122 |
+ Blip_Buffer( const Blip_Buffer& ); |
|
| 123 |
+ Blip_Buffer& operator = ( const Blip_Buffer& ); |
|
| 124 |
+public: |
|
| 125 |
+ typedef blip_long buf_t_; |
|
| 126 |
+ blip_ulong factor_; |
|
| 127 |
+ blip_resampled_time_t offset_; |
|
| 128 |
+ buf_t_* buffer_; |
|
| 129 |
+ blip_long buffer_size_; |
|
| 130 |
+ blip_long reader_accum_; |
|
| 131 |
+ int bass_shift_; |
|
| 132 |
+private: |
|
| 133 |
+ long sample_rate_; |
|
| 134 |
+ long clock_rate_; |
|
| 135 |
+ int bass_freq_; |
|
| 136 |
+ int length_; |
|
| 137 |
+ Blip_Buffer* modified_; // non-zero = true (more optimal than using bool, heh) |
|
| 138 |
+ friend class Blip_Reader; |
|
| 139 |
+}; |
|
| 140 |
+ |
|
| 141 |
+#ifdef HAVE_CONFIG_H |
|
| 142 |
+ #include "config.h" |
|
| 143 |
+#endif |
|
| 144 |
+ |
|
| 145 |
+// Number of bits in resample ratio fraction. Higher values give a more accurate ratio |
|
| 146 |
+// but reduce maximum buffer size. |
|
| 147 |
+#ifndef BLIP_BUFFER_ACCURACY |
|
| 148 |
+ #define BLIP_BUFFER_ACCURACY 16 |
|
| 149 |
+#endif |
|
| 150 |
+ |
|
| 151 |
+// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in |
|
| 152 |
+// noticeable broadband noise when synthesizing high frequency square waves. |
|
| 153 |
+// Affects size of Blip_Synth objects since they store the waveform directly. |
|
| 154 |
+#ifndef BLIP_PHASE_BITS |
|
| 155 |
+ #if BLIP_BUFFER_FAST |
|
| 156 |
+ #define BLIP_PHASE_BITS 8 |
|
| 157 |
+ #else |
|
| 158 |
+ #define BLIP_PHASE_BITS 6 |
|
| 159 |
+ #endif |
|
| 160 |
+#endif |
|
| 161 |
+ |
|
| 162 |
+ // Internal |
|
| 163 |
+ typedef blip_ulong blip_resampled_time_t; |
|
| 164 |
+ int const blip_widest_impulse_ = 16; |
|
| 165 |
+ int const blip_buffer_extra_ = blip_widest_impulse_ + 2; |
|
| 166 |
+ int const blip_res = 1 << BLIP_PHASE_BITS; |
|
| 167 |
+ class blip_eq_t; |
|
| 168 |
+ |
|
| 169 |
+ class Blip_Synth_Fast_ {
|
|
| 170 |
+ public: |
|
| 171 |
+ Blip_Buffer* buf; |
|
| 172 |
+ int last_amp; |
|
| 173 |
+ int delta_factor; |
|
| 174 |
+ |
|
| 175 |
+ void volume_unit( double ); |
|
| 176 |
+ Blip_Synth_Fast_(); |
|
| 177 |
+ void treble_eq( blip_eq_t const& ) { }
|
|
| 178 |
+ }; |
|
| 179 |
+ |
|
| 180 |
+ class Blip_Synth_ {
|
|
| 181 |
+ public: |
|
| 182 |
+ Blip_Buffer* buf; |
|
| 183 |
+ int last_amp; |
|
| 184 |
+ int delta_factor; |
|
| 185 |
+ |
|
| 186 |
+ void volume_unit( double ); |
|
| 187 |
+ Blip_Synth_( short* impulses, int width ); |
|
| 188 |
+ void treble_eq( blip_eq_t const& ); |
|
| 189 |
+ private: |
|
| 190 |
+ double volume_unit_; |
|
| 191 |
+ short* const impulses; |
|
| 192 |
+ int const width; |
|
| 193 |
+ blip_long kernel_unit; |
|
| 194 |
+ int impulses_size() const { return blip_res / 2 * width + 1; }
|
|
| 195 |
+ void adjust_impulse(); |
|
| 196 |
+ }; |
|
| 197 |
+ |
|
| 198 |
+// Quality level, better = slower. In general, use blip_good_quality. |
|
| 199 |
+const int blip_med_quality = 8; |
|
| 200 |
+const int blip_good_quality = 12; |
|
| 201 |
+const int blip_high_quality = 16; |
|
| 202 |
+ |
|
| 203 |
+// Range specifies the greatest expected change in amplitude. Calculate it |
|
| 204 |
+// by finding the difference between the maximum and minimum expected |
|
| 205 |
+// amplitudes (max - min). |
|
| 206 |
+template<int quality,int range> |
|
| 207 |
+class Blip_Synth {
|
|
| 208 |
+public: |
|
| 209 |
+ // Sets overall volume of waveform |
|
| 210 |
+ void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? -range : range)) ); }
|
|
| 211 |
+ |
|
| 212 |
+ // Configures low-pass filter (see blip_buffer.txt) |
|
| 213 |
+ void treble_eq( blip_eq_t const& eq ) { impl.treble_eq( eq ); }
|
|
| 214 |
+ |
|
| 215 |
+ // Gets/sets Blip_Buffer used for output |
|
| 216 |
+ Blip_Buffer* output() const { return impl.buf; }
|
|
| 217 |
+ void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; }
|
|
| 218 |
+ |
|
| 219 |
+ // Updates amplitude of waveform at given time. Using this requires a separate |
|
| 220 |
+ // Blip_Synth for each waveform. |
|
| 221 |
+ void update( blip_time_t time, int amplitude ); |
|
| 222 |
+ |
|
| 223 |
+// Low-level interface |
|
| 224 |
+ |
|
| 225 |
+ // Adds an amplitude transition of specified delta, optionally into specified buffer |
|
| 226 |
+ // rather than the one set with output(). Delta can be positive or negative. |
|
| 227 |
+ // The actual change in amplitude is delta * (volume / range) |
|
| 228 |
+ void offset( blip_time_t, int delta, Blip_Buffer* ) const; |
|
| 229 |
+ void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); }
|
|
| 230 |
+ |
|
| 231 |
+ // Works directly in terms of fractional output samples. Contact author for more info. |
|
| 232 |
+ void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const; |
|
| 233 |
+ |
|
| 234 |
+ // Same as offset(), except code is inlined for higher performance |
|
| 235 |
+ void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const {
|
|
| 236 |
+ offset_resampled( t * buf->factor_ + buf->offset_, delta, buf ); |
|
| 237 |
+ } |
|
| 238 |
+ void offset_inline( blip_time_t t, int delta ) const {
|
|
| 239 |
+ offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf ); |
|
| 240 |
+ } |
|
| 241 |
+ |
|
| 242 |
+private: |
|
| 243 |
+#if BLIP_BUFFER_FAST |
|
| 244 |
+ Blip_Synth_Fast_ impl; |
|
| 245 |
+#else |
|
| 246 |
+ Blip_Synth_ impl; |
|
| 247 |
+ typedef short imp_t; |
|
| 248 |
+ imp_t impulses [blip_res * (quality / 2) + 1]; |
|
| 249 |
+public: |
|
| 250 |
+ Blip_Synth() : impl( impulses, quality ) { }
|
|
| 251 |
+#endif |
|
| 252 |
+}; |
|
| 253 |
+ |
|
| 254 |
+// Low-pass equalization parameters |
|
| 255 |
+class blip_eq_t {
|
|
| 256 |
+public: |
|
| 257 |
+ // Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce |
|
| 258 |
+ // treble, small positive values (0 to 5.0) increase treble. |
|
| 259 |
+ blip_eq_t( double treble_db = 0 ); |
|
| 260 |
+ |
|
| 261 |
+ // See blip_buffer.txt |
|
| 262 |
+ blip_eq_t( double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0 ); |
|
| 263 |
+ |
|
| 264 |
+private: |
|
| 265 |
+ double treble; |
|
| 266 |
+ long rolloff_freq; |
|
| 267 |
+ long sample_rate; |
|
| 268 |
+ long cutoff_freq; |
|
| 269 |
+ void generate( float* out, int count ) const; |
|
| 270 |
+ friend class Blip_Synth_; |
|
| 271 |
+}; |
|
| 272 |
+ |
|
| 273 |
+int const blip_sample_bits = 30; |
|
| 274 |
+ |
|
| 275 |
+// Dummy Blip_Buffer to direct sound output to, for easy muting without |
|
| 276 |
+// having to stop sound code. |
|
| 277 |
+class Silent_Blip_Buffer : public Blip_Buffer {
|
|
| 278 |
+ buf_t_ buf [blip_buffer_extra_ + 1]; |
|
| 279 |
+public: |
|
| 280 |
+ // The following cannot be used (an assertion will fail if attempted): |
|
| 281 |
+ blargg_err_t set_sample_rate( long samples_per_sec, int msec_length ); |
|
| 282 |
+ blip_time_t count_clocks( long count ) const; |
|
| 283 |
+ void mix_samples( blip_sample_t const* buf, long count ); |
|
| 284 |
+ |
|
| 285 |
+ Silent_Blip_Buffer(); |
|
| 286 |
+}; |
|
| 287 |
+ |
|
| 288 |
+ #if __GNUC__ >= 3 || _MSC_VER >= 1100 |
|
| 289 |
+ #define BLIP_RESTRICT __restrict |
|
| 290 |
+ #else |
|
| 291 |
+ #define BLIP_RESTRICT |
|
| 292 |
+ #endif |
|
| 293 |
+ |
|
| 294 |
+// Optimized reading from Blip_Buffer, for use in custom sample output |
|
| 295 |
+ |
|
| 296 |
+// Begins reading from buffer. Name should be unique to the current block. |
|
| 297 |
+#define BLIP_READER_BEGIN( name, blip_buffer ) \ |
|
| 298 |
+ const Blip_Buffer::buf_t_* BLIP_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\ |
|
| 299 |
+ blip_long name##_reader_accum = (blip_buffer).reader_accum_ |
|
| 300 |
+ |
|
| 301 |
+// Gets value to pass to BLIP_READER_NEXT() |
|
| 302 |
+#define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_) |
|
| 303 |
+ |
|
| 304 |
+// Constant value to use instead of BLIP_READER_BASS(), for slightly more optimal |
|
| 305 |
+// code at the cost of having no bass control |
|
| 306 |
+int const blip_reader_default_bass = 9; |
|
| 307 |
+ |
|
| 308 |
+// Current sample |
|
| 309 |
+#define BLIP_READER_READ( name ) (name##_reader_accum >> (blip_sample_bits - 16)) |
|
| 310 |
+ |
|
| 311 |
+// Current raw sample in full internal resolution |
|
| 312 |
+#define BLIP_READER_READ_RAW( name ) (name##_reader_accum) |
|
| 313 |
+ |
|
| 314 |
+// Advances to next sample |
|
| 315 |
+#define BLIP_READER_NEXT( name, bass ) \ |
|
| 316 |
+ (void) (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass))) |
|
| 317 |
+ |
|
| 318 |
+// Ends reading samples from buffer. The number of samples read must now be removed |
|
| 319 |
+// using Blip_Buffer::remove_samples(). |
|
| 320 |
+#define BLIP_READER_END( name, blip_buffer ) \ |
|
| 321 |
+ (void) ((blip_buffer).reader_accum_ = name##_reader_accum) |
|
| 322 |
+ |
|
| 323 |
+ |
|
| 324 |
+// experimental |
|
| 325 |
+#define BLIP_READER_ADJ_( name, offset ) (name##_reader_buf += offset) |
|
| 326 |
+ |
|
| 327 |
+blip_long const blip_reader_idx_factor = sizeof (Blip_Buffer::buf_t_); |
|
| 328 |
+ |
|
| 329 |
+#define BLIP_READER_NEXT_IDX_( name, bass, idx ) {\
|
|
| 330 |
+ name##_reader_accum -= name##_reader_accum >> (bass);\ |
|
| 331 |
+ name##_reader_accum += name##_reader_buf [(idx)];\ |
|
| 332 |
+} |
|
| 333 |
+ |
|
| 334 |
+#define BLIP_READER_NEXT_RAW_IDX_( name, bass, idx ) {\
|
|
| 335 |
+ name##_reader_accum -= name##_reader_accum >> (bass);\ |
|
| 336 |
+ name##_reader_accum +=\ |
|
| 337 |
+ *(Blip_Buffer::buf_t_ const*) ((char const*) name##_reader_buf + (idx));\ |
|
| 338 |
+} |
|
| 339 |
+ |
|
| 340 |
+// Compatibility with older version |
|
| 341 |
+const long blip_unscaled = 65535; |
|
| 342 |
+const int blip_low_quality = blip_med_quality; |
|
| 343 |
+const int blip_best_quality = blip_high_quality; |
|
| 344 |
+ |
|
| 345 |
+// Deprecated; use BLIP_READER macros as follows: |
|
| 346 |
+// Blip_Reader r; r.begin( buf ); -> BLIP_READER_BEGIN( r, buf ); |
|
| 347 |
+// int bass = r.begin( buf ) -> BLIP_READER_BEGIN( r, buf ); int bass = BLIP_READER_BASS( buf ); |
|
| 348 |
+// r.read() -> BLIP_READER_READ( r ) |
|
| 349 |
+// r.read_raw() -> BLIP_READER_READ_RAW( r ) |
|
| 350 |
+// r.next( bass ) -> BLIP_READER_NEXT( r, bass ) |
|
| 351 |
+// r.next() -> BLIP_READER_NEXT( r, blip_reader_default_bass ) |
|
| 352 |
+// r.end( buf ) -> BLIP_READER_END( r, buf ) |
|
| 353 |
+class Blip_Reader {
|
|
| 354 |
+public: |
|
| 355 |
+ int begin( Blip_Buffer& ); |
|
| 356 |
+ blip_long read() const { return accum >> (blip_sample_bits - 16); }
|
|
| 357 |
+ blip_long read_raw() const { return accum; }
|
|
| 358 |
+ void next( int bass_shift = 9 ) { accum += *buf++ - (accum >> bass_shift); }
|
|
| 359 |
+ void end( Blip_Buffer& b ) { b.reader_accum_ = accum; }
|
|
| 360 |
+private: |
|
| 361 |
+ const Blip_Buffer::buf_t_* buf; |
|
| 362 |
+ blip_long accum; |
|
| 363 |
+}; |
|
| 364 |
+ |
|
| 365 |
+#if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \ |
|
| 366 |
+ defined (__x86_64__) || defined (__ia64__) || defined (__i386__) |
|
| 367 |
+ #define BLIP_CLAMP_( in ) in < -0x8000 || 0x7FFF < in |
|
| 368 |
+#else |
|
| 369 |
+ #define BLIP_CLAMP_( in ) (blip_sample_t) in != in |
|
| 370 |
+#endif |
|
| 371 |
+ |
|
| 372 |
+// Clamp sample to blip_sample_t range |
|
| 373 |
+#define BLIP_CLAMP( sample, out )\ |
|
| 374 |
+ { if ( BLIP_CLAMP_( (sample) ) ) (out) = ((sample) >> 24) ^ 0x7FFF; }
|
|
| 375 |
+ |
|
| 376 |
+struct blip_buffer_state_t |
|
| 377 |
+{
|
|
| 378 |
+ blip_resampled_time_t offset_; |
|
| 379 |
+ blip_long reader_accum_; |
|
| 380 |
+ blip_long buf [blip_buffer_extra_]; |
|
| 381 |
+}; |
|
| 382 |
+ |
|
| 383 |
+// End of public interface |
|
| 384 |
+ |
|
| 385 |
+#ifndef assert |
|
| 386 |
+ #include <assert.h> |
|
| 387 |
+#endif |
|
| 388 |
+ |
|
| 389 |
+template<int quality,int range> |
|
| 390 |
+inline void Blip_Synth<quality,range>::offset_resampled( blip_resampled_time_t time, |
|
| 391 |
+ int delta, Blip_Buffer* blip_buf ) const |
|
| 392 |
+{
|
|
| 393 |
+ // If this assertion fails, it means that an attempt was made to add a delta |
|
| 394 |
+ // at a negative time or past the end of the buffer. |
|
| 395 |
+ assert( (blip_long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ ); |
|
| 396 |
+ |
|
| 397 |
+ delta *= impl.delta_factor; |
|
| 398 |
+ blip_long* BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY); |
|
| 399 |
+ int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1)); |
|
| 400 |
+ |
|
| 401 |
+#if BLIP_BUFFER_FAST |
|
| 402 |
+ blip_long left = buf [0] + delta; |
|
| 403 |
+ |
|
| 404 |
+ // Kind of crappy, but doing shift after multiply results in overflow. |
|
| 405 |
+ // Alternate way of delaying multiply by delta_factor results in worse |
|
| 406 |
+ // sub-sample resolution. |
|
| 407 |
+ blip_long right = (delta >> BLIP_PHASE_BITS) * phase; |
|
| 408 |
+ left -= right; |
|
| 409 |
+ right += buf [1]; |
|
| 410 |
+ |
|
| 411 |
+ buf [0] = left; |
|
| 412 |
+ buf [1] = right; |
|
| 413 |
+#else |
|
| 414 |
+ |
|
| 415 |
+ int const fwd = (blip_widest_impulse_ - quality) / 2; |
|
| 416 |
+ int const rev = fwd + quality - 2; |
|
| 417 |
+ int const mid = quality / 2 - 1; |
|
| 418 |
+ |
|
| 419 |
+ imp_t const* BLIP_RESTRICT imp = impulses + blip_res - phase; |
|
| 420 |
+ |
|
| 421 |
+ #if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \ |
|
| 422 |
+ defined (__x86_64__) || defined (__ia64__) || defined (__i386__) |
|
| 423 |
+ |
|
| 424 |
+ // this straight forward version gave in better code on GCC for x86 |
|
| 425 |
+ |
|
| 426 |
+ #define ADD_IMP( out, in ) \ |
|
| 427 |
+ buf [out] += (blip_long) imp [blip_res * (in)] * delta |
|
| 428 |
+ |
|
| 429 |
+ #define BLIP_FWD( i ) {\
|
|
| 430 |
+ ADD_IMP( fwd + i, i );\ |
|
| 431 |
+ ADD_IMP( fwd + 1 + i, i + 1 );\ |
|
| 432 |
+ } |
|
| 433 |
+ #define BLIP_REV( r ) {\
|
|
| 434 |
+ ADD_IMP( rev - r, r + 1 );\ |
|
| 435 |
+ ADD_IMP( rev + 1 - r, r );\ |
|
| 436 |
+ } |
|
| 437 |
+ |
|
| 438 |
+ BLIP_FWD( 0 ) |
|
| 439 |
+ if ( quality > 8 ) BLIP_FWD( 2 ) |
|
| 440 |
+ if ( quality > 12 ) BLIP_FWD( 4 ) |
|
| 441 |
+ {
|
|
| 442 |
+ ADD_IMP( fwd + mid - 1, mid - 1 ); |
|
| 443 |
+ ADD_IMP( fwd + mid , mid ); |
|
| 444 |
+ imp = impulses + phase; |
|
| 445 |
+ } |
|
| 446 |
+ if ( quality > 12 ) BLIP_REV( 6 ) |
|
| 447 |
+ if ( quality > 8 ) BLIP_REV( 4 ) |
|
| 448 |
+ BLIP_REV( 2 ) |
|
| 449 |
+ |
|
| 450 |
+ ADD_IMP( rev , 1 ); |
|
| 451 |
+ ADD_IMP( rev + 1, 0 ); |
|
| 452 |
+ |
|
| 453 |
+ #undef ADD_IMP |
|
| 454 |
+ |
|
| 455 |
+ #else |
|
| 456 |
+ |
|
| 457 |
+ // for RISC processors, help compiler by reading ahead of writes |
|
| 458 |
+ |
|
| 459 |
+ #define BLIP_FWD( i ) {\
|
|
| 460 |
+ blip_long t0 = i0 * delta + buf [fwd + i];\ |
|
| 461 |
+ blip_long t1 = imp [blip_res * (i + 1)] * delta + buf [fwd + 1 + i];\ |
|
| 462 |
+ i0 = imp [blip_res * (i + 2)];\ |
|
| 463 |
+ buf [fwd + i] = t0;\ |
|
| 464 |
+ buf [fwd + 1 + i] = t1;\ |
|
| 465 |
+ } |
|
| 466 |
+ #define BLIP_REV( r ) {\
|
|
| 467 |
+ blip_long t0 = i0 * delta + buf [rev - r];\ |
|
| 468 |
+ blip_long t1 = imp [blip_res * r] * delta + buf [rev + 1 - r];\ |
|
| 469 |
+ i0 = imp [blip_res * (r - 1)];\ |
|
| 470 |
+ buf [rev - r] = t0;\ |
|
| 471 |
+ buf [rev + 1 - r] = t1;\ |
|
| 472 |
+ } |
|
| 473 |
+ |
|
| 474 |
+ blip_long i0 = *imp; |
|
| 475 |
+ BLIP_FWD( 0 ) |
|
| 476 |
+ if ( quality > 8 ) BLIP_FWD( 2 ) |
|
| 477 |
+ if ( quality > 12 ) BLIP_FWD( 4 ) |
|
| 478 |
+ {
|
|
| 479 |
+ blip_long t0 = i0 * delta + buf [fwd + mid - 1]; |
|
| 480 |
+ blip_long t1 = imp [blip_res * mid] * delta + buf [fwd + mid ]; |
|
| 481 |
+ imp = impulses + phase; |
|
| 482 |
+ i0 = imp [blip_res * mid]; |
|
| 483 |
+ buf [fwd + mid - 1] = t0; |
|
| 484 |
+ buf [fwd + mid ] = t1; |
|
| 485 |
+ } |
|
| 486 |
+ if ( quality > 12 ) BLIP_REV( 6 ) |
|
| 487 |
+ if ( quality > 8 ) BLIP_REV( 4 ) |
|
| 488 |
+ BLIP_REV( 2 ) |
|
| 489 |
+ |
|
| 490 |
+ blip_long t0 = i0 * delta + buf [rev ]; |
|
| 491 |
+ blip_long t1 = *imp * delta + buf [rev + 1]; |
|
| 492 |
+ buf [rev ] = t0; |
|
| 493 |
+ buf [rev + 1] = t1; |
|
| 494 |
+ #endif |
|
| 495 |
+ |
|
| 496 |
+#endif |
|
| 497 |
+} |
|
| 498 |
+ |
|
| 499 |
+#undef BLIP_FWD |
|
| 500 |
+#undef BLIP_REV |
|
| 501 |
+ |
|
| 502 |
+template<int quality,int range> |
|
| 503 |
+#if BLIP_BUFFER_FAST |
|
| 504 |
+ inline |
|
| 505 |
+#endif |
|
| 506 |
+void Blip_Synth<quality,range>::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const |
|
| 507 |
+{
|
|
| 508 |
+ offset_resampled( t * buf->factor_ + buf->offset_, delta, buf ); |
|
| 509 |
+} |
|
| 510 |
+ |
|
| 511 |
+template<int quality,int range> |
|
| 512 |
+#if BLIP_BUFFER_FAST |
|
| 513 |
+ inline |
|
| 514 |
+#endif |
|
| 515 |
+void Blip_Synth<quality,range>::update( blip_time_t t, int amp ) |
|
| 516 |
+{
|
|
| 517 |
+ int delta = amp - impl.last_amp; |
|
| 518 |
+ impl.last_amp = amp; |
|
| 519 |
+ offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf ); |
|
| 520 |
+} |
|
| 521 |
+ |
|
| 522 |
+inline blip_eq_t::blip_eq_t( double t ) : |
|
| 523 |
+ treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { }
|
|
| 524 |
+inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) : |
|
| 525 |
+ treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { }
|
|
| 526 |
+ |
|
| 527 |
+inline int Blip_Buffer::length() const { return length_; }
|
|
| 528 |
+inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); }
|
|
| 529 |
+inline long Blip_Buffer::sample_rate() const { return sample_rate_; }
|
|
| 530 |
+inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; }
|
|
| 531 |
+inline long Blip_Buffer::clock_rate() const { return clock_rate_; }
|
|
| 532 |
+inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); }
|
|
| 533 |
+ |
|
| 534 |
+inline int Blip_Reader::begin( Blip_Buffer& blip_buf ) |
|
| 535 |
+{
|
|
| 536 |
+ buf = blip_buf.buffer_; |
|
| 537 |
+ accum = blip_buf.reader_accum_; |
|
| 538 |
+ return blip_buf.bass_shift_; |
|
| 539 |
+} |
|
| 540 |
+ |
|
| 541 |
+inline void Blip_Buffer::remove_silence( long count ) |
|
| 542 |
+{
|
|
| 543 |
+ // fails if you try to remove more samples than available |
|
| 544 |
+ assert( count <= samples_avail() ); |
|
| 545 |
+ offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY; |
|
| 546 |
+} |
|
| 547 |
+ |
|
| 548 |
+inline blip_ulong Blip_Buffer::unsettled() const |
|
| 549 |
+{
|
|
| 550 |
+ return reader_accum_ >> (blip_sample_bits - 16); |
|
| 551 |
+} |
|
| 552 |
+ |
|
| 553 |
+int const blip_max_length = 0; |
|
| 554 |
+int const blip_default_length = 250; // 1/4 second |
|
| 555 |
+ |
|
| 556 |
+#endif |