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#if __has_include("esp32/rom/lldesc.h")
45 #include "esp32/rom/lldesc.h"
46#else
47 #include "rom/lldesc.h"
48#endif
49#include "soc/i2s_struct.h"
50#include "soc/sens_struct.h"
51
52#include "fabglconf.h"
53#include "fabutils.h"
54
55
56
57namespace fabgl {
58
59
60#define FABGL_SOUNDGEN_DEFAULT_SAMPLE_RATE 16384
61
62
63// DAC mode specific:
64// setting 64 at 16KHz, generates 16000/64=250 interrupts per second
65#define FABGL_SOUNDGEN_SAMPLE_BUFFER_SIZE 64
66
67
68
71public:
72 WaveformGenerator() : next(nullptr), m_sampleRate(0), m_volume(100), m_enabled(false), m_duration(-1), m_autoDestroy(false), m_autoDetach(false) { }
73
74 virtual ~WaveformGenerator() { }
75
81 virtual void setFrequency(int value) = 0;
82
88 void setDuration(uint32_t value) { m_duration = value; }
89
95 uint32_t duration() { return m_duration; }
96
102 void setAutoDetach(bool value) { m_autoDetach = value; }
103
104 bool autoDetach() { return m_autoDetach; }
105
111 void setAutoDestroy(bool value) { m_autoDestroy = value; m_autoDetach |= value; }
112
113 bool autoDestroy() { return m_autoDestroy; }
114
120 virtual int getSample() = 0;
121
127 void setVolume(int value) { m_volume = value; }
128
134 int volume() { return m_volume; }
135
141 bool enabled() { return m_enabled; }
142
150 void enable(bool value) { m_enabled = value; }
151
159 void setSampleRate(int value) { m_sampleRate = value; }
160
166 uint16_t sampleRate() { return m_sampleRate; }
167
168 WaveformGenerator * next;
169
170protected:
171
172 void decDuration() { --m_duration; if (m_duration == 0) m_enabled = false; }
173
174private:
175 uint16_t m_sampleRate;
176 int8_t m_volume;
177 int8_t m_enabled; // 0 = disabled, 1 = enabled
178 uint32_t m_duration; // number of samples to play (-1 = infinite)
179 bool m_autoDestroy; // if true: this object needs to be destroyed by the sound generator when there are no more samples to play
180 bool m_autoDetach; // if true: this object needs to be autodetached from the sound generator when there are no more samples to play
181};
182
183
186public:
188
189 void setFrequency(int value);
190
191 int getSample();
192
193private:
194 uint32_t m_phaseInc;
195 uint32_t m_phaseAcc;
196 uint16_t m_frequency;
197 int16_t m_lastSample;
198};
199
200
203public:
205
206 void setFrequency(int value);
207
213 void setDutyCycle(int dutyCycle);
214
215 int getSample();
216
217private:
218 uint32_t m_phaseInc;
219 uint32_t m_phaseAcc;
220 uint16_t m_frequency;
221 int8_t m_lastSample;
222 uint8_t m_dutyCycle;
223};
224
225
228public:
230
231 void setFrequency(int value);
232
233 int getSample();
234
235private:
236 uint32_t m_phaseInc;
237 uint32_t m_phaseAcc;
238 uint16_t m_frequency;
239 int8_t m_lastSample;
240};
241
242
245public:
247
248 void setFrequency(int value);
249
250 int getSample();
251
252private:
253 uint32_t m_phaseInc;
254 uint32_t m_phaseAcc;
255 uint16_t m_frequency;
256 int8_t m_lastSample;
257};
258
259
262public:
264
265 void setFrequency(int value);
266
267 int getSample();
268
269private:
270 uint16_t m_noise;
271};
272
273
275// "tries" to emulate VIC6561 noise generator
276// derived from a reverse enginnered VHDL code: http://www.denial.shamani.dk/bb/viewtopic.php?t=8733&start=210
277
284public:
286
287 void setFrequency(int value);
288 uint16_t frequency() { return m_frequency; }
289
290 int getSample();
291
292private:
293 static const uint16_t LFSRINIT = 0x0202;
294 static const int CLK = 4433618;
295
296 uint16_t m_frequency;
297 uint16_t m_counter;
298 uint16_t m_LFSR;
299 uint16_t m_outSR;
300};
301
302
303
311public:
312 SamplesGenerator(int8_t const * data, int length);
313
314 void setFrequency(int value);
315
316 int getSample();
317
318private:
319 int8_t const * m_data;
320 int m_length;
321 int m_index;
322};
323
324
328enum class SoundGenMethod {
329 DAC,
330 SigmaDelta,
331 Auto,
332};
333
334
351
352public:
353
372 SoundGenerator(int sampleRate = FABGL_SOUNDGEN_DEFAULT_SAMPLE_RATE, gpio_num_t gpio = GPIO_AUTO, SoundGenMethod genMethod = SoundGenMethod::Auto);
373
375
379 void clear();
380
392 bool play(bool value);
393
407 SamplesGenerator * playSamples(int8_t const * data, int length, int volume = 100, int durationMS = 0);
408
430 template <typename T>
431 void playSound(T const & waveform, int frequency, int durationMS, int volume = 100) {
432 auto wf = new T(waveform);
433 attach(wf);
434 wf->setFrequency(frequency);
435 wf->setVolume(volume);
436 wf->setAutoDestroy(true);
437 wf->setDuration(m_sampleRate / 1000 * durationMS);
438 wf->enable(true);
439 play(true);
440 }
441
447 bool playing() { return m_play; }
448
449 WaveformGenerator * channels() { return m_channels; }
450
463 void attach(WaveformGenerator * value);
464
470 void detach(WaveformGenerator * value);
471
477 void setVolume(int value) { m_volume = value; }
478
484 int volume() { return m_volume; }
485
486
487private:
488
489 static void ISRHandler(void * arg); // used in DAC mode
490 static void timerHandler(void * args); // used in sigma-delta mode
491
492 void dac_init();
493 void sigmadelta_init();
494 void detachNoSuspend(WaveformGenerator * value);
495 void setDMANode(int index, volatile uint16_t * buf, int len);
496 void init();
497
498 int getSample();
499
500 #ifdef FABGL_EMULATED
501 void sdl_init();
502 static void SDLAudioCallback(void * data, Uint8 * buffer, int length);
503 #endif
504
505
506 WaveformGenerator * m_channels;
507
508 uint16_t * m_sampleBuffer[2];
509
510 int8_t m_volume;
511
512 uint16_t m_sampleRate;
513
514 bool m_play;
515
516 gpio_num_t m_gpio;
517
518 intr_handle_t m_isr_handle;
519
520 lldesc_t volatile * m_DMAChain;
521
522 SoundGenMethod m_genMethod;
523
524 bool m_initDone;
525
526 esp_timer_handle_t m_timerHandle;
527
528 #ifdef FABGL_EMULATED
529 SDL_AudioDeviceID m_device;
530 #endif
531
532};
533
534
535
536
537} // end of namespace
538
int getSample()
Gets next sample.
Definition: soundgen.cpp:308
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:303
int getSample()
Gets next sample.
Definition: soundgen.cpp:425
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:420
Samples generator.
Definition: soundgen.h:310
int getSample()
Gets next sample.
Definition: soundgen.cpp:262
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:254
Sawtooth waveform generator.
Definition: soundgen.h:244
int getSample()
Gets next sample.
Definition: soundgen.cpp:97
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:89
Sine waveform generator.
Definition: soundgen.h:185
void attach(WaveformGenerator *value)
Attaches a waveform generator.
Definition: soundgen.cpp:684
void detach(WaveformGenerator *value)
Detaches a waveform generator.
Definition: soundgen.cpp:697
SoundGenerator(int sampleRate=16384, gpio_num_t gpio=GPIO_AUTO, SoundGenMethod genMethod=SoundGenMethod::Auto)
Creates an instance of the sound generator. Only one instance is allowed.
Definition: soundgen.cpp:454
int volume()
Determines current overall volume.
Definition: soundgen.h:484
void setVolume(int value)
Sets the overall volume.
Definition: soundgen.h:477
SamplesGenerator * playSamples(int8_t const *data, int length, int volume=100, int durationMS=0)
Plays the specified samples.
Definition: soundgen.cpp:669
bool playing()
Determines whether sound generator is playing.
Definition: soundgen.h:447
bool play(bool value)
Starts or stops playing.
Definition: soundgen.cpp:644
void playSound(T const &waveform, int frequency, int durationMS, int volume=100)
Plays the specified waveform.
Definition: soundgen.h:431
void clear()
Stops playing and removes all attached waveform generators.
Definition: soundgen.cpp:497
SoundGenerator handles audio output.
Definition: soundgen.h:350
int getSample()
Gets next sample.
Definition: soundgen.cpp:159
void setDutyCycle(int dutyCycle)
Sets square wave duty cycle.
Definition: soundgen.cpp:153
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:144
Square waveform generator.
Definition: soundgen.h:202
int getSample()
Gets next sample.
Definition: soundgen.cpp:210
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:202
Triangle waveform generator.
Definition: soundgen.h:227
int getSample()
Gets next sample.
Definition: soundgen.cpp:358
void setFrequency(int value)
Sets output frequency.
Definition: soundgen.cpp:347
Emulates VIC6561 (VIC20) noise generator.
Definition: soundgen.h:283
void setAutoDestroy(bool value)
Sets autodestroy mode.
Definition: soundgen.h:111
void enable(bool value)
Enables or disabled this generator.
Definition: soundgen.h:150
int volume()
Determines current volume.
Definition: soundgen.h:134
virtual void setFrequency(int value)=0
Sets output frequency.
void setVolume(int value)
Sets volume of this generator.
Definition: soundgen.h:127
void setSampleRate(int value)
Sets the sample rate.
Definition: soundgen.h:159
uint32_t duration()
Returns number of remaining samples to play.
Definition: soundgen.h:95
void setDuration(uint32_t value)
Sets number of samples to play.
Definition: soundgen.h:88
uint16_t sampleRate()
Determines the sample rate.
Definition: soundgen.h:166
bool enabled()
Determines whether this generator is enabled or disabled.
Definition: soundgen.h:141
void setAutoDetach(bool value)
Sets autodetach mode.
Definition: soundgen.h:102
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:70
uint8_t const * data
This file contains FabGL library configuration settings, like number of supported colors,...
This file contains some utility classes and functions.
SoundGenMethod
Specifies sound generation method.
Definition: soundgen.h:328