OpenWareLaboratory
SampleOscillator.h
Go to the documentation of this file.
1 #ifndef __SampleOscillator_h
2 #define __SampleOscillator_h
3 
4 #include "Oscillator.h"
5 
6 template<InterpolationMethod im>
7 class SampleOscillator : public Oscillator {
8 public:
9  enum RepeatMode {
12  REPEAT_FORWARD = 1
13  };
14 private:
15  const float sr;
16  FloatArray buffer;
17  float pos = 0.0f;
18  size_t size;
19  float rate = 1.0f;
20  RepeatMode repeat_mode = REPEAT_NONE;
21  static constexpr float MIDDLE_C = 261.6;
22 public:
23 
24  SampleOscillator(float sr, FloatArray sample)
25  : sr(sr)
26  , buffer(sample), pos(0), size(sample.getSize() - 1) {}
27  void setFrequency(float freq) {
28  rate = copysignf(freq / MIDDLE_C, rate); // preserve sign
29  }
30  float getFrequency(){
31  return rate*MIDDLE_C;
32  }
33  void setSample(FloatArray sample){
34  buffer = sample;
35  size = sample.getSize() -1;
36  pos = 0;
37  }
39  return buffer;
40  }
42  repeat_mode = mode;
43  }
44  void reset() {
45  pos = 0;
46  }
47  float interpolate(float index, FloatArray data);
48  void setPhase(float phase){
49  pos = size*phase/(2*M_PI);
50  }
51  float getPhase(){
52  return pos*2*M_PI/size;
53  }
54  float generate(float fm) {
55  return generate();
56  }
57  float generate() {
58  if(pos < 0){
59  if(repeat_mode == REPEAT_REVERSE){
60  rate *= -1;
61  pos = 0;
62  }else{
63  return 0;
64  }
65  }else if(pos > size){
66  if(repeat_mode == REPEAT_FORWARD){
67  pos = 0;
68  }else if(repeat_mode == REPEAT_REVERSE){
69  rate *= -1;
70  pos = size;
71  }else{
72  return 0;
73  }
74  }
75  float sample = interpolate(pos, buffer);
76  pos += rate;
77  return sample;
78  }
79  void generate(FloatArray output){
80  size_t len = output.getSize();
81  float* dest = output;
82  if(rate > 0){
83  while(pos + rate*len > size){
84  float remain = size - pos;
85  size_t steps = (size_t)(remain/rate);
86  for(size_t i=0; i<steps; ++i){
87  *dest++ = interpolate(pos, buffer);
88  pos += rate;
89  }
90  len -= steps;
91  if(repeat_mode == REPEAT_FORWARD){
92  pos -= size;
93  }else if(repeat_mode == REPEAT_REVERSE){
94  rate *= -1;
95  pos = size;
96  }else{
97  return;
98  }
99  }
100  }else{
101  while(pos + rate*len < 0){
102  float remain = pos;
103  size_t steps = (size_t)(remain/rate);
104  for(size_t i=0; i<steps; ++i){
105  *dest++ = interpolate(pos, buffer);
106  pos += rate;
107  }
108  len -= steps;
109  if(repeat_mode == REPEAT_REVERSE){
110  rate *= -1;
111  pos = 0;
112  }else{
113  return;
114  }
115  }
116  }
117  for(size_t i=0; i<len; ++i){
118  *dest++ = interpolate(pos, buffer);
119  pos += rate;
120  }
121  }
122  void generate(FloatArray output, FloatArray fm){
123  return generate(output);
124  }
125  size_t findZeroCrossing(size_t index) {
126  size_t len = buffer.getSize()-1;
127  size_t i = min(index, len);
128  if (buffer[i] > 0)
129  while (i < len && buffer[i] > 0)
130  i++;
131  else
132  while (i < len && buffer[i] < 0)
133  i++;
134  return i;
135  }
136  void setDuration(float duration) {
137  size_t samples = duration * getSampleLength()+sr*0.025; // min 25 mS
138  size = findZeroCrossing(samples);
139  }
140  /* @return the audio length in samples */
141  size_t getSampleLength() {
142  return buffer.getSize();
143  }
144  static SampleOscillator* create(float sr, FloatArray buf) {
145  return new SampleOscillator(sr, buf);
146  }
147  static void destroy(SampleOscillator* obj) {
148  delete obj;
149  }
150 };
151 
152 template<>
154  size_t idx = (int)index;
155  float low = data[idx];
156  float high = data[idx + 1];
157  float frac = index - idx;
158  return Interpolator::linear(low, high, frac);
159 }
160 
161 template<>
163  size_t idx = (int)index;
164  return Interpolator::cosine(data[idx], data[idx + 1], index - idx);
165 }
166 
169 
170 #endif /* __SampleOscillator_h */
SampleOscillator< COSINE_INTERPOLATION > CosineSampleOscillator
SampleOscillator< LINEAR_INTERPOLATION > LinearSampleOscillator
#define min(a, b)
Definition: basicmaths.h:38
#define M_PI
Definition: basicmaths.h:52
This class contains useful methods for manipulating arrays of floats.
Definition: FloatArray.h:12
static float linear(float y1, float y2, float mu)
Definition: Interpolator.h:8
static float cosine(float y1, float y2, float mu)
Definition: Interpolator.h:11
An Oscillator is a SignalGenerator that operates at a given frequency and that can be frequency modul...
Definition: Oscillator.h:12
void generate(FloatArray output, FloatArray fm)
Produce a block of samples with frequency modulation.
static SampleOscillator * create(float sr, FloatArray buf)
SampleOscillator(float sr, FloatArray sample)
void setDuration(float duration)
static void destroy(SampleOscillator *obj)
void generate(FloatArray output)
Produce a block of samples.
float getPhase()
Get current oscillator phase in radians.
float getFrequency()
Get oscillator frequency in Hertz.
float generate()
Produce the next consecutive sample.
FloatArray getSample()
size_t findZeroCrossing(size_t index)
void setFrequency(float freq)
Set oscillator frequency in Hertz.
void setPhase(float phase)
Set current oscillator phase in radians.
float generate(float fm)
Produce a sample with frequency modulation.
void setSample(FloatArray sample)
void setRepeatMode(RepeatMode mode)
void reset()
Reset oscillator (typically resets phase)
float interpolate(float index, FloatArray data)
size_t getSize() const
Definition: SimpleArray.h:31