ToneGenerator.h
Go to the documentation of this file.
1 /****
2  * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
3  * Created 2015 by Skurydin Alexey
4  * http://github.com/SmingHub/Sming
5  * All files of the Sming Core are provided under the LGPL v3 license.
6  *
7  * ToneGenerator.h - Tone generation via I2S
8  *
9  * @author Sept 2019 mikee47 <mike@sillyhouse.net>
10  *
11  ****/
12 
13 #pragma once
14 
16 #include <WString.h>
17 #include <driver/i2s.h>
18 
19 #define TG_VOICE_MAP(XX) \
20  XX(Sine) \
21  XX(Triangular) \
22  XX(Sawtooth) \
23  XX(Square)
24 
25 #define TG_EFFECT_MAP(XX) \
26  XX(Normal) \
27  XX(Mute) \
28  XX(FadeIn) \
29  XX(FadeOut)
30 
43 {
44 public:
45  enum class Voice {
46 #define XX(t) t,
48 #undef XX
49  MAX
50  };
51 
52  enum class ToneEffect {
53 #define XX(t) t,
55 #undef XX
56  };
57 
58  static String getVoiceName(Voice voice);
59  static String getEffectName(ToneEffect effect);
60 
62  {
63  end();
64  }
65 
71  bool begin(unsigned sampleRate);
72 
77  void end();
78 
82  bool start();
83 
88  void stop();
89 
90  bool isStarted()
91  {
92  return started;
93  }
94 
103  ToneBuffer* createTone(Voice voice, unsigned frequency, ToneEffect effect, unsigned repeatCount = 0);
104 
111  void queueTone(Voice voice, unsigned frequency);
112 
117  {
118  transition.append(pending);
119  }
120 
121 private:
122  ToneBuffer* allocateBuffer(unsigned sampleCount);
123  int16_t getSampleValue(Voice voice, unsigned pos, unsigned sampleCount, int16_t amplitude);
124  static void IRAM_ATTR i2sCallback(void* param, i2s_event_type_t event);
125  void IRAM_ATTR i2sWrite();
126  bool IRAM_ATTR i2sWriteBuffer(ToneBuffer* buffer, bool end);
127 
128 private:
129  unsigned sampleRate;
130  unsigned curFreq = 0;
131  static constexpr uint8_t fadeCycles = 2;
132  static constexpr uint8_t noteGapMs = 16;
133  // Three buffer queues
134  ToneBuffer* active = nullptr;
135  ToneBufferQueue pending;
136  ToneBufferQueue transition;
137  ToneBufferQueue unused;
138  unsigned offset = 0; // Read position in active buffer
139  bool started = false;
140 };
Definition: ToneBufferQueue.h:18
#define TG_EFFECT_MAP(XX)
Definition: ToneGenerator.h:25
ToneEffect
Definition: ToneGenerator.h:52
The String class.
Definition: WString.h:136
static String getVoiceName(Voice voice)
void submitPending()
Submit queued tone buffers for playback.
Definition: ToneGenerator.h:116
#define TG_VOICE_MAP(XX)
Definition: ToneGenerator.h:19
void end()
Stop playback and un-initialise I2S.
void queueTone(Voice voice, unsigned frequency)
Create a tone with appropriate filtering.
Contains samples for one full signal cycle at a specific frequency.
Definition: ToneBuffer.h:23
static String getEffectName(ToneEffect effect)
Generates tones with smooth transitions using Tone Buffers.
Definition: ToneGenerator.h:42
void append(ToneBuffer *buf)
ToneBuffer * createTone(Voice voice, unsigned frequency, ToneEffect effect, unsigned repeatCount=0)
Create a tone and queue it.
~ToneGenerator()
Definition: ToneGenerator.h:61
Voice
Definition: ToneGenerator.h:45
bool begin(unsigned sampleRate)
Initialise the tone generator and I2S.
bool isStarted()
Definition: ToneGenerator.h:90
void stop()
Stop tone playback and release any memory allocated for buffers.
bool start()
Start tone playback.