Mozzi  version v2.0
sound synthesis library for Arduino
WavePacket.h
1 /*
2  * WavePacket.h
3  *
4  * This file is part of Mozzi.
5  *
6  * Copyright 2013-2024 Tim Barrass and the Mozzi Team
7  *
8  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
9  *
10  */
11 
12 
13 #ifndef WAVEPACKET_H
14 #define WAVEPACKET_H
15 
16 #include "MozziHeadersOnly.h"
17 #include "Oscil.h"
18 #include "tables/cos8192_int8.h"
19 #include "mozzi_fixmath.h"
20 #include "Phasor.h"
21 #include "Line.h"
22 #include "meta.h"
23 
24 
25 enum algorithms {SINGLE,DOUBLE};
26 
35 template <int8_t ALGORITHM>
37 {
38 public:
39 
42  WavePacket():AUDIO_STEPS_PER_CONTROL(MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE)
43  {
44  aCos.setTable(COS8192_DATA);
45  }
46 
47 
56  inline
57  void set(int fundamental, int bandwidth, int centrefreq)
58  {
59  setFundamental(fundamental);
60  setBandwidth(bandwidth);
61  setCentreFreq(centrefreq);
62  }
63 
64 
69  inline
70  void setFundamental(int fundamental)
71  {
72  aPhasor.setFreq(fundamental);
73  invFreq = Q8n24_FIX1 / fundamental;
74  }
75 
76 
77 
84  inline
85  void setBandwidth(int bandwidth)
86  {
87  Q15n16 bw = invFreq*bandwidth;
88  bw >>= 9;
89  bw = max(bw, Q15n16_FIX1>>3);
90  aBandwidth.set(bw, AUDIO_STEPS_PER_CONTROL);
91  }
92 
93 
94 
99  inline
100  void setCentreFreq(int centrefreq)
101  {
102  Q15n16 cf = invFreq * centrefreq;
103  cf >>= 3;
104  aCentrefreq.set(cf, AUDIO_STEPS_PER_CONTROL);
105  }
106 
107 
112  inline
113  int next()
114  {
115  gcentrefreq = aCentrefreq.next();
116  gbandwidth = aBandwidth.next();
117  int phase1 = aPhasor.next()>>16; // -0.5 to 0.5, 0n15
118  if (ALGORITHM == DOUBLE) {
119  return (signalPath(params1, phase1)+signalPath(params2, phase1+32768))>>1;
120  } else {
121  return signalPath(params1, phase1);
122  }
123  }
124 
125 
126 
127 private:
128  //Q15n16 fundamental; // range 4 to 6271 in pd patch, 13 integer bits
129  Q8n24 invFreq;
130  Q15n16 gcentrefreq; // range 0 to 3068, 12 integer bits
131  Q15n16 gbandwidth; // range 1 to 3068, 12 integer bits
132 
133  // Lines to interpolate controls at audio rate
134  Line <Q15n16> aCentrefreq;
135  Line <Q16n16> aBandwidth;
136  Line <Q16n16> aFreq;
137 
138  // different sets of params for each audio phase stream
139  struct parameters
140  {
141  int previous_phase;
142  Q15n16 centrefreq;
143  Q23n8 bandwidth;
144  }
145  params1,params2;
146 
147  // the number of audio steps the line has to take to reach the next control value
148  const unsigned int AUDIO_STEPS_PER_CONTROL;
149 
152 
153 
154  inline
155  int signalPath(struct parameters &param, int phase) // 25us? * 2
156  {
157  //setPin13High();
158  int index;
159 
160  if(phase<param.previous_phase)
161  {
162  param.centrefreq = gcentrefreq>>8;
163  param.bandwidth = Q15n16_to_Q23n8(gbandwidth);
164  }
165  param.previous_phase = phase;
166 
167  // oscillation
168  index = (param.centrefreq * phase)>>16;
169  // hack to make peak in middle of packet, otherwise it centres around a zero-crossing..
170  index += COS8192_NUM_CELLS>>1;
171  index &= COS8192_NUM_CELLS-1;
172  int8_t sig1 = aCos.atIndex(index);
173 
174  // packet envelope
175  Q23n8 bwphase = (param.bandwidth * phase)>>8;
176  bwphase += COS8192_NUM_CELLS>>1;
177  index = constrain(bwphase, 0, (COS8192_NUM_CELLS-1));
178  uint8_t packet_width = 128 + aCos.atIndex(index);
179  // if (AUDIO_MODE == HIFI){
180  // return ((int) sig1 * packet_width)>>3; // scaled to fit HIFI updateAudio output
181  // }else{
182  // return ((int) sig1 * packet_width)>>8; // scaled to fit STANDARD updateAudio output
183  // }
184 
185  return ((int) sig1 * packet_width);
186  }
187 
188 };
189 
194 #endif // #ifndef WAVEPACKET_H
This file provides declarations of the Mozzi Core Functions Mozzi functions, but no implementation.
T next()
Increments one step along the line.
Definition: Line.h:60
void set(T value)
Set the current value of the line.
Definition: Line.h:75
void setTable(const int8_t *TABLE_NAME)
Change the sound table which will be played by the Oscil.
Definition: Oscil.h:99
int8_t atIndex(unsigned int index)
Returns the sample at the given table index.
Definition: Oscil.h:333
uint32_t next()
Increments one step along the phase.
Definition: Phasor.h:46
void setFreq(int frequency)
Set the Phasor frequency with an unsigned int.
Definition: Phasor.h:68
Wavepacket synthesis, with two overlapping streams of wave packets.
Definition: WavePacket.h:37
WavePacket()
Constructor.
Definition: WavePacket.h:42
int next()
Calculate the next synthesised sample.
Definition: WavePacket.h:113
void setBandwidth(int bandwidth)
Set the bandwidth.
Definition: WavePacket.h:85
void set(int fundamental, int bandwidth, int centrefreq)
Set all the parameters for the synthesis.
Definition: WavePacket.h:57
void setCentreFreq(int centrefreq)
Set the centre frequency.
Definition: WavePacket.h:100
void setFundamental(int fundamental)
Set the fundamental frequency.
Definition: WavePacket.h:70
#define MOZZI_CONTROL_RATE
Control rate setting.
#define MOZZI_AUDIO_RATE
Defines the audio rate, i.e.
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767....
Definition: mozzi_fixmath.h:46
#define Q8n24_FIX1
1 in Q8n24 format
Definition: mozzi_fixmath.h:70
uint32_t Q8n24
signed fractional number using 8 integer bits and 24 fractional bits, represents 0 to 255....
Definition: mozzi_fixmath.h:50
Q23n8 Q15n16_to_Q23n8(Q15n16 a)
Convert Q15n16 fixed to Q23n8 signed int32_t.
#define Q15n16_FIX1
1 in Q15n16 format
Definition: mozzi_fixmath.h:69
int32_t Q23n8
signed fractional number using 23 integer bits and 8 fractional bits, represents -8388607....
Definition: mozzi_fixmath.h:45