From 8478d34daba70c5da429f22ddb841d74d7702a67 Mon Sep 17 00:00:00 2001 From: Phil Schatzmann Date: Wed, 16 Jun 2021 10:08:00 +0200 Subject: [PATCH 1/9] Support Callback --- TTS.cpp | 14 ++-- TTS.h | 37 ++++++++++ .../SpeakWithCallback/SpeakWithCallback.ino | 19 ++++++ sound.cpp | 32 ++++++++- sound.h | 67 +++++++++++++++++-- 5 files changed, 155 insertions(+), 14 deletions(-) create mode 100644 examples/SpeakWithCallback/SpeakWithCallback.ino diff --git a/TTS.cpp b/TTS.cpp index 6e2b744..f359346 100644 --- a/TTS.cpp +++ b/TTS.cpp @@ -16,7 +16,6 @@ #include "TTS.h" #include "english.h" -#include "sound.h" #define NUM_VOCAB sizeof(s_vocab)/sizeof(VOCAB) #define NUM_PHONEME sizeof(s_phonemes)/sizeof(PHONEME) @@ -319,14 +318,14 @@ static byte random2(void) return seed0; } -static byte playTone(int pin, byte soundNum, byte soundPos, char pitch1, char pitch2, byte count, byte volume) +byte TTS::playTone(int pin, byte soundNum, byte soundPos, char pitch1, char pitch2, byte count, byte volume) { const byte *soundData = &SoundData[soundNum * 0x40]; while (count-- > 0) { byte s = pgm_read_byte(&soundData[soundPos & 0x3fu]); - sound(pin, s & volume); + sound_api->sound(s & volume); pause(pitch1); - sound(pin, (s >> 4) & volume); + sound_api->sound((s >> 4) & volume); pause(pitch2); soundPos++; @@ -334,7 +333,7 @@ static byte playTone(int pin, byte soundNum, byte soundPos, char pitch1, char pi return soundPos & 0x3fu; } -static void play(int pin, byte duration, byte soundNumber) +void TTS::play(int pin, byte duration, byte soundNumber) { while (duration--) playTone(pin, soundNumber, random2(), 7, 7, 10, 15); @@ -346,6 +345,7 @@ static void play(int pin, byte duration, byte soundNumber) TTS::TTS(int p) { pin = p; + sound_api = new Sound(p); defaultPitch = 7; #ifdef __AVR__ pinMode(pin, OUTPUT); @@ -373,7 +373,7 @@ void TTS::sayPhonemes(const char *textp) if (phonemesToData(textp, s_phonemes)) { // phonemes has list of sound bytes - soundOn(pin); + sound_api->soundOn(); // initialise random number seed seed0 = 0xecu; @@ -543,7 +543,7 @@ void TTS::sayPhonemes(const char *textp) delay2(25); } // next phoneme } - soundOff(pin); + sound_api->soundOff(); } /* diff --git a/TTS.h b/TTS.h index 67ec9ea..1be006f 100644 --- a/TTS.h +++ b/TTS.h @@ -13,12 +13,42 @@ #ifndef _TTS_H_ #define _TTS_H_ +#include "sound.h" + +// acess to sound implementation, some methods are static so this needs to be static as well... + class TTS { public: + /** + * @brief Construct a new TTS object + * + * @param pin + */ TTS(int pin); + /** + * @brief Construct a new TTS object - Uses the Callback to provide the result + * + */ + TTS(data_callback_type cb, int len=512) { + sound_api = new SoundCallback(cb,len); + pin = -1; + defaultPitch = 7; + } + + /** + * @brief Destroy the TTS object + * + */ + ~TTS(){ + if(sound_api!=nullptr) { + delete sound_api; + } + } + + /** * speaks a string of (english) text */ @@ -39,9 +69,16 @@ class TTS { */ byte getPitch(void) { return defaultPitch; } + private: byte defaultPitch; int pin; + BaseSound *sound_api = nullptr; + + void play(int pin, byte duration, byte soundNumber); + byte playTone(int pin, byte soundNum, byte soundPos, char pitch1, char pitch2, byte count, byte volume); + + }; #endif diff --git a/examples/SpeakWithCallback/SpeakWithCallback.ino b/examples/SpeakWithCallback/SpeakWithCallback.ino new file mode 100644 index 0000000..c2037fb --- /dev/null +++ b/examples/SpeakWithCallback/SpeakWithCallback.ino @@ -0,0 +1,19 @@ + +#include "TTS.h" + +void data_callback(int len, byte *data){ + for (int j=0;jpin = pin; + } + void soundOff(); + void soundOn(); + void sound(byte b); + + private: + int pin; + +}; + +/** + * @brief Output to Callback + * + */ +class SoundCallback : public BaseSound { + public: + SoundCallback(data_callback_type callback, int len=512){ + // allocate result array + this->max_length = len; + this->callback = callback; + this->out_data = new byte[max_length]; + } + + ~SoundCallback(){ + delete[] out_data; + } + + void soundOff(); + void soundOn(); + void sound(byte b); + + private: + data_callback_type callback = nullptr; + byte *out_data = nullptr; + int max_length = 0; + int current_length = 0; + bool active = false; + +}; + #endif From 7f68fc4757d6f92465b04bb4efdf108afd9fa2a0 Mon Sep 17 00:00:00 2001 From: Phil Schatzmann Date: Wed, 16 Jun 2021 10:59:51 +0200 Subject: [PATCH 2/9] Default Pins --- README.md | 2 +- TTS.cpp | 13 +++++++++++++ TTS.h | 5 +++++ examples/Speak/Speak.ino | 19 +++++++++++++++++++ .../SpeakWithCallback/SpeakWithCallback.ino | 5 ++++- sound.cpp | 6 ++++++ sound.h | 19 ++++++++++++++++--- 7 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 examples/Speak/Speak.ino diff --git a/README.md b/README.md index 0dee32c..d7861b8 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ View this project on [CADLAB.io](https://cadlab.io/project/1281). ## Text-to-Speech Library for Arduino - checkout this project into your ``sketchbook/libraries`` folder -- requires an amplifier on the PWM output pin (see below) +- requires an amplifier on the PWM output pin (see below) or callback method - see [blog articles](http://programmablehardware.blogspot.ie/search/label/tts) ## Supported Hardware diff --git a/TTS.cpp b/TTS.cpp index f359346..daad84d 100644 --- a/TTS.cpp +++ b/TTS.cpp @@ -342,6 +342,19 @@ void TTS::play(int pin, byte duration, byte soundNumber) /****************************************************************************** * User API ******************************************************************************/ + + +TTS::TTS() +{ + pin = DEFAULT_PIN; + sound_api = new Sound(pin); + defaultPitch = 7; +#ifdef __AVR__ + pinMode(pin, OUTPUT); +#endif +} + + TTS::TTS(int p) { pin = p; diff --git a/TTS.h b/TTS.h index 1be006f..8a6a875 100644 --- a/TTS.h +++ b/TTS.h @@ -20,6 +20,11 @@ class TTS { public: + /** + * @brief Construct a new TTS object using the default pin + * + */ + TTS(); /** * @brief Construct a new TTS object diff --git a/examples/Speak/Speak.ino b/examples/Speak/Speak.ino new file mode 100644 index 0000000..05f655c --- /dev/null +++ b/examples/Speak/Speak.ino @@ -0,0 +1,19 @@ + +/** + * @brief Simple example which should work on most environments + */ + +#include "TTS.h" + + +// TTS tts(3); // with explicit pin +TTS tts; // with default pin + +void setup(){ + Serial.begin(115200); +} + +void loop(){ + tts.sayText("hallo"); + delay(5000); +} \ No newline at end of file diff --git a/examples/SpeakWithCallback/SpeakWithCallback.ino b/examples/SpeakWithCallback/SpeakWithCallback.ino index c2037fb..8628d95 100644 --- a/examples/SpeakWithCallback/SpeakWithCallback.ino +++ b/examples/SpeakWithCallback/SpeakWithCallback.ino @@ -1,4 +1,7 @@ - +/** + * @brief Example with Callback which just prints the result + * + */ #include "TTS.h" void data_callback(int len, byte *data){ diff --git a/sound.cpp b/sound.cpp index a635613..d626aaa 100644 --- a/sound.cpp +++ b/sound.cpp @@ -6,6 +6,12 @@ #define CHANNEL_FOR(p) (p == 25)? DAC_CHANNEL_1: DAC_CHANNEL_2 #endif +Sound::Sound(int pin) +{ + this->pin = pin; +} + + void Sound::soundOff() { diff --git a/sound.h b/sound.h index a1240aa..01a1f2a 100644 --- a/sound.h +++ b/sound.h @@ -3,6 +3,20 @@ #define PWM_TOP (1200/2) +// Determine default PIN +#if defined(ESP32) +#define DEFAULT_PIN 25 +#elif defined(ESP8266) +#define DEFAULT_PIN 16 +#elif defined(__arm__) +#define DEFAULT_PIN DAC0 +#elif defined(__AVR__) +#define DEFAULT_PIN 3 +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#define DEFAULT_PIN 44 +#endif + +// Define collback data type typedef void (*data_callback_type)(int len, byte *data); /** @@ -24,9 +38,8 @@ class BaseSound { */ class Sound : public BaseSound { public: - Sound(int pin){ - this->pin = pin; - } + Sound(); + Sound(int pin); void soundOff(); void soundOn(); void sound(byte b); From 996652975846d65c37a88c34d2032847734bde21 Mon Sep 17 00:00:00 2001 From: Phil Schatzmann Date: Wed, 16 Jun 2021 11:05:35 +0200 Subject: [PATCH 3/9] Display default pin --- examples/Speak/Speak.ino | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/Speak/Speak.ino b/examples/Speak/Speak.ino index 05f655c..561ce18 100644 --- a/examples/Speak/Speak.ino +++ b/examples/Speak/Speak.ino @@ -11,6 +11,9 @@ TTS tts; // with default pin void setup(){ Serial.begin(115200); + // display pin + Serial.print("Using Pin "); + Serial.println(DEFAULT_PIN); } void loop(){ From 2700e7bac5b10cdbb27496fe40167daca130bca5 Mon Sep 17 00:00:00 2001 From: Phil Schatzmann Date: Wed, 16 Jun 2021 11:11:42 +0200 Subject: [PATCH 4/9] Spelling --- sound.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound.h b/sound.h index 01a1f2a..93cc523 100644 --- a/sound.h +++ b/sound.h @@ -10,13 +10,13 @@ #define DEFAULT_PIN 16 #elif defined(__arm__) #define DEFAULT_PIN DAC0 -#elif defined(__AVR__) -#define DEFAULT_PIN 3 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #define DEFAULT_PIN 44 +#elif defined(__AVR__) +#define DEFAULT_PIN 3 #endif -// Define collback data type +// Define callback data type typedef void (*data_callback_type)(int len, byte *data); /** From b5e88d5a83a5e8ae5bd20df6385fb443344dc878 Mon Sep 17 00:00:00 2001 From: Phil Schatzmann Date: Wed, 16 Jun 2021 11:22:46 +0200 Subject: [PATCH 5/9] Remove pin from TTS --- TTS.cpp | 26 ++++++++++++-------------- TTS.h | 6 ++---- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/TTS.cpp b/TTS.cpp index daad84d..3bf3558 100644 --- a/TTS.cpp +++ b/TTS.cpp @@ -318,7 +318,7 @@ static byte random2(void) return seed0; } -byte TTS::playTone(int pin, byte soundNum, byte soundPos, char pitch1, char pitch2, byte count, byte volume) +byte TTS::playTone(byte soundNum, byte soundPos, char pitch1, char pitch2, byte count, byte volume) { const byte *soundData = &SoundData[soundNum * 0x40]; while (count-- > 0) { @@ -333,10 +333,10 @@ byte TTS::playTone(int pin, byte soundNum, byte soundPos, char pitch1, char pitc return soundPos & 0x3fu; } -void TTS::play(int pin, byte duration, byte soundNumber) +void TTS::play(byte duration, byte soundNumber) { while (duration--) - playTone(pin, soundNumber, random2(), 7, 7, 10, 15); + playTone(soundNumber, random2(), 7, 7, 10, 15); } /****************************************************************************** @@ -346,18 +346,16 @@ void TTS::play(int pin, byte duration, byte soundNumber) TTS::TTS() { - pin = DEFAULT_PIN; - sound_api = new Sound(pin); + sound_api = new Sound(DEFAULT_PIN); defaultPitch = 7; #ifdef __AVR__ - pinMode(pin, OUTPUT); + pinMode(DEFAULT_PIN, OUTPUT); #endif } TTS::TTS(int p) { - pin = p; sound_api = new Sound(p); defaultPitch = 7; #ifdef __AVR__ @@ -448,7 +446,7 @@ void TTS::sayPhonemes(const char *textp) // Make a white noise sound! byte volume = (duration == 6) ? 15 : 1; // volume mask for (duration <<= 2; duration > 0; duration--) { - playTone(pin, sound1Num, random2(), 8, 12, 11, volume); + playTone(sound1Num, random2(), 8, 12, 11, volume); // Increase the volume if (++volume == 16) volume = 15; // full volume from now on @@ -515,11 +513,11 @@ void TTS::sayPhonemes(const char *textp) byte sound1End = min(sound1Stop, sound2Stop); if (sound1Stop) - soundPos = playTone(pin, sound1Num, soundPos, pitch1, pitch1, sound1End, 15); + soundPos = playTone(sound1Num, soundPos, pitch1, pitch1, sound1End, 15); // s18 if (sound2Stop != 0x40) { - soundPos = playTone(pin, sound2Num, soundPos, pitch2, pitch2, sound2Stop - sound1End, 15); + soundPos = playTone(sound2Num, soundPos, pitch2, pitch2, sound2Stop - sound1End, 15); } // s23 if (sound1Duration != 0xff && duration < byte2) { @@ -530,13 +528,13 @@ void TTS::sayPhonemes(const char *textp) } // Call any additional sound if (byte1 == -1) - play(pin, 3, 30); // make an 'f' sound + play(3, 30); // make an 'f' sound else if (byte1 == -2) - play(pin, 3, 29); // make an 's' sound + play(3, 29); // make an 's' sound else if (byte1 == -3) - play(pin, 3, 33); // make a 'th' sound + play(3, 33); // make a 'th' sound else if (byte1 == -4) - play(pin, 3, 27); // make a 'sh' sound + play(3, 27); // make a 'sh' sound } while (--duration); diff --git a/TTS.h b/TTS.h index 8a6a875..cafbe10 100644 --- a/TTS.h +++ b/TTS.h @@ -39,7 +39,6 @@ class TTS { */ TTS(data_callback_type cb, int len=512) { sound_api = new SoundCallback(cb,len); - pin = -1; defaultPitch = 7; } @@ -77,11 +76,10 @@ class TTS { private: byte defaultPitch; - int pin; BaseSound *sound_api = nullptr; - void play(int pin, byte duration, byte soundNumber); - byte playTone(int pin, byte soundNum, byte soundPos, char pitch1, char pitch2, byte count, byte volume); + void play(byte duration, byte soundNumber); + byte playTone(byte soundNum, byte soundPos, char pitch1, char pitch2, byte count, byte volume); }; From 2002d179c1e491c942525aae72bb5360394778dc Mon Sep 17 00:00:00 2001 From: Phil Schatzmann Date: Tue, 22 Jun 2021 18:42:03 +0200 Subject: [PATCH 6/9] TTS Info --- TTS.cpp | 34 ++++++++++++++++++++++++---------- TTS.h | 48 ++++++++++++++++++++++++++++++++++++------------ sound.cpp | 15 ++++++--------- sound.h | 13 ++++++++----- 4 files changed, 74 insertions(+), 36 deletions(-) diff --git a/TTS.cpp b/TTS.cpp index 3bf3558..3e9f969 100644 --- a/TTS.cpp +++ b/TTS.cpp @@ -28,6 +28,7 @@ static byte seed2; static char phonemes[128]; static char modifier[sizeof(phonemes)]; // must be same size as 'phonemes' + // Lookup user specified pitch changes static const byte PROGMEM PitchesP[] = { 1, 2, 4, 6, 8, 10, 13, 16 }; @@ -344,25 +345,34 @@ void TTS::play(byte duration, byte soundNumber) ******************************************************************************/ -TTS::TTS() -{ - sound_api = new Sound(DEFAULT_PIN); - defaultPitch = 7; -#ifdef __AVR__ - pinMode(DEFAULT_PIN, OUTPUT); -#endif -} - - TTS::TTS(int p) { sound_api = new Sound(p); defaultPitch = 7; + stream_ptr = nullptr; #ifdef __AVR__ pinMode(pin, OUTPUT); #endif } +TTS::TTS(tts_data_callback_type cb, int len) { + sound_api = new SoundCallback(cb, this, len); + defaultPitch = 7; + stream_ptr = nullptr; +} + +/** + * @brief Construct a new TTS object which outputs the data to an Arduino Stream + * + * @param out + */ +TTS::TTS(Stream &out) { + stream_ptr = &out; + sound_api = new SoundCallback((tts_data_callback_type)TTS::stream_data_callback, this, 512); + defaultPitch = 7; +} + + /* * Speak a string of phonemes */ @@ -567,3 +577,7 @@ void TTS::sayText(const char *original) if (textToPhonemes(original, s_vocab, text)) sayPhonemes(text); } + + + + diff --git a/TTS.h b/TTS.h index cafbe10..191d2a9 100644 --- a/TTS.h +++ b/TTS.h @@ -15,8 +15,11 @@ #define _TTS_H_ #include "sound.h" -// acess to sound implementation, some methods are static so this needs to be static as well... - +struct TTSInfo { + int channels = 1; + int sample_rate = 12000; + int bits_per_sample = 8; +}; class TTS { public: @@ -24,23 +27,21 @@ class TTS { * @brief Construct a new TTS object using the default pin * */ - TTS(); + TTS(int pin); + /** - * @brief Construct a new TTS object + * @brief Construct a new TTS object - Uses the Callback to provide the result * - * @param pin */ - TTS(int pin); + TTS(tts_data_callback_type cb, int len=512); /** - * @brief Construct a new TTS object - Uses the Callback to provide the result + * @brief Construct a new TTS object which outputs the data to an Arduino Stream * + * @param out */ - TTS(data_callback_type cb, int len=512) { - sound_api = new SoundCallback(cb,len); - defaultPitch = 7; - } + TTS(Stream &out); /** * @brief Destroy the TTS object @@ -73,15 +74,38 @@ class TTS { */ byte getPitch(void) { return defaultPitch; } + /** + * @brief Get additional output information + * + * @return TTSInfo + */ + static TTSInfo getInfo() { + TTSInfo info; + return info; + } + + // allow callback to access private fields + friend void stream_data_callback(void *vtts, int len, byte *data); - private: + protected: byte defaultPitch; BaseSound *sound_api = nullptr; + Stream *stream_ptr = nullptr; void play(byte duration, byte soundNumber); byte playTone(byte soundNum, byte soundPos, char pitch1, char pitch2, byte count, byte volume); + // callback to write sound data to stream + static void stream_data_callback(void *vtts, int len, byte *data){ + TTS *tts = (TTS *) vtts; + if (tts->stream_ptr!=nullptr && len>0 && data!=nullptr){ + tts->stream_ptr->write((const char*)data, len); + } + } }; + + + #endif diff --git a/sound.cpp b/sound.cpp index d626aaa..4cc9f71 100644 --- a/sound.cpp +++ b/sound.cpp @@ -204,12 +204,9 @@ void Sound::sound(byte b) } - void SoundCallback::soundOff(){ - callback(current_length, out_data); - for (int j=0;j=max_length){ + if (tts_callback!=nullptr) { + (*tts_callback)(tts, current_length, out_data); } + memset(out_data, 0, current_length); current_length = 0; } } \ No newline at end of file diff --git a/sound.h b/sound.h index 93cc523..57c8077 100644 --- a/sound.h +++ b/sound.h @@ -17,7 +17,7 @@ #endif // Define callback data type -typedef void (*data_callback_type)(int len, byte *data); +typedef void (*tts_data_callback_type)(void *tts, int len, byte *data); /** * @brief Base Output Class @@ -55,11 +55,12 @@ class Sound : public BaseSound { */ class SoundCallback : public BaseSound { public: - SoundCallback(data_callback_type callback, int len=512){ + SoundCallback(tts_data_callback_type callback, void *tts, int len=512){ // allocate result array + this->tts = tts; + this->tts_callback = callback; + this->out_data = new byte[len+1]; this->max_length = len; - this->callback = callback; - this->out_data = new byte[max_length]; } ~SoundCallback(){ @@ -71,12 +72,14 @@ class SoundCallback : public BaseSound { void sound(byte b); private: - data_callback_type callback = nullptr; + void *tts; + tts_data_callback_type tts_callback = nullptr; byte *out_data = nullptr; int max_length = 0; int current_length = 0; bool active = false; + }; #endif From b64403d45e1719082fd4ea75a66d213aa4449991 Mon Sep 17 00:00:00 2001 From: Phil Schatzmann Date: Wed, 23 Jun 2021 10:18:59 +0200 Subject: [PATCH 7/9] Readme --- README.md | 5 ++++- TTS.h | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d7861b8..c50eee8 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,11 @@ View this project on [CADLAB.io](https://cadlab.io/project/1281). ## Text-to-Speech Library for Arduino - checkout this project into your ``sketchbook/libraries`` folder -- requires an amplifier on the PWM output pin (see below) or callback method +- requires an amplifier on the PWM output pin (see below) +- alternative output via Stream or callback method - see [blog articles](http://programmablehardware.blogspot.ie/search/label/tts) + ## Supported Hardware - ATmega328-based Arduinos (e.g., Uno, Pro, Pro Mini, etc.): pins 3, 9, 10 @@ -43,3 +45,4 @@ and ARM processors with DAC (Teensy, Due) - Teensy [forum](https://forum.pjrc.com/threads/44587-TTS-(Text-to-Speech)-Library-Port) - separate port/hack for MBED ARM with DAC [repository](https://developer.mbed.org/users/manitou/code/tts/) - Hackaday article on [LM386 amplifiers](https://hackaday.com/2016/12/07/you-can-have-my-lm386s-when-you-pry-them-from-my-cold-dead-hands/) +- Example on how to use the [Output via Streams](https://www.pschatzmann.ch/home/2021/06/22/text-to-speach-in-arduino-using-tts/) \ No newline at end of file diff --git a/TTS.h b/TTS.h index 191d2a9..ca54e39 100644 --- a/TTS.h +++ b/TTS.h @@ -15,12 +15,21 @@ #define _TTS_H_ #include "sound.h" +/** + * @brief TTS Output Information + * + */ struct TTSInfo { int channels = 1; int sample_rate = 12000; int bits_per_sample = 8; }; +/** + * @brief TTS API + * + */ + class TTS { public: /** From 5bebaaf954dfc2670d137c873b04ec24015b49c9 Mon Sep 17 00:00:00 2001 From: Phil Schatzmann Date: Tue, 26 Oct 2021 11:09:26 +0200 Subject: [PATCH 8/9] Change Stream to Print --- TTS.cpp | 2 +- TTS.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/TTS.cpp b/TTS.cpp index 3e9f969..a51db27 100644 --- a/TTS.cpp +++ b/TTS.cpp @@ -366,7 +366,7 @@ TTS::TTS(tts_data_callback_type cb, int len) { * * @param out */ -TTS::TTS(Stream &out) { +TTS::TTS(Print &out) { stream_ptr = &out; sound_api = new SoundCallback((tts_data_callback_type)TTS::stream_data_callback, this, 512); defaultPitch = 7; diff --git a/TTS.h b/TTS.h index ca54e39..33e41cd 100644 --- a/TTS.h +++ b/TTS.h @@ -50,7 +50,7 @@ class TTS { * * @param out */ - TTS(Stream &out); + TTS(Print &out); /** * @brief Destroy the TTS object @@ -99,7 +99,7 @@ class TTS { protected: byte defaultPitch; BaseSound *sound_api = nullptr; - Stream *stream_ptr = nullptr; + Print *stream_ptr = nullptr; void play(byte duration, byte soundNumber); byte playTone(byte soundNum, byte soundPos, char pitch1, char pitch2, byte count, byte volume); From 68e96821d7f46ce32dbfb1b00fd0fa80edbcaa61 Mon Sep 17 00:00:00 2001 From: Phil Schatzmann Date: Thu, 9 Jun 2022 10:40:05 +0200 Subject: [PATCH 9/9] 16bit support --- TTS.cpp | 3 ++- TTS.h | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/TTS.cpp b/TTS.cpp index a51db27..5d09535 100644 --- a/TTS.cpp +++ b/TTS.cpp @@ -366,10 +366,11 @@ TTS::TTS(tts_data_callback_type cb, int len) { * * @param out */ -TTS::TTS(Print &out) { +TTS::TTS(Print &out, int bits_per_sample) { stream_ptr = &out; sound_api = new SoundCallback((tts_data_callback_type)TTS::stream_data_callback, this, 512); defaultPitch = 7; + getInfo().bits_per_sample = bits_per_sample; } diff --git a/TTS.h b/TTS.h index 33e41cd..e306f6e 100644 --- a/TTS.h +++ b/TTS.h @@ -50,7 +50,7 @@ class TTS { * * @param out */ - TTS(Print &out); + TTS(Print &out, int bits_per_sample=16); /** * @brief Destroy the TTS object @@ -88,8 +88,8 @@ class TTS { * * @return TTSInfo */ - static TTSInfo getInfo() { - TTSInfo info; + static TTSInfo& getInfo() { + static TTSInfo info; return info; } @@ -107,8 +107,18 @@ class TTS { // callback to write sound data to stream static void stream_data_callback(void *vtts, int len, byte *data){ TTS *tts = (TTS *) vtts; + TTSInfo *info = &getInfo(); if (tts->stream_ptr!=nullptr && len>0 && data!=nullptr){ - tts->stream_ptr->write((const char*)data, len); + if (info->bits_per_sample==8){ + tts->stream_ptr->write((const char*)data, len); + } else { + // convert 8 to 16 bits + for (int j=0;jstream_ptr->write((const char*)&sample16, 2); + } + } } } @@ -116,5 +126,4 @@ class TTS { - #endif