-
Notifications
You must be signed in to change notification settings - Fork 53
/
Copy pathTalkie.h
171 lines (151 loc) · 6.97 KB
/
Talkie.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
* Talkie.h
* Based on the Talkie library. https://github.com/going-digital/Talkie.
* Copyright 2011 Peter Knight
*
* SUMMARY
* Talkie is a speech library for Arduino.
* Output is at pin 3 + 11
*
* Copyright (C) 2018-2024 Armin Joachimsmeyer
* armin.joachimsmeyer@gmail.com
*
* This file is part of Talkie https://github.com/ArminJo/Talkie.
*
* Talkie is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
*
*/
#ifndef _TALKIE_H
#define _TALKIE_H
#include <inttypes.h>
#define VERSION_TALKIE "1.4.0"
#define VERSION_TALKIE_MAJOR 1
#define VERSION_TALKIE_MINOR 4
#define VERSION_TALKIE_PATCH 0
// The change log is at the bottom of the file
//#define ENABLE_PITCH // requires around 160 bytes of program space
#define ORIGINAL_SAMPLE_RATE 8000 // Speech engine sample rate
#define SAMPLE_RATE_DEFAULT ORIGINAL_SAMPLE_RATE // If you want to globally set pitch for Talkie, you can change this value, this saves the overhead implied by activating ENABLE_PITCH
/*
* Macro to convert 3 version parts into an integer
* To be used in preprocessor comparisons, such as #if VERSION_TALKIE_HEX >= VERSION_HEX_VALUE(3, 0, 0)
*/
#define VERSION_HEX_VALUE(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
#define VERSION_TALKIE_HEX VERSION_HEX_VALUE(VERSION_TALKIE_MAJOR, VERSION_TALKIE_MINOR, VERSION_TALKIE_PATCH)
// If you do not use the Arduino Tone library, then activating can save up to 844 bytes program size :-)
//#define NO_COMPATIBILITY_FOR_TONE_LIB_REQUIRED
/*
* Use 8bit coefficients K1 and K2.
* Saves 10 microseconds (40 instead of 50 us) for a 16 MHz ATmega
* has almost the same quality, except of a few "dropouts" e.g. in the word "thousand"
*/
//#define FAST_8BIT_MODE
#if defined(__AVR__)
#if !defined(__AVR_ATmega32U4__) && !defined(TCCR2A)
#error Sorry, when using an AVR chip, Talkie requires Timer2. This board does not have one.
#endif
#if F_CPU < 8000000L
#error F_CPU must be at least 8 MHz
#endif
#endif // (__AVR__)
#define FIFO_BUFFER_SIZE 24 // 24 sets of 4 bytes plus added queue indexes is about 100 added bytes.
#define TALKIE_USE_PIN_FLAG 0xFF // Flag to signal, that a pin (for inverted or not inverted output) should be used as output, but pin number is not yet filled in, since it depends of board type.
#define TALKIE_DO_NOT_USE_PIN_FLAG 0x00 // As pin number is initially != 0xFF, this is not really required at startup
class Talkie {
public:
Talkie();
Talkie(bool aUseNonInvertedOutputPin, bool aUseInvertedOutputPin);
void beginPWM(uint8_t aPinPWM); // // To be compatible to Teensy library
void say(const uint8_t *aWordDataAddress, unsigned int aSampleRateForPitch = ORIGINAL_SAMPLE_RATE); // Blocking version with pitch
int8_t sayQ(const uint8_t *aWordDataAddress, unsigned int aSampleRateForPitch = ORIGINAL_SAMPLE_RATE); // Queuing version. Returns free space in FIFO
void wait(); // wait for sayQ to end
void stop(); // allow the actual word to end -> only clears the FIFO guarded with cli and sei
void terminate(); // terminate synthesizer directly
void resetFIFO();
void initializeHardware();
void terminateHardware();
void doNotUseInvertedOutput(bool aDoNotUseInvertedOutput = true);
void doNotUseNonInvertedOutput(bool aDoNotUseNonInvertedOutput = true);
void digitalWriteInvertedOutput(uint8_t aValue);
void digitalWriteNonInvertedOutput(uint8_t aValue);
// Output pins to use. 0xFF -> Enable output (default). 0 -> Disable output.
uint8_t NonInvertedOutputPin; // Pin number of output, maybe fixed for some boards. On Arduino enables pin 3 (Talkie default) as PWM output. 0xFF -> Enable output (default). 0 -> Disable output.
uint8_t InvertedOutputPin; // On Arduino enables pin 11 as inverted PWM output to increase the volume.
const uint8_t *volatile WordDataPointer; // Pointer to word data array !!! Must be volatile, since it is accessed also by ISR
uint8_t WordDataBit; // [0-7] bit number of next bit in array bitstream
volatile bool isTalkingFlag;
uint8_t getNumberOfWords(); // Returns 0 if nothing to play, otherwise the number of the queued items plus the one which is active.
bool isTalking();
uint8_t getBits(uint8_t bits);
void setPtr(const uint8_t *aAddress);
void FIFOPushBack(const uint8_t *aAddress); // only sayQ() calls this
const uint8_t* FIFOPopFront(); // only sayISR() calls this
volatile uint8_t free; // init on setup = FIFO_BUFFER_SIZE
private:
// FIFO queue for sayQ
const uint8_t *FIFOBuffer[FIFO_BUFFER_SIZE];
// not required to specify the next 2 variables as volatile, since it code using them is guarded with noInterrupts() and interrupts()
uint8_t back; // index of last voice init on setup = 0
uint8_t front; // index of next voice init on setup = 0
// Bitstream parser
uint8_t rev(uint8_t a);
};
/*
* Version 1.4.0
* - Adding parameter aSampleRateForPitch and macro ENABLE_PITCH.
*
* Version 1.3.3
* - Adding support for SAMD51 and ESP32 core 3.x.
*
* Version 1.3.2
* - Fixed ESP32 timer bug.
*
* Version 1.3.1
* - Improved SAMD support.
*
* Version 1.3.0
* - 10 bit Coefficients are working now, but they do not sound better :-(.
* - Tested on an ESP32.
* - Tested on a BluePill.
*
* Version 1.2.0 - 8/2020
* - Corrected wrong function name doNotUseUseInvertedOutput().
* - Added functions digitalWriteNonInvertedOutput() and digitalWriteInvertedOutput().
*
* Version 1.1.0 - 6/2020
* - SAMD support.
* - ESP32 support.
* - Teensy support.
* - Version number.
* - Added function `sayQTimeout()` in *TalkieUtils.cpp*.
* - Added example *USDistanceToVoice*.
* - Added function `sayQVoltageVolts()`.
* - Improved end handling to minimize clicks.
*
* Version 1.0.2 - 09-11/2019
* - ATmega2560 supported and tested.
* - Always set pins to input when finishing, to avoid a click.
*
* Version 1.0.1 - 09/2019
* - Added SPI compatibility (after speaking do not reset pin 11 to input if SPI detected).
*
* Version 1.0.0 - 11/2018
* - Fix the ISR_RATIO Bug for plain Arduino
* - Added a lot of comments and do refactoring to better understand the functionality
* - Added stopping timer1 interrupts at every end of speech to free resources for usage of Arduino tone library
* - Extracted initializeHardware() function
* - Added some utility functions, extracted from the examples.
* - Improved shifting code so Talkie now runs on 8 MHz Arduino (with millis() interrupt disabled while talking)
*/
#endif // _TALKIE_H