1 /* blip_buf 1.1.0. http://www.slack.net/~ant/ */ 2 3 module blip_buf; 4 5 import core.stdc.stdlib; 6 import core.stdc..string; 7 8 /* Library Copyright (C) 2003-2009 Shay Green. This library is free software; 9 you can redistribute it and/or modify it under the terms of the GNU Lesser 10 General Public License as published by the Free Software Foundation; either 11 version 2.1 of the License, or (at your option) any later version. This 12 library is distributed in the hope that it will be useful, but WITHOUT ANY 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 14 A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 15 details. You should have received a copy of the GNU Lesser General Public 16 License along with this module; if not, write to the Free Software Foundation, 17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 18 19 20 /** Maximum clock_rate/sample_rate ratio. For a given sample_rate, 21 clock_rate must not be greater than sample_rate*blip_max_ratio. */ 22 enum blip_max_ratio = 1 << 20; 23 24 /** Maximum number of samples that can be generated from one time frame. */ 25 enum blip_max_frame = 4000; 26 27 alias fixed_t = ulong; 28 enum pre_shift = 32; 29 30 enum time_bits = pre_shift + 20; 31 32 const fixed_t time_unit = cast(fixed_t)(1) << time_bits; 33 34 enum bass_shift = 9; /* affects high-pass filter breakpoint frequency */ 35 enum end_frame_extra = 2; /* allows deltas slightly after frame length */ 36 37 enum half_width = 8; 38 enum buf_extra = half_width*2 + end_frame_extra; 39 enum phase_bits = 5; 40 enum phase_count = 1 << phase_bits; 41 enum delta_bits = 15; 42 enum delta_unit = 1 << delta_bits; 43 enum frac_bits = time_bits - pre_shift; 44 45 /* We could eliminate avail and encode whole samples in offset, but that would 46 limit the total buffered samples to blip_max_frame. That could only be 47 increased by decreasing time_bits, which would reduce resample ratio accuracy. 48 */ 49 50 /** Sample buffer that resamples to output rate and accumulates samples 51 until they're read out */ 52 struct blip_t { 53 fixed_t factor; 54 fixed_t offset; 55 int avail; 56 int size; 57 int integrator; 58 } 59 60 alias buf_t = int; 61 62 /* probably not totally portable */ 63 buf_t* SAMPLES(blip_t* buf) { 64 return cast(buf_t*)(buf + 1); 65 } 66 67 /* Arithmetic (sign-preserving) right shift */ 68 int ARITH_SHIFT(int n, int shift) { 69 return n >> shift; 70 } 71 72 enum max_sample = +32767; 73 enum min_sample = -32768; 74 75 void CLAMP(ref int n) { 76 if (cast(short)n != n) 77 n = ARITH_SHIFT(n, 16) ^ max_sample; 78 } 79 80 void check_assumptions() { 81 int n; 82 83 assert(int.max >= 0x7FFFFFFF && uint.max >= 0xFFFFFFFF, "int must be at least 32 bits"); 84 85 assert((-3 >> 1) == -2); /* right shift must preserve sign */ 86 87 n = max_sample * 2; 88 CLAMP(n); 89 assert(n == max_sample); 90 91 n = min_sample * 2; 92 CLAMP(n); 93 assert(n == min_sample); 94 95 assert(blip_max_ratio <= time_unit); 96 assert(blip_max_frame <= cast(fixed_t)-1 >> time_bits); 97 } 98 99 blip_t* blip_new(int size) { 100 blip_t* m; 101 assert(size >= 0); 102 103 m = cast(blip_t*) malloc((*m).sizeof + (size + buf_extra) * buf_t.sizeof); 104 if (m) { 105 m.factor = time_unit / blip_max_ratio; 106 m.size = size; 107 blip_clear(m); 108 check_assumptions(); 109 } 110 return m; 111 } 112 113 void blip_delete(blip_t* m) { 114 if (m != null) { 115 /* Clear fields in case user tries to use after freeing */ 116 memset(m, 0, (*m).sizeof); 117 free(m); 118 } 119 } 120 121 void blip_set_rates(blip_t* m, double clock_rate, double sample_rate) { 122 double factor = time_unit * sample_rate / clock_rate; 123 m.factor = cast(fixed_t)factor; 124 125 /* Fails if clock_rate exceeds maximum, relative to sample_rate */ 126 assert(0 <= factor - m.factor && factor - m.factor < 1); 127 128 /* Avoid requiring math.h. Equivalent to 129 m.factor = (int) ceil(factor) */ 130 if (m.factor < factor) 131 m.factor++; 132 133 /* At this point, factor is most likely rounded up, but could still 134 have been rounded down in the floating-point calculation. */ 135 } 136 137 void blip_clear(blip_t* m) { 138 /* We could set offset to 0, factor/2, or factor-1. 0 is suitable if 139 factor is rounded up. factor-1 is suitable if factor is rounded down. 140 Since we don't know rounding direction, factor/2 accommodates either, 141 with the slight loss of showing an error in half the time. Since for 142 a 64-bit factor this is years, the halving isn't a problem. */ 143 144 m.offset = m.factor / 2; 145 m.avail = 0; 146 m.integrator = 0; 147 memset(SAMPLES(m), 0, (m.size + buf_extra) * buf_t.sizeof); 148 } 149 150 int blip_clocks_needed(const blip_t* m, int samples) { 151 fixed_t needed; 152 153 /* Fails if buffer can't hold that many more samples */ 154 assert(samples >= 0 && m.avail + samples <= m.size); 155 156 needed = cast(fixed_t) samples * time_unit; 157 if (needed < m.offset) 158 return 0; 159 160 return cast(int)((needed - m.offset + m.factor - 1) / m.factor); 161 } 162 163 void blip_end_frame(blip_t* m, uint t) { 164 fixed_t off = t * m.factor + m.offset; 165 m.avail += off >> time_bits; 166 m.offset = off & (time_unit - 1); 167 168 /* Fails if buffer size was exceeded */ 169 assert(m.avail <= m.size); 170 } 171 172 int blip_samples_avail(const blip_t* m) { 173 return m.avail; 174 } 175 176 void remove_samples(blip_t* m, int count) { 177 buf_t* buf = SAMPLES(m); 178 int remain = m.avail + buf_extra - count; 179 m.avail -= count; 180 181 memmove(&buf [0], &buf[count], remain * buf[0].sizeof); 182 memset(&buf[remain], 0, count * buf[0].sizeof); 183 } 184 185 int blip_read_samples(blip_t* m, short* _out, int count, int stereo) { 186 assert(count >= 0); 187 188 if (count > m.avail) 189 count = m.avail; 190 191 if (count) { 192 const int step = stereo ? 2 : 1; 193 const(buf_t)* _in = SAMPLES(m); 194 const(buf_t)* end = _in + count; 195 int sum = m.integrator; 196 do { 197 /* Eliminate fraction */ 198 int s = ARITH_SHIFT(sum, delta_bits); 199 200 sum += *_in++; 201 202 CLAMP(s); 203 204 *_out = cast(short)s; 205 _out += step; 206 207 /* High-pass filter */ 208 sum -= s << (delta_bits - bass_shift); 209 } while (_in != end); 210 m.integrator = sum; 211 212 remove_samples(m, count); 213 } 214 215 return count; 216 } 217 218 /* Sinc_Generator(0.9, 0.55, 4.5) */ 219 immutable short[half_width][phase_count + 1] bl_step = 220 [ 221 [ 43, -115, 350, -488, 1136, -914, 5861,21022], 222 [ 44, -118, 348, -473, 1076, -799, 5274,21001], 223 [ 45, -121, 344, -454, 1011, -677, 4706,20936], 224 [ 46, -122, 336, -431, 942, -549, 4156,20829], 225 [ 47, -123, 327, -404, 868, -418, 3629,20679], 226 [ 47, -122, 316, -375, 792, -285, 3124,20488], 227 [ 47, -120, 303, -344, 714, -151, 2644,20256], 228 [ 46, -117, 289, -310, 634, -17, 2188,19985], 229 [ 46, -114, 273, -275, 553, 117, 1758,19675], 230 [ 44, -108, 255, -237, 471, 247, 1356,19327], 231 [ 43, -103, 237, -199, 390, 373, 981,18944], 232 [ 42, -98, 218, -160, 310, 495, 633,18527], 233 [ 40, -91, 198, -121, 231, 611, 314,18078], 234 [ 38, -84, 178, -81, 153, 722, 22,17599], 235 [ 36, -76, 157, -43, 80, 824, -241,17092], 236 [ 34, -68, 135, -3, 8, 919, -476,16558], 237 [ 32, -61, 115, 34, -60, 1006, -683,16001], 238 [ 29, -52, 94, 70, -123, 1083, -862,15422], 239 [ 27, -44, 73, 106, -184, 1152,-1015,14824], 240 [ 25, -36, 53, 139, -239, 1211,-1142,14210], 241 [ 22, -27, 34, 170, -290, 1261,-1244,13582], 242 [ 20, -20, 16, 199, -335, 1301,-1322,12942], 243 [ 18, -12, -3, 226, -375, 1331,-1376,12293], 244 [ 15, -4, -19, 250, -410, 1351,-1408,11638], 245 [ 13, 3, -35, 272, -439, 1361,-1419,10979], 246 [ 11, 9, -49, 292, -464, 1362,-1410,10319], 247 [ 9, 16, -63, 309, -483, 1354,-1383, 9660], 248 [ 7, 22, -75, 322, -496, 1337,-1339, 9005], 249 [ 6, 26, -85, 333, -504, 1312,-1280, 8355], 250 [ 4, 31, -94, 341, -507, 1278,-1205, 7713], 251 [ 3, 35, -102, 347, -506, 1238,-1119, 7082], 252 [ 1, 40, -110, 350, -499, 1190,-1021, 6464], 253 [ 0, 43, -115, 350, -488, 1136, -914, 5861] 254 ]; 255 256 /* Shifting by pre_shift allows calculation using unsigned int rather than 257 possibly-wider fixed_t. On 32-bit platforms, this is likely more efficient. 258 And by having pre_shift 32, a 32-bit platform can easily do the shift by 259 simply ignoring the low half. */ 260 261 void blip_add_delta(blip_t* m, uint time, int delta) { 262 uint fixed = cast(uint) ((time * m.factor + m.offset) >> pre_shift); 263 buf_t* _out = SAMPLES(m) + m.avail + (fixed >> frac_bits); 264 265 const int phase_shift = frac_bits - phase_bits; 266 int phase = fixed >> phase_shift & (phase_count - 1); 267 const(short)* _in = bl_step[phase].ptr; 268 const(short)* rev = bl_step[phase_count - phase].ptr; 269 270 int interp = fixed >> (phase_shift - delta_bits) & (delta_unit - 1); 271 int delta2 = (delta * interp) >> delta_bits; 272 delta -= delta2; 273 274 /* Fails if buffer size was exceeded */ 275 assert(_out <= &SAMPLES(m) [m.size + end_frame_extra]); 276 277 _out [0] += _in[0]*delta + _in[half_width+0]*delta2; 278 _out [1] += _in[1]*delta + _in[half_width+1]*delta2; 279 _out [2] += _in[2]*delta + _in[half_width+2]*delta2; 280 _out [3] += _in[3]*delta + _in[half_width+3]*delta2; 281 _out [4] += _in[4]*delta + _in[half_width+4]*delta2; 282 _out [5] += _in[5]*delta + _in[half_width+5]*delta2; 283 _out [6] += _in[6]*delta + _in[half_width+6]*delta2; 284 _out [7] += _in[7]*delta + _in[half_width+7]*delta2; 285 286 _in = rev; 287 _out [ 8] += _in[7]*delta + _in[7-half_width]*delta2; 288 _out [ 9] += _in[6]*delta + _in[6-half_width]*delta2; 289 _out [10] += _in[5]*delta + _in[5-half_width]*delta2; 290 _out [11] += _in[4]*delta + _in[4-half_width]*delta2; 291 _out [12] += _in[3]*delta + _in[3-half_width]*delta2; 292 _out [13] += _in[2]*delta + _in[2-half_width]*delta2; 293 _out [14] += _in[1]*delta + _in[1-half_width]*delta2; 294 _out [15] += _in[0]*delta + _in[0-half_width]*delta2; 295 } 296 297 void blip_add_delta_fast(blip_t* m, uint time, int delta) { 298 uint fixed = cast(uint) ((time * m.factor + m.offset) >> pre_shift); 299 buf_t* _out = SAMPLES(m) + m.avail + (fixed >> frac_bits); 300 301 int interp = fixed >> (frac_bits - delta_bits) & (delta_unit - 1); 302 int delta2 = delta * interp; 303 304 /* Fails if buffer size was exceeded */ 305 assert(_out <= &SAMPLES(m)[m.size + end_frame_extra]); 306 307 _out [7] += delta * delta_unit - delta2; 308 _out [8] += delta2; 309 }