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-2022 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
49namespace 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
63public:
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
162protected:
163
164 void decDuration() { --m_duration; if (m_duration == 0) m_enabled = false; }
165
166private:
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
178public:
180
181 void setFrequency(int value);
182
183 int getSample();
184
185private:
186 uint32_t m_phaseInc;
187 uint32_t m_phaseAcc;
188 uint16_t m_frequency;
189 int16_t m_lastSample;
190};
191
192
195public:
197
198 void setFrequency(int value);
199
205 void setDutyCycle(int dutyCycle);
206
207 int getSample();
208
209private:
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
220public:
222
223 void setFrequency(int value);
224
225 int getSample();
226
227private:
228 uint32_t m_phaseInc;
229 uint32_t m_phaseAcc;
230 uint16_t m_frequency;
231 int8_t m_lastSample;
232};
233
234
237public:
239
240 void setFrequency(int value);
241
242 int getSample();
243
244private:
245 uint32_t m_phaseInc;
246 uint32_t m_phaseAcc;
247 uint16_t m_frequency;
248 int8_t m_lastSample;
249};
250
251
254public:
256
257 void setFrequency(int value);
258
259 int getSample();
260
261private:
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
276public:
278
279 void setFrequency(int value);
280 uint16_t frequency() { return m_frequency; }
281
282 int getSample();
283
284private:
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
303public:
304 SamplesGenerator(int8_t const * data, int length);
305
306 void setFrequency(int value);
307
308 int getSample();
309
310private:
311 int8_t const * m_data;
312 int m_length;
313 int m_index;
314};
315
316
320enum class SoundGeneratorState {
321 Stop,
322 RequestToPlay,
323 Playing,
324 RequestToStop,
325};
326
327
345
346public:
347
351 SoundGenerator(int sampleRate = DEFAULT_SAMPLE_RATE);
352
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
466private:
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
int getSample()
Gets next sample.
Definition: soundgen.cpp:313
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:308
int getSample()
Gets next sample.
Definition: soundgen.cpp:430
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:425
Samples generator.
Definition: soundgen.h:302
int getSample()
Gets next sample.
Definition: soundgen.cpp:267
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:259
Sawtooth waveform generator.
Definition: soundgen.h:236
int getSample()
Gets next sample.
Definition: soundgen.cpp:101
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:93
Sine waveform generator.
Definition: soundgen.h:177
void attach(WaveformGenerator *value)
Attaches a waveform generator.
Definition: soundgen.cpp:580
void detach(WaveformGenerator *value)
Detaches a waveform generator.
Definition: soundgen.cpp:595
int volume()
Determines current overall volume.
Definition: soundgen.h:463
void setVolume(int value)
Sets the overall volume.
Definition: soundgen.h:456
SamplesGenerator * playSamples(int8_t const *data, int length, int volume=100, int durationMS=0)
Plays the specified samples.
Definition: soundgen.cpp:534
bool playing()
Determines whether sound generator is playing.
Definition: soundgen.h:426
SoundGenerator(int sampleRate=16000)
Creates an instance of the sound generator. Only one instance is allowed.
Definition: soundgen.cpp:461
bool play(bool value)
Starts or stops playing.
Definition: soundgen.cpp:520
void playSound(T const &waveform, int frequency, int durationMS, int volume=100)
Plays the specified waveform.
Definition: soundgen.h:410
void clear()
Stops playing and removes all attached waveform generators.
Definition: soundgen.cpp:484
SoundGenerator handles audio output.
Definition: soundgen.h:344
int getSample()
Gets next sample.
Definition: soundgen.cpp:164
void setDutyCycle(int dutyCycle)
Sets square wave duty cycle.
Definition: soundgen.cpp:158
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:149
Square waveform generator.
Definition: soundgen.h:194
int getSample()
Gets next sample.
Definition: soundgen.cpp:215
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:207
Triangle waveform generator.
Definition: soundgen.h:219
int getSample()
Gets next sample.
Definition: soundgen.cpp:363
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:352
Emulates VIC6561 (VIC20) noise generator.
Definition: soundgen.h:275
void setAutoDestroy(bool value)
Sets autodestroy mode.
Definition: soundgen.h:103
void enable(bool value)
Enables or disabled this generator.
Definition: soundgen.h:142
int volume()
Determines current volume.
Definition: soundgen.h:126
virtual void setFrequency(int value)=0
Sets output frequency.
void setVolume(int value)
Sets volume of this generator.
Definition: soundgen.h:119
void setSampleRate(int value)
Sets the sample rate.
Definition: soundgen.h:151
uint32_t duration()
Returns number of remaining samples to play.
Definition: soundgen.h:87
void setDuration(uint32_t value)
Sets number of samples to play.
Definition: soundgen.h:80
uint16_t sampleRate()
Determines the sample rate.
Definition: soundgen.h:158
bool enabled()
Determines whether this generator is enabled or disabled.
Definition: soundgen.h:133
void setAutoDetach(bool value)
Sets autodetach mode.
Definition: soundgen.h:94
virtual int getSample()=0
Gets next sample.
Base abstract class for waveform generators. A waveform generator can be seen as an audio channel tha...
Definition: soundgen.h:62
uint8_t const * data
This file contains FabGL library configuration settings, like number of supported colors,...
This file contains some utility classes and functions.