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  This file is part of FabGL Library.
7 
8  FabGL is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  FabGL is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with FabGL. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 
23 #pragma once
24 
25 
35 #include <stdint.h>
36 #include <stddef.h>
37 
38 #include "freertos/FreeRTOS.h"
39 
40 #include "fabglconf.h"
41 #include "fabutils.h"
42 
43 
44 
45 namespace fabgl {
46 
47 
48 #define DEFAULT_SAMPLE_RATE 16000
49 
50 // 512 samples, at 16KHz generate a send every 512/16000*1000 = 32ms (16000/512=31.25 sends per second)
51 // 200 samples, at 16Khz generate a send every 200/16000*1000 = 12.5ms (16000/200=80 sends per second)
52 #define I2S_SAMPLE_BUFFER_SIZE 200 // must be even
53 
54 #define WAVEGENTASK_STACK_SIZE 2000
55 
56 
59 public:
60  WaveformGenerator() : next(nullptr), m_sampleRate(0), m_volume(100), m_enabled(false), m_duration(-1), m_autoDestroy(false), m_autoDetach(false) { }
61 
62  virtual ~WaveformGenerator() { }
63 
69  virtual void setFrequency(int value) = 0;
70 
76  void setDuration(uint32_t value) { m_duration = value; }
77 
83  uint32_t duration() { return m_duration; }
84 
90  void setAutoDetach(bool value) { m_autoDetach = value; }
91 
92  bool autoDetach() { return m_autoDetach; }
93 
99  void setAutoDestroy(bool value) { m_autoDestroy = value; m_autoDetach |= value; }
100 
101  bool autoDestroy() { return m_autoDestroy; }
102 
108  virtual int getSample() = 0;
109 
115  void setVolume(int value) { m_volume = value; }
116 
122  int volume() { return m_volume; }
123 
129  bool enabled() { return m_enabled; }
130 
138  void enable(bool value) { m_enabled = value; }
139 
147  void setSampleRate(int value) { m_sampleRate = value; }
148 
154  uint16_t sampleRate() { return m_sampleRate; }
155 
156  WaveformGenerator * next;
157 
158 protected:
159 
160  void decDuration() { --m_duration; if (m_duration == 0) m_enabled = false; }
161 
162 private:
163  uint16_t m_sampleRate;
164  int8_t m_volume;
165  int8_t m_enabled; // 0 = disabled, 1 = enabled
166  uint32_t m_duration; // number of samples to play (-1 = infinite)
167  bool m_autoDestroy; // if true: this object needs to be destroyed by the sound generator when there are no more samples to play
168  bool m_autoDetach; // if true: this object needs to be autodetached from the sound generator when there are no more samples to play
169 };
170 
171 
174 public:
176 
177  void setFrequency(int value);
178 
179  int getSample();
180 
181 private:
182  uint32_t m_phaseInc;
183  uint32_t m_phaseAcc;
184  uint16_t m_frequency;
185  int16_t m_lastSample;
186 };
187 
188 
191 public:
193 
194  void setFrequency(int value);
195 
201  void setDutyCycle(int dutyCycle);
202 
203  int getSample();
204 
205 private:
206  uint32_t m_phaseInc;
207  uint32_t m_phaseAcc;
208  uint16_t m_frequency;
209  int8_t m_lastSample;
210  uint8_t m_dutyCycle;
211 };
212 
213 
216 public:
218 
219  void setFrequency(int value);
220 
221  int getSample();
222 
223 private:
224  uint32_t m_phaseInc;
225  uint32_t m_phaseAcc;
226  uint16_t m_frequency;
227  int8_t m_lastSample;
228 };
229 
230 
233 public:
235 
236  void setFrequency(int value);
237 
238  int getSample();
239 
240 private:
241  uint32_t m_phaseInc;
242  uint32_t m_phaseAcc;
243  uint16_t m_frequency;
244  int8_t m_lastSample;
245 };
246 
247 
250 public:
252 
253  void setFrequency(int value);
254 
255  int getSample();
256 
257 private:
258  uint16_t m_noise;
259 };
260 
261 
263 // "tries" to emulate VIC6561 noise generator
264 // derived from a reverse enginnered VHDL code: http://www.denial.shamani.dk/bb/viewtopic.php?t=8733&start=210
265 
272 public:
274 
275  void setFrequency(int value);
276  uint16_t frequency() { return m_frequency; }
277 
278  int getSample();
279 
280 private:
281  static const uint16_t LFSRINIT = 0x0202;
282  static const int CLK = 4433618;
283 
284  uint16_t m_frequency;
285  uint16_t m_counter;
286  uint16_t m_LFSR;
287  uint16_t m_outSR;
288 };
289 
290 
291 
299 public:
300  SamplesGenerator(int8_t const * data, int length);
301 
302  void setFrequency(int value);
303 
304  int getSample();
305 
306 private:
307  int8_t const * m_data;
308  int m_length;
309  int m_index;
310 };
311 
312 
316 enum class SoundGeneratorState {
317  Stop,
318  RequestToPlay,
319  Playing,
320  RequestToStop,
321 };
322 
323 
341 
342 public:
343 
347  SoundGenerator(int sampleRate = DEFAULT_SAMPLE_RATE);
348 
349  ~SoundGenerator();
350 
354  void clear();
355 
367  bool play(bool value);
368 
382  SamplesGenerator * playSamples(int8_t const * data, int length, int volume = 100, int durationMS = 0);
383 
405  template <typename T>
406  void playSound(T const & waveform, int frequency, int durationMS, int volume = 100) {
407  auto wf = new T(waveform);
408  attach(wf);
409  wf->setFrequency(frequency);
410  wf->setVolume(volume);
411  wf->setAutoDestroy(true);
412  wf->setDuration(m_sampleRate / 1000 * durationMS);
413  wf->enable(true);
414  play(true);
415  }
416 
422  bool playing() { return m_play; }
423 
424  WaveformGenerator * channels() { return m_channels; }
425 
438  void attach(WaveformGenerator * value);
439 
445  void detach(WaveformGenerator * value);
446 
452  void setVolume(int value) { m_volume = value; }
453 
459  int volume() { return m_volume; }
460 
461 
462 private:
463 
464  void i2s_audio_init();
465  static void waveGenTask(void * arg);
466  bool forcePlay(bool value);
467  void mutizeOutput();
468  void detachNoSuspend(WaveformGenerator * value);
469  bool actualPlaying();
470 
471 
472  TaskHandle_t m_waveGenTaskHandle;
473 
474  WaveformGenerator * m_channels;
475 
476  uint16_t * m_sampleBuffer;
477 
478  int8_t m_volume;
479 
480  uint16_t m_sampleRate;
481 
482  bool m_play;
483  SoundGeneratorState m_state;
484  SemaphoreHandle_t m_mutex;
485 
486 };
487 
488 
489 
490 
491 } // end of namespace
492 
Noise generator.
Definition: soundgen.h:249
bool enabled()
Determines whether this generator is enabled or disabled.
Definition: soundgen.h:129
void setAutoDestroy(bool value)
Sets autodestroy mode.
Definition: soundgen.h:99
int getSample()
Gets next sample.
Definition: soundgen.cpp:160
SamplesGenerator * playSamples(int8_t const *data, int length, int volume=100, int durationMS=0)
Plays the specified samples.
Definition: soundgen.cpp:530
void playSound(T const &waveform, int frequency, int durationMS, int volume=100)
Plays the specified waveform.
Definition: soundgen.h:406
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:304
Samples generator.
Definition: soundgen.h:298
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:255
int getSample()
Gets next sample.
Definition: soundgen.cpp:211
Base abstract class for waveform generators. A waveform generator can be seen as an audio channel tha...
Definition: soundgen.h:58
Triangle waveform generator.
Definition: soundgen.h:215
int getSample()
Gets next sample.
Definition: soundgen.cpp:426
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:421
void setVolume(int value)
Sets the overall volume.
Definition: soundgen.h:452
uint8_t const * data
uint32_t duration()
Returns number of remaining samples to play.
Definition: soundgen.h:83
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:203
void attach(WaveformGenerator *value)
Attaches a waveform generator.
Definition: soundgen.cpp:576
void enable(bool value)
Enables or disabled this generator.
Definition: soundgen.h:138
void setAutoDetach(bool value)
Sets autodetach mode.
Definition: soundgen.h:90
void setSampleRate(int value)
Sets the sample rate.
Definition: soundgen.h:147
int getSample()
Gets next sample.
Definition: soundgen.cpp:359
void setDuration(uint32_t value)
Sets number of samples to play.
Definition: soundgen.h:76
bool playing()
Determines whether sound generator is playing.
Definition: soundgen.h:422
int volume()
Determines current overall volume.
Definition: soundgen.h:459
This file contains some utility classes and functions.
Definition: canvas.cpp:32
void clear()
Stops playing and removes all attached waveform generators.
Definition: soundgen.cpp:480
Sine waveform generator.
Definition: soundgen.h:173
void detach(WaveformGenerator *value)
Detaches a waveform generator.
Definition: soundgen.cpp:591
bool play(bool value)
Starts or stops playing.
Definition: soundgen.cpp:516
SoundGenerator handles audio output.
Definition: soundgen.h:340
Emulates VIC6561 (VIC20) noise generator.
Definition: soundgen.h:271
int getSample()
Gets next sample.
Definition: soundgen.cpp:263
void setVolume(int value)
Sets volume of this generator.
Definition: soundgen.h:115
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:348
int getSample()
Gets next sample.
Definition: soundgen.cpp:97
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:89
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:145
void setDutyCycle(int dutyCycle)
Sets square wave duty cycle.
Definition: soundgen.cpp:154
Sawtooth waveform generator.
Definition: soundgen.h:232
uint16_t sampleRate()
Determines the sample rate.
Definition: soundgen.h:154
int getSample()
Gets next sample.
Definition: soundgen.cpp:309
int volume()
Determines current volume.
Definition: soundgen.h:122
SoundGenerator(int sampleRate=16000)
Creates an instance of the sound generator. Only one instance is allowed.
Definition: soundgen.cpp:457
Square waveform generator.
Definition: soundgen.h:190
virtual void setFrequency(int value)=0
Sets output frequency.