minilogue xd SDK  v1.1-0
delayline.hpp
Go to the documentation of this file.
1 #pragma once
2 /*
3  BSD 3-Clause License
4 
5  Copyright (c) 2018, KORG INC.
6  All rights reserved.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions are met:
10 
11  * Redistributions of source code must retain the above copyright notice, this
12  list of conditions and the following disclaimer.
13 
14  * Redistributions in binary form must reproduce the above copyright notice,
15  this list of conditions and the following disclaimer in the documentation
16  and/or other materials provided with the distribution.
17 
18  * Neither the name of the copyright holder nor the names of its
19  contributors may be used to endorse or promote products derived from
20  this software without specific prior written permission.
21 
22  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 //*/
34 
44 #include "float_math.h"
45 #include "int_math.h"
46 #include "buffer_ops.h"
47 
51 namespace dsp {
52 
56  struct DelayLine {
57 
58  /*===========================================================================*/
59  /* Types and Data Structures. */
60  /*===========================================================================*/
61 
62  /*===========================================================================*/
63  /* Constructor / Destructor. */
64  /*===========================================================================*/
65 
69  DelayLine(void) :
70  mLine(0),
71  mFracZ(0),
72  mSize(0),
73  mMask(0),
74  mWriteIdx(0)
75  { }
76 
84  DelayLine(float *ram, size_t line_size) :
85  mLine(ram),
86  mFracZ(0),
87  mSize(line_size),
88  mMask(line_size-1),
89  mWriteIdx(0)
90  { }
91 
92  /*===========================================================================*/
93  /* Public Methods. */
94  /*===========================================================================*/
95 
99  inline __attribute__((optimize("Ofast"),always_inline))
100  void clear(void) {
101  buf_clr_f32((float *)mLine, mSize);
102  }
103 
112  inline __attribute__((optimize("Ofast"),always_inline))
113  void setMemory(float *ram, size_t line_size) {
114  mLine = ram;
115  mSize = nextpow2_u32(line_size); // must be power of 2
116  mMask = (mSize-1);
117  mWriteIdx = 0;
118  }
119 
125  inline __attribute__((optimize("Ofast"),always_inline))
126  void write(const float s) {
127  mLine[(mWriteIdx--) & mMask] = s;
128  }
129 
136  inline __attribute__((optimize("Ofast"),always_inline))
137  float read(const uint32_t pos) {
138  return mLine[(mWriteIdx + pos) & mMask];
139  }
140 
147  inline __attribute__((optimize("Ofast"),always_inline))
148  float readFrac(const float pos) {
149  const uint32_t base = (uint32_t)pos;
150  const float frac = pos - base;
151  const float s0 = read(base);
152  const float s1 = read(base+1);
153  return linintf(frac, s0, s1);
154  }
155 
163  inline __attribute__((optimize("Ofast"),always_inline))
164  float readFracz(const uint32_t pos, const float frac) {
165  const float s0 = read(pos);
166  const float y = linintf(frac, s0, mFracZ);
167  mFracZ = s0;
168  return y;
169  }
170 
171 
172  /*===========================================================================*/
173  /* Member Variables. */
174  /*===========================================================================*/
175 
176  float *mLine;
177  float mFracZ;
178  size_t mSize;
179  size_t mMask;
180  uint32_t mWriteIdx;
181 
182  };
183 
187  struct DualDelayLine {
188 
189  /*===========================================================================*/
190  /* Types and Data Structures. */
191  /*===========================================================================*/
192 
193  /*===========================================================================*/
194  /* Constructor / Destructor. */
195  /*===========================================================================*/
196 
201  mLine(0),
202  mSize(0),
203  mMask(0),
204  mWriteIdx(0)
205  { }
206 
207 
215  DualDelayLine(f32pair_t *ram, size_t line_size) :
216  mWriteIdx(0)
217  {
218  setMemory(ram, line_size);
219  }
220 
221  /*===========================================================================*/
222  /* Public Methods. */
223  /*===========================================================================*/
224 
228  inline __attribute__((optimize("Ofast"),always_inline))
229  void clear(void) {
230  buf_clr_f32((float *)mLine, 2*mSize);
231  }
232 
241  inline __attribute__((optimize("Ofast"),always_inline))
242  void setMemory(f32pair_t *ram, size_t line_size) {
243  mLine = ram;
244  mSize = nextpow2_u32(line_size); // must be power of 2
245  mMask = (mSize-1);
246  mWriteIdx = 0;
247  }
248 
254  inline __attribute__((optimize("Ofast"),always_inline))
255  void write(const f32pair_t &p) {
256  mLine[(mWriteIdx--) & mMask] = p;
257  }
258 
265  inline __attribute__((optimize("Ofast"),always_inline))
266  f32pair_t read(const uint32_t pos) {
267  return mLine[(mWriteIdx + pos) & mMask];
268  }
269 
276  inline __attribute__((optimize("Ofast"),always_inline))
277  f32pair_t readFrac(const float pos) {
278  const int32_t base = (uint32_t)pos;
279  const float frac = pos - base;
280  const f32pair_t p0 = read(base);
281  const f32pair_t p1 = read(base+1);
282 
283  return f32pair_linint(frac, p0, p1);
284  }
285 
293  inline __attribute__((optimize("Ofast"),always_inline))
294  f32pair_t readFracz(const uint32_t pos, const float frac) {
295  const f32pair_t p0 = read(pos);
296  const f32pair_t y = f32pair_linint(frac, p0, mFracZ);
297  mFracZ = p0;
298  return y;
299  }
300 
307  inline __attribute__((optimize("Ofast"),always_inline))
308  float read0(const uint32_t pos) {
309  return (mLine[(mWriteIdx + pos) & mMask]).a;
310  }
311 
318  inline __attribute__((optimize("Ofast"),always_inline))
319  float read1(const uint32_t pos) {
320  return (mLine[(mWriteIdx + pos) & mMask]).b;
321  }
322 
329  inline __attribute__((optimize("Ofast"),always_inline))
330  float read0Frac(const float pos) {
331  const int32_t base = (uint32_t)pos;
332  const float frac = pos - base;
333  const float f0 = read0(base);
334  const float f1 = read0(base+1);
335  return linintf(frac, f0, f1);
336  }
337 
345  inline __attribute__((optimize("Ofast"),always_inline))
346  float read0Fracz(const uint32_t pos, const float frac) {
347  const float f0 = read0(pos);
348  const float y = linintf(frac, f0, mFracZ.a);
349  mFracZ.a = f0;
350  return y;
351  }
352 
359  inline __attribute__((optimize("Ofast"),always_inline))
360  float read1Frac(const float pos) {
361  const int32_t base = (uint32_t)pos;
362  const float frac = pos - base;
363  const float f0 = read1(base);
364  const float f1 = read1(base+1);
365  return linintf(frac, f0, f1);
366  }
367 
375  inline __attribute__((optimize("Ofast"),always_inline))
376  float read1Fracz(const uint32_t pos, const float frac) {
377  const float f0 = read1(pos);
378  const float y = linintf(frac, f0, mFracZ.b);
379  mFracZ.b = f0;
380  return y;
381  }
382 
383  /*===========================================================================*/
384  /* Member Variables. */
385  /*===========================================================================*/
386 
387  f32pair_t *mLine;
388  f32pair_t mFracZ;
389  size_t mSize;
390  size_t mMask;
391  uint32_t mWriteIdx;
392 
393  };
394 
395 
396 }
397 
f32pair_linint
static f32pair_t f32pair_linint(const float fr, const f32pair_t p0, const f32pair_t p1)
Pair-wise linear interpolation.
Definition: float_math.h:262
dsp::DualDelayLine::write
void write(const f32pair_t &p)
Write a sample pair to the delay line.
Definition: delayline.hpp:255
dsp::DualDelayLine::clear
void clear(void)
Zero clear the whole delay line.
Definition: delayline.hpp:229
dsp::DualDelayLine::DualDelayLine
DualDelayLine(f32pair_t *ram, size_t line_size)
Constructor with explicit memory area to use as backing buffer for delay line.
Definition: delayline.hpp:215
int_math.h
Integer Math Utilities.
dsp::DualDelayLine::read1
float read1(const uint32_t pos)
Read a single sample from the delay line's secondary channel at given position from current write ind...
Definition: delayline.hpp:319
dsp::DelayLine::clear
void clear(void)
Zero clear the whole delay line.
Definition: delayline.hpp:100
float_math.h
Floating Point Math Utilities.
dsp::DelayLine::readFracz
float readFracz(const uint32_t pos, const float frac)
Read a sample from the delay line at a position from current write index with interpolation from last...
Definition: delayline.hpp:164
dsp::DelayLine::write
void write(const float s)
Write a single sample to the head of the delay line.
Definition: delayline.hpp:126
dsp::DelayLine
Basic delay line abstraction.
Definition: delayline.hpp:56
dsp::DualDelayLine::DualDelayLine
DualDelayLine(void)
Default constructor.
Definition: delayline.hpp:200
dsp::DualDelayLine::read0Frac
float read0Frac(const float pos)
Read a single sample from the delay line's primary channel at a fractional position from current writ...
Definition: delayline.hpp:330
dsp::DelayLine::readFrac
float readFrac(const float pos)
Read a sample from the delay line at a fractional position from current write index.
Definition: delayline.hpp:148
buffer_ops.h
Operations over data buffers.
dsp::DualDelayLine::read
f32pair_t read(const uint32_t pos)
Read a sample pair from the delay line at given position from current write index.
Definition: delayline.hpp:266
dsp::DualDelayLine::read1Fracz
float read1Fracz(const uint32_t pos, const float frac)
Read a single sample from the delay line's secondary channel at a position from current write index w...
Definition: delayline.hpp:376
buf_clr_f32
static void buf_clr_f32(float *__restrict__ ptr, const uint32_t len)
Buffer clear (float version)
Definition: buffer_ops.h:104
dsp::DualDelayLine::readFracz
f32pair_t readFracz(const uint32_t pos, const float frac)
Read a sample pair from the delay line at a position from current write index with interpolation from...
Definition: delayline.hpp:294
dsp::DualDelayLine::read0Fracz
float read0Fracz(const uint32_t pos, const float frac)
Read a single sample from the delay line's primary channel at a position from current write index wit...
Definition: delayline.hpp:346
nextpow2_u32
static uint32_t nextpow2_u32(uint32_t x)
Compute next power of 2 greater than x.
Definition: int_math.h:117
dsp::DualDelayLine
Dual channel delay line abstraction with interleaved samples.
Definition: delayline.hpp:187
dsp::DelayLine::setMemory
void setMemory(float *ram, size_t line_size)
Set the memory area to use as backing buffer for the delay line.
Definition: delayline.hpp:113
dsp::DelayLine::read
float read(const uint32_t pos)
Read a single sample from the delay line at given position from current write index.
Definition: delayline.hpp:137
dsp
Common DSP Utilities.
Definition: biquad.hpp:49
dsp::DelayLine::DelayLine
DelayLine(float *ram, size_t line_size)
Constructor with explicit memory area to use as backing buffer for delay line.
Definition: delayline.hpp:84
dsp::DelayLine::DelayLine
DelayLine(void)
Default constructor.
Definition: delayline.hpp:69
f32pair_t
Definition: float_math.h:166
dsp::DualDelayLine::read1Frac
float read1Frac(const float pos)
Read a single sample from the delay line's secondary channel at a fractional position from current wr...
Definition: delayline.hpp:360
linintf
static float linintf(const float fr, const float x0, const float x1)
Linear interpolation.
Definition: float_math.h:824
dsp::DualDelayLine::setMemory
void setMemory(f32pair_t *ram, size_t line_size)
Set the memory area to use as backing buffer for the delay line.
Definition: delayline.hpp:242
dsp::DualDelayLine::read0
float read0(const uint32_t pos)
Read a single sample from the delay line's primary channel at given position from current write index...
Definition: delayline.hpp:308
dsp::DualDelayLine::readFrac
f32pair_t readFrac(const float pos)
Read a sample pair from the delay line at a fractional position from current write index.
Definition: delayline.hpp:277