24#include "WrappedAudioOutputBase.h"
25#include "BackgroundAudioGain.h"
26#include "BackgroundAudioBuffers.h"
27#include "libespeak-ng/espeak-ng/speak_lib.h"
28#include "libespeak-ng/phoneme/phonindex.h"
29#include "libespeak-ng/phoneme/phontab.h"
30#include "libespeak-ng/phoneme/phondata.h"
31#include "libespeak-ng/phoneme/intonations.h"
34extern const unsigned char __espeakng_dict[];
35extern size_t __espeakng_dictlen;
55template<
class DataBuffer>
99 _gain = (int32_t)(scale * (1 << 16));
118 espeak_SetParameter(espeakRATE, rate, 0);
127 espeak_SetParameter(espeakPITCH, pitch, 0);
136 espeak_SetParameter(espeakWORDGAP, gap, 0);
145 if (_playing || !_voice || !_voiceLen) {
149 espeak_EnableSingleStep();
150 espeak_InstallDict(__espeakng_dict, __espeakng_dictlen);
151 espeak_InstallPhonIndex(_phonindex,
sizeof(_phonindex));
152 espeak_InstallPhonTab(_phontab,
sizeof(_phontab));
153 espeak_InstallPhonData(_phondata,
sizeof(_phondata));
154 espeak_InstallIntonations(_intonations,
sizeof(_intonations));
155 espeak_InstallVoice(_voice, _voiceLen);
157 int samplerate = espeak_Initialize(AUDIO_OUTPUT_SYNCH_PLAYBACK, 20,
nullptr, 0);
158 espeak_SetVoiceByFile(
"INTERNAL");
159 espeak_SetSynthCallback(_speechCB);
162 _out->setBuffers(5, framelen);
163 _out->onTransmit(&_cb, (
void *)
this);
164 _out->setBitsPerSample(16);
165 _out->setStereo(
true);
166 _out->setFrequency(samplerate);
170 uint16_t zeros[32] __attribute__((aligned(4))) = {};
171 while (_out->availableForWrite() > 32) {
172 _out->write((uint8_t *)zeros,
sizeof(zeros));
217 size_t write(
const void *data,
size_t len) {
218 return _ib.write((
const uint8_t *)data, len);
231 return write((
const void *)
string, strlen(
string) + 1);
240 size_t speak(
const String &
string) {
241 return speak(
string.c_str());
257 return _ib.availableForWrite();
266 return _ib.available();
275 return !
available() && !_generatingSpeech;
357 _generatingSpeech =
false;
359 espeak_SynthesizeOneStep(&mono);
360 espeak_AbortSynthesis();
365 static void _cb(
void *ptr) {
369 static int _speechCB(
short *data,
int count, espeak_EVENT *events) {
373 void generateOneFrame() {
377 if (!_generatingSpeech) {
378 if (_ib.available()) {
379 const uint8_t *b = _ib.buffer();
380 for (
int i = 0; i < (int)_ib.available(); i++) {
382 espeak_Synth(_ib.buffer(), i, 0, (espeak_POSITION_TYPE)0, 0, espeakCHARS_AUTO, 0,
this);
383 _generatingSpeech =
true;
390 if (_generatingSpeech && !_frameLen) {
393 _frameLen = std::min(espeak_SynthesizeOneStep(&mono), framelen);
395 int16_t *ptr = _frame;
396 for (
int i = 0; i < _frameLen; i++) {
401 ApplyGain(_frame, _frameLen * 2, _gain);
403 if (!espeak_SynthesisGenerateNext()) {
404 _generatingSpeech =
false;
405 _ib.shiftUp(strlen((
const char *)_ib.buffer()) + 1);
412 while (_out->availableForWrite() >= (
int)framelen) {
413 if (!_frameLen && !_paused) {
416 if (_paused || !_frameLen) {
417 bzero(_frame,
sizeof(_frame));
418 _out->write((uint8_t *)_frame,
sizeof(_frame));
420 _frameLen -= _out->write((uint8_t *)_frame, _frameLen * 4) / 4;
426 AudioOutputBase *_out;
427 bool _playing =
false;
428 bool _paused =
false;
430 int32_t _gain = 1 << 16;
431 bool _generatingSpeech =
false;
432 static constexpr int framelen = 1324;
433 int16_t _frame[framelen * 2];
436 const unsigned char *_dict;
438 const unsigned char *_voice;
442 uint32_t _frames = 0;
443 uint32_t _shifts = 0;
444 uint32_t _underflows = 0;
445 uint32_t _errors = 0;
Interrupt-driven ESpeak-NG instance. Generates a full frame of samples each cycle and uses the RawBuf...
Definition BackgroundAudioSpeech.h:56
bool done()
Determine if no more speech is present in the buffer.
Definition BackgroundAudioSpeech.h:274
void setWordGap(int gap)
Adjust the interword gap after begin()
Definition BackgroundAudioSpeech.h:135
uint32_t underflows()
Get the number of times the speaker has underflowed waiting on raw data since begin
Definition BackgroundAudioSpeech.h:301
bool playing()
Determines if the speaker has been started.
Definition BackgroundAudioSpeech.h:195
size_t speak(const char *string)
Speaks a C-String.
Definition BackgroundAudioSpeech.h:227
BackgroundAudioSpeechClass(AudioOutputBase &d)
Construct an output device using the specified physical audio output.
Definition BackgroundAudioSpeech.h:70
bool setDevice(AudioOutputBase *d)
Set an output device before begin
Definition BackgroundAudioSpeech.h:85
bool paused()
Determine if the playback is paused.
Definition BackgroundAudioSpeech.h:335
uint32_t shifts()
Get the number of input data shifts processed by decoder since begin
Definition BackgroundAudioSpeech.h:292
void setPitch(int pitch)
Adjust the pitch, 0...99, with 50 default. After begin()
Definition BackgroundAudioSpeech.h:126
void pause()
Pause the decoder. Won't process raw input data and will transmit silence.
Definition BackgroundAudioSpeech.h:326
uint32_t frames()
Get number of "frames" processed by speaker.
Definition BackgroundAudioSpeech.h:283
uint32_t dumps()
Get the number of full buffer dumps (catastrophic data error) since begin
Definition BackgroundAudioSpeech.h:319
size_t availableForWrite()
Gets number of bytes available to write to raw buffer.
Definition BackgroundAudioSpeech.h:256
void unpause()
Unpause previously paused playback. Will start processing input data again.
Definition BackgroundAudioSpeech.h:343
bool begin()
Starts the background speaker. Will initialize the output device and start sending silence immediatel...
Definition BackgroundAudioSpeech.h:144
size_t available()
Gets number of bytes already in the raw buffer.
Definition BackgroundAudioSpeech.h:265
size_t speak(const String &string)
Speaks an Arduino String.
Definition BackgroundAudioSpeech.h:240
void setRate(int rate)
Set the speaking rate in ~wpm, after calling begin()
Definition BackgroundAudioSpeech.h:117
void end()
Stops the process and the calls the output device's end to shut it down, too.
Definition BackgroundAudioSpeech.h:183
size_t write(const void *data, size_t len)
Writes a block of raw data to the decoder's buffer.
Definition BackgroundAudioSpeech.h:217
void setVoice(BackgroundAudioVoice &v)
Sets the voice parameters (language customization)
Definition BackgroundAudioSpeech.h:107
void flush()
Flushes any existing raw data, resets the processor to start a new speaking.
Definition BackgroundAudioSpeech.h:354
void setGain(float scale)
Set the gain multiplier (volume) for the stream. Takes effect immediately.
Definition BackgroundAudioSpeech.h:98
uint32_t errors()
Get the number of decoder errors since begin
Definition BackgroundAudioSpeech.h:310
Structure to collect a ESpeak-NG voice with its human-readable name.
Definition BackgroundAudioSpeech.h:40
const char * name
Definition BackgroundAudioSpeech.h:42
const unsigned char * data
Definition BackgroundAudioSpeech.h:46
size_t len
Definition BackgroundAudioSpeech.h:44