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