Mozzi  version 2015-05-11-20:23
sound synthesis library for Arduino
 All Classes Functions Typedefs Groups
WavePacket.h
1 /*
2  * WavePacket.h
3  *
4  * Copyright 2013 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12 
13 #ifndef WAVEPACKET_H
14 #define WAVEPACKET_H
15 
16 #include <MozziGuts.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(AUDIO_RATE / 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 
151  Phasor <AUDIO_RATE> aPhasor;
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
void set(T value)
Set the current value of the line.
Definition: Line.h:77
Q23n8 Q15n16_to_Q23n8(Q15n16 a)
Convert Q15n16 fixed to Q23n8 signed int32_t.
#define CONTROL_RATE
Control rate setting.
Definition: MozziGuts.h:36
void setCentreFreq(int centrefreq)
Set the centre frequency.
Definition: WavePacket.h:100
void setFreq(int frequency)
Set the Phasor frequency with an unsigned int.
Definition: Phasor.h:76
int next()
Calculate the next synthesised sample.
Definition: WavePacket.h:113
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767...
Definition: mozzi_fixmath.h:40
WavePacket()
Constructor.
Definition: WavePacket.h:42
void set(int fundamental, int bandwidth, int centrefreq)
Set all the parameters for the synthesis.
Definition: WavePacket.h:57
void setFundamental(int fundamental)
Set the fundamental frequency.
Definition: WavePacket.h:70
#define AUDIO_RATE
Holds the audio rate setting.
Definition: mozzi_config.h:61
void setTable(const int8_t *TABLE_NAME)
Change the sound table which will be played by the Oscil.
Definition: Oscil.h:103
int8_t atIndex(unsigned int index)
Returns the sample at the given table index.
Definition: Oscil.h:273
#define Q15n16_FIX1
1 in Q15n16 format
Definition: mozzi_fixmath.h:63
void setBandwidth(int bandwidth)
Set the bandwidth.
Definition: WavePacket.h:85
Wavepacket synthesis, with two overlapping streams of wave packets.
Definition: WavePacket.h:36
unsigned long next()
Increments one step along the phase.
Definition: Phasor.h:51
uint32_t Q8n24
signed fractional number using 8 integer bits and 24 fractional bits, represents 0 to 255...
Definition: mozzi_fixmath.h:44
#define Q8n24_FIX1
1 in Q8n24 format
Definition: mozzi_fixmath.h:64
int32_t Q23n8
signed fractional number using 23 integer bits and 8 fractional bits, represents -8388607.996 to 8388607.996
Definition: mozzi_fixmath.h:39
T next()
Increments one step along the line.
Definition: Line.h:59