FabGL
ESP32 Display Controller and Graphics Library
soundgen.h
Go to the documentation of this file.
1 /*
2  Created by Fabrizio Di Vittorio (fdivitto2013@gmail.com) - <http://www.fabgl.com>
3  Copyright (c) 2019-2021 Fabrizio Di Vittorio.
4  All rights reserved.
5 
6 
7 * Please contact fdivitto2013@gmail.com if you need a commercial license.
8 
9 
10 * This library and related software is available under GPL v3.
11 
12  FabGL is free software: you can redistribute it and/or modify
13  it under the terms of the GNU General Public License as published by
14  the Free Software Foundation, either version 3 of the License, or
15  (at your option) any later version.
16 
17  FabGL is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  GNU General Public License for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with FabGL. If not, see <http://www.gnu.org/licenses/>.
24  */
25 
26 
27 #pragma once
28 
29 
39 #include <stdint.h>
40 #include <stddef.h>
41 
42 #include "freertos/FreeRTOS.h"
43 
44 #include "fabglconf.h"
45 #include "fabutils.h"
46 
47 
48 
49 namespace fabgl {
50 
51 
52 #define DEFAULT_SAMPLE_RATE 16000
53 
54 // 512 samples, at 16KHz generate a send every 512/16000*1000 = 32ms (16000/512=31.25 sends per second)
55 // 200 samples, at 16Khz generate a send every 200/16000*1000 = 12.5ms (16000/200=80 sends per second)
56 #define I2S_SAMPLE_BUFFER_SIZE 200 // must be even
57 
58 #define WAVEGENTASK_STACK_SIZE 2000
59 
60 
63 public:
64  WaveformGenerator() : next(nullptr), m_sampleRate(0), m_volume(100), m_enabled(false), m_duration(-1), m_autoDestroy(false), m_autoDetach(false) { }
65 
66  virtual ~WaveformGenerator() { }
67 
73  virtual void setFrequency(int value) = 0;
74 
80  void setDuration(uint32_t value) { m_duration = value; }
81 
87  uint32_t duration() { return m_duration; }
88 
94  void setAutoDetach(bool value) { m_autoDetach = value; }
95 
96  bool autoDetach() { return m_autoDetach; }
97 
103  void setAutoDestroy(bool value) { m_autoDestroy = value; m_autoDetach |= value; }
104 
105  bool autoDestroy() { return m_autoDestroy; }
106 
112  virtual int getSample() = 0;
113 
119  void setVolume(int value) { m_volume = value; }
120 
126  int volume() { return m_volume; }
127 
133  bool enabled() { return m_enabled; }
134 
142  void enable(bool value) { m_enabled = value; }
143 
151  void setSampleRate(int value) { m_sampleRate = value; }
152 
158  uint16_t sampleRate() { return m_sampleRate; }
159 
160  WaveformGenerator * next;
161 
162 protected:
163 
164  void decDuration() { --m_duration; if (m_duration == 0) m_enabled = false; }
165 
166 private:
167  uint16_t m_sampleRate;
168  int8_t m_volume;
169  int8_t m_enabled; // 0 = disabled, 1 = enabled
170  uint32_t m_duration; // number of samples to play (-1 = infinite)
171  bool m_autoDestroy; // if true: this object needs to be destroyed by the sound generator when there are no more samples to play
172  bool m_autoDetach; // if true: this object needs to be autodetached from the sound generator when there are no more samples to play
173 };
174 
175 
178 public:
180 
181  void setFrequency(int value);
182 
183  int getSample();
184 
185 private:
186  uint32_t m_phaseInc;
187  uint32_t m_phaseAcc;
188  uint16_t m_frequency;
189  int16_t m_lastSample;
190 };
191 
192 
195 public:
197 
198  void setFrequency(int value);
199 
205  void setDutyCycle(int dutyCycle);
206 
207  int getSample();
208 
209 private:
210  uint32_t m_phaseInc;
211  uint32_t m_phaseAcc;
212  uint16_t m_frequency;
213  int8_t m_lastSample;
214  uint8_t m_dutyCycle;
215 };
216 
217 
220 public:
222 
223  void setFrequency(int value);
224 
225  int getSample();
226 
227 private:
228  uint32_t m_phaseInc;
229  uint32_t m_phaseAcc;
230  uint16_t m_frequency;
231  int8_t m_lastSample;
232 };
233 
234 
237 public:
239 
240  void setFrequency(int value);
241 
242  int getSample();
243 
244 private:
245  uint32_t m_phaseInc;
246  uint32_t m_phaseAcc;
247  uint16_t m_frequency;
248  int8_t m_lastSample;
249 };
250 
251 
254 public:
256 
257  void setFrequency(int value);
258 
259  int getSample();
260 
261 private:
262  uint16_t m_noise;
263 };
264 
265 
267 // "tries" to emulate VIC6561 noise generator
268 // derived from a reverse enginnered VHDL code: http://www.denial.shamani.dk/bb/viewtopic.php?t=8733&start=210
269 
276 public:
278 
279  void setFrequency(int value);
280  uint16_t frequency() { return m_frequency; }
281 
282  int getSample();
283 
284 private:
285  static const uint16_t LFSRINIT = 0x0202;
286  static const int CLK = 4433618;
287 
288  uint16_t m_frequency;
289  uint16_t m_counter;
290  uint16_t m_LFSR;
291  uint16_t m_outSR;
292 };
293 
294 
295 
303 public:
304  SamplesGenerator(int8_t const * data, int length);
305 
306  void setFrequency(int value);
307 
308  int getSample();
309 
310 private:
311  int8_t const * m_data;
312  int m_length;
313  int m_index;
314 };
315 
316 
320 enum class SoundGeneratorState {
321  Stop,
322  RequestToPlay,
323  Playing,
324  RequestToStop,
325 };
326 
327 
345 
346 public:
347 
351  SoundGenerator(int sampleRate = DEFAULT_SAMPLE_RATE);
352 
353  ~SoundGenerator();
354 
358  void clear();
359 
371  bool play(bool value);
372 
386  SamplesGenerator * playSamples(int8_t const * data, int length, int volume = 100, int durationMS = 0);
387 
409  template <typename T>
410  void playSound(T const & waveform, int frequency, int durationMS, int volume = 100) {
411  auto wf = new T(waveform);
412  attach(wf);
413  wf->setFrequency(frequency);
414  wf->setVolume(volume);
415  wf->setAutoDestroy(true);
416  wf->setDuration(m_sampleRate / 1000 * durationMS);
417  wf->enable(true);
418  play(true);
419  }
420 
426  bool playing() { return m_play; }
427 
428  WaveformGenerator * channels() { return m_channels; }
429 
442  void attach(WaveformGenerator * value);
443 
449  void detach(WaveformGenerator * value);
450 
456  void setVolume(int value) { m_volume = value; }
457 
463  int volume() { return m_volume; }
464 
465 
466 private:
467 
468  void i2s_audio_init();
469  static void waveGenTask(void * arg);
470  bool forcePlay(bool value);
471  void mutizeOutput();
472  void detachNoSuspend(WaveformGenerator * value);
473  bool actualPlaying();
474 
475 
476  TaskHandle_t m_waveGenTaskHandle;
477 
478  WaveformGenerator * m_channels;
479 
480  uint16_t * m_sampleBuffer;
481 
482  int8_t m_volume;
483 
484  uint16_t m_sampleRate;
485 
486  bool m_play;
487  SoundGeneratorState m_state;
488  SemaphoreHandle_t m_mutex;
489 
490 };
491 
492 
493 
494 
495 } // end of namespace
496 
Noise generator.
Definition: soundgen.h:253
bool enabled()
Determines whether this generator is enabled or disabled.
Definition: soundgen.h:133
void setAutoDestroy(bool value)
Sets autodestroy mode.
Definition: soundgen.h:103
int getSample()
Gets next sample.
Definition: soundgen.cpp:164
SamplesGenerator * playSamples(int8_t const *data, int length, int volume=100, int durationMS=0)
Plays the specified samples.
Definition: soundgen.cpp:534
void playSound(T const &waveform, int frequency, int durationMS, int volume=100)
Plays the specified waveform.
Definition: soundgen.h:410
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:308
Samples generator.
Definition: soundgen.h:302
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:259
int getSample()
Gets next sample.
Definition: soundgen.cpp:215
Base abstract class for waveform generators. A waveform generator can be seen as an audio channel tha...
Definition: soundgen.h:62
Triangle waveform generator.
Definition: soundgen.h:219
int getSample()
Gets next sample.
Definition: soundgen.cpp:430
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:425
void setVolume(int value)
Sets the overall volume.
Definition: soundgen.h:456
uint8_t const * data
uint32_t duration()
Returns number of remaining samples to play.
Definition: soundgen.h:87
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:207
void attach(WaveformGenerator *value)
Attaches a waveform generator.
Definition: soundgen.cpp:580
void enable(bool value)
Enables or disabled this generator.
Definition: soundgen.h:142
void setAutoDetach(bool value)
Sets autodetach mode.
Definition: soundgen.h:94
void setSampleRate(int value)
Sets the sample rate.
Definition: soundgen.h:151
int getSample()
Gets next sample.
Definition: soundgen.cpp:363
void setDuration(uint32_t value)
Sets number of samples to play.
Definition: soundgen.h:80
bool playing()
Determines whether sound generator is playing.
Definition: soundgen.h:426
int volume()
Determines current overall volume.
Definition: soundgen.h:463
This file contains some utility classes and functions.
Definition: canvas.cpp:36
void clear()
Stops playing and removes all attached waveform generators.
Definition: soundgen.cpp:484
Sine waveform generator.
Definition: soundgen.h:177
void detach(WaveformGenerator *value)
Detaches a waveform generator.
Definition: soundgen.cpp:595
bool play(bool value)
Starts or stops playing.
Definition: soundgen.cpp:520
SoundGenerator handles audio output.
Definition: soundgen.h:344
Emulates VIC6561 (VIC20) noise generator.
Definition: soundgen.h:275
int getSample()
Gets next sample.
Definition: soundgen.cpp:267
void setVolume(int value)
Sets volume of this generator.
Definition: soundgen.h:119
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:352
int getSample()
Gets next sample.
Definition: soundgen.cpp:101
virtual int getSample()=0
Gets next sample.
This file contains FabGL library configuration settings, like number of supported colors...
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:93
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:149
void setDutyCycle(int dutyCycle)
Sets square wave duty cycle.
Definition: soundgen.cpp:158
Sawtooth waveform generator.
Definition: soundgen.h:236
uint16_t sampleRate()
Determines the sample rate.
Definition: soundgen.h:158
int getSample()
Gets next sample.
Definition: soundgen.cpp:313
int volume()
Determines current volume.
Definition: soundgen.h:126
SoundGenerator(int sampleRate=16000)
Creates an instance of the sound generator. Only one instance is allowed.
Definition: soundgen.cpp:461
Square waveform generator.
Definition: soundgen.h:194
virtual void setFrequency(int value)=0
Sets output frequency.