mirror of
https://github.com/opentx/opentx.git
synced 2025-07-25 09:15:38 +03:00
More TTS work:
French numbers now ok with gender. 200ms removed at the start and the end of all prompts
This commit is contained in:
parent
17945fc24f
commit
7ca6a733c8
3 changed files with 72 additions and 51 deletions
|
@ -364,7 +364,10 @@ enum TelemetryUnit {
|
||||||
UNIT_WATTS,
|
UNIT_WATTS,
|
||||||
UNIT_MAX,
|
UNIT_MAX,
|
||||||
UNIT_FEET,
|
UNIT_FEET,
|
||||||
UNIT_KTS
|
UNIT_KTS,
|
||||||
|
UNIT_HOURS,
|
||||||
|
UNIT_MINUTES,
|
||||||
|
UNIT_SECONDS
|
||||||
};
|
};
|
||||||
|
|
||||||
PACK(typedef struct t_FrSkyChannelData {
|
PACK(typedef struct t_FrSkyChannelData {
|
||||||
|
|
|
@ -36,22 +36,23 @@
|
||||||
enum FrenchPrompts {
|
enum FrenchPrompts {
|
||||||
PROMPT_NUMBERS_BASE = 0,
|
PROMPT_NUMBERS_BASE = 0,
|
||||||
PROMPT_ZERO = PROMPT_NUMBERS_BASE+0,
|
PROMPT_ZERO = PROMPT_NUMBERS_BASE+0,
|
||||||
/* ... */
|
PROMPT_CENT = PROMPT_NUMBERS_BASE+100,
|
||||||
PROMPT_VINGT = PROMPT_NUMBERS_BASE+20,
|
PROMPT_MILLE = PROMPT_NUMBERS_BASE+101,
|
||||||
PROMPT_TRENTE = PROMPT_NUMBERS_BASE+21,
|
|
||||||
/* ... */
|
|
||||||
PROMPT_QUATREVINGTDIX = PROMPT_NUMBERS_BASE+27,
|
|
||||||
PROMPT_CENT = PROMPT_NUMBERS_BASE+28,
|
|
||||||
PROMPT_MILLE = PROMPT_NUMBERS_BASE+29,
|
|
||||||
|
|
||||||
PROMPT_HEURE = 40,
|
PROMPT_UNE = 102,
|
||||||
PROMPT_MINUTE = 41,
|
PROMPT_ONZE = 103,
|
||||||
PROMPT_SECONDE = 42,
|
PROMPT_VINGT_ET_UNE = 104,
|
||||||
|
PROMPT_TRENTE_ET_UNE = 105,
|
||||||
|
PROMPT_QUARANTE_ET_UNE = 106,
|
||||||
|
PROMPT_CINQUANTE_ET_UNE = 107,
|
||||||
|
PROMPT_SOIXANTE_ET_UNE = 108,
|
||||||
|
PROMPT_SOIXANTE_ET_ONZE = 109,
|
||||||
|
PROMPT_QUATRE_VINGT_UNE = 110,
|
||||||
|
|
||||||
PROMPT_ET = 47,
|
PROMPT_ET = 117,
|
||||||
PROMPT_MOINS = 48,
|
PROMPT_MOINS = 118,
|
||||||
|
|
||||||
PROMPT_UNITS_BASE = 50,
|
PROMPT_UNITS_BASE = 120,
|
||||||
PROMPT_VOLTS = PROMPT_UNITS_BASE+UNIT_VOLTS,
|
PROMPT_VOLTS = PROMPT_UNITS_BASE+UNIT_VOLTS,
|
||||||
PROMPT_AMPS = PROMPT_UNITS_BASE+UNIT_AMPS,
|
PROMPT_AMPS = PROMPT_UNITS_BASE+UNIT_AMPS,
|
||||||
PROMPT_METERS_PER_SECOND = PROMPT_UNITS_BASE+UNIT_METERS_PER_SECOND,
|
PROMPT_METERS_PER_SECOND = PROMPT_UNITS_BASE+UNIT_METERS_PER_SECOND,
|
||||||
|
@ -65,8 +66,11 @@ enum FrenchPrompts {
|
||||||
PROMPT_WATTS = PROMPT_UNITS_BASE+UNIT_WATTS,
|
PROMPT_WATTS = PROMPT_UNITS_BASE+UNIT_WATTS,
|
||||||
PROMPT_FEET = PROMPT_UNITS_BASE+UNIT_FEET,
|
PROMPT_FEET = PROMPT_UNITS_BASE+UNIT_FEET,
|
||||||
PROMPT_KTS = PROMPT_UNITS_BASE+UNIT_KTS,
|
PROMPT_KTS = PROMPT_UNITS_BASE+UNIT_KTS,
|
||||||
|
PROMPT_HEURE = PROMPT_UNITS_BASE+UNIT_HOURS,
|
||||||
|
PROMPT_MINUTE = PROMPT_UNITS_BASE+UNIT_MINUTES,
|
||||||
|
PROMPT_SECONDE = PROMPT_UNITS_BASE+UNIT_SECONDS,
|
||||||
|
|
||||||
PROMPT_LABELS_BASE = 100,
|
PROMPT_LABELS_BASE = 140,
|
||||||
PROMPT_TIMER1 = PROMPT_LABELS_BASE+TELEM_TM1,
|
PROMPT_TIMER1 = PROMPT_LABELS_BASE+TELEM_TM1,
|
||||||
PROMPT_TIMER2 = PROMPT_LABELS_BASE+TELEM_TM2,
|
PROMPT_TIMER2 = PROMPT_LABELS_BASE+TELEM_TM2,
|
||||||
PROMPT_A1 = PROMPT_LABELS_BASE+TELEM_A1,
|
PROMPT_A1 = PROMPT_LABELS_BASE+TELEM_A1,
|
||||||
|
@ -92,10 +96,13 @@ enum FrenchPrompts {
|
||||||
PROMPT_ACCELz = PROMPT_LABELS_BASE+TELEM_ACCz,
|
PROMPT_ACCELz = PROMPT_LABELS_BASE+TELEM_ACCz,
|
||||||
PROMPT_HDG = PROMPT_LABELS_BASE+TELEM_HDG,
|
PROMPT_HDG = PROMPT_LABELS_BASE+TELEM_HDG,
|
||||||
PROMPT_VARIO = PROMPT_LABELS_BASE+TELEM_VSPD,
|
PROMPT_VARIO = PROMPT_LABELS_BASE+TELEM_VSPD,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(SOMO) || defined(PCBARM)
|
#if defined(SOMO) || defined(PCBARM)
|
||||||
|
|
||||||
|
#define FEMININ 0x80
|
||||||
|
|
||||||
void playNumber(int16_t number, uint8_t unit, uint8_t att)
|
void playNumber(int16_t number, uint8_t unit, uint8_t att)
|
||||||
{
|
{
|
||||||
/* if digit >= 1000000000:
|
/* if digit >= 1000000000:
|
||||||
|
@ -107,13 +114,19 @@ void playNumber(int16_t number, uint8_t unit, uint8_t att)
|
||||||
prompts.extend(self.getNumberPrompt(temp_digit))
|
prompts.extend(self.getNumberPrompt(temp_digit))
|
||||||
prompts.append(Prompt(GUIDE_00_MILLION, dir=2))
|
prompts.append(Prompt(GUIDE_00_MILLION, dir=2))
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (number < 0) {
|
||||||
|
pushPrompt(PROMPT_MOINS);
|
||||||
|
number = -number;
|
||||||
|
}
|
||||||
|
|
||||||
if (number >= 1000) {
|
if (number >= 1000) {
|
||||||
if (number >= 2000)
|
if (number >= 2000)
|
||||||
playNumber(number / 1000);
|
playNumber(number / 1000);
|
||||||
pushPrompt(PROMPT_MILLE);
|
pushPrompt(PROMPT_MILLE);
|
||||||
number %= 1000;
|
number %= 1000;
|
||||||
if (number == 0)
|
if (number == 0)
|
||||||
return;
|
number = -1;
|
||||||
}
|
}
|
||||||
if (number >= 100) {
|
if (number >= 100) {
|
||||||
if (number >= 200)
|
if (number >= 200)
|
||||||
|
@ -121,15 +134,14 @@ void playNumber(int16_t number, uint8_t unit, uint8_t att)
|
||||||
pushPrompt(PROMPT_CENT);
|
pushPrompt(PROMPT_CENT);
|
||||||
number %= 100;
|
number %= 100;
|
||||||
if (number == 0)
|
if (number == 0)
|
||||||
return;
|
number = -1;
|
||||||
}
|
}
|
||||||
if (number >= 20) {
|
if (((number % 10) == 1) && number < 90 && (att & FEMININ)) {
|
||||||
pushPrompt(PROMPT_VINGT + (number-20)/10);
|
pushPrompt(PROMPT_UNE+(number/10));
|
||||||
number %= 10;
|
}
|
||||||
if (number == 0)
|
else if (number >= 0) {
|
||||||
return;
|
pushPrompt(PROMPT_ZERO+number);
|
||||||
}
|
}
|
||||||
pushPrompt(PROMPT_ZERO+number);
|
|
||||||
|
|
||||||
if (unit) {
|
if (unit) {
|
||||||
pushPrompt(PROMPT_UNITS_BASE+unit-1);
|
pushPrompt(PROMPT_UNITS_BASE+unit-1);
|
||||||
|
@ -146,21 +158,21 @@ void playDuration(int16_t seconds)
|
||||||
uint8_t tmp = seconds / 3600;
|
uint8_t tmp = seconds / 3600;
|
||||||
seconds %= 3600;
|
seconds %= 3600;
|
||||||
if (tmp > 0) {
|
if (tmp > 0) {
|
||||||
playNumber(tmp);
|
playNumber(tmp, 0, FEMININ);
|
||||||
pushPrompt(PROMPT_HEURE);
|
pushPrompt(PROMPT_HEURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = seconds / 60;
|
tmp = seconds / 60;
|
||||||
seconds %= 60;
|
seconds %= 60;
|
||||||
if (tmp > 0) {
|
if (tmp > 0) {
|
||||||
playNumber(tmp);
|
playNumber(tmp, 0, FEMININ);
|
||||||
pushPrompt(PROMPT_MINUTE);
|
pushPrompt(PROMPT_MINUTE);
|
||||||
if (seconds > 0)
|
if (seconds > 0)
|
||||||
pushPrompt(PROMPT_ET);
|
pushPrompt(PROMPT_ET);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seconds > 0) {
|
if (seconds > 0) {
|
||||||
playNumber(seconds);
|
playNumber(seconds, 0, FEMININ);
|
||||||
pushPrompt(PROMPT_SECONDE);
|
pushPrompt(PROMPT_SECONDE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
56
util/tts.py
56
util/tts.py
|
@ -13,10 +13,6 @@
|
||||||
# copy the entire pyTTS directory from Python25\Lib\site-packages to Python26 or Python27
|
# copy the entire pyTTS directory from Python25\Lib\site-packages to Python26 or Python27
|
||||||
# replace TTSFast.py with an empty file. This way the version-dependent pyd file isn't loaded.
|
# replace TTSFast.py with an empty file. This way the version-dependent pyd file isn't loaded.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os, sys, shutil, platform, subprocess, wave, zipfile
|
import os, sys, shutil, platform, subprocess, wave, zipfile
|
||||||
|
|
||||||
def generate(str, idx):
|
def generate(str, idx):
|
||||||
|
@ -31,7 +27,23 @@ def generate(str, idx):
|
||||||
else:
|
else:
|
||||||
result = idx + ".wav"
|
result = idx + ".wav"
|
||||||
print result, str
|
print result, str
|
||||||
tts.SpeakToWave(result, str)
|
|
||||||
|
temp = "_" + result
|
||||||
|
tts.SpeakToWave(temp, str)
|
||||||
|
|
||||||
|
i = wave.open(temp, "r")
|
||||||
|
n = i.getnframes()
|
||||||
|
f = i.readframes(n)
|
||||||
|
i.close()
|
||||||
|
o = wave.open(result, "w")
|
||||||
|
o.setnchannels(i.getnchannels())
|
||||||
|
o.setsampwidth(i.getsampwidth())
|
||||||
|
o.setframerate(i.getframerate())
|
||||||
|
o.writeframes(f[6400:-6400])
|
||||||
|
o.close()
|
||||||
|
|
||||||
|
os.remove(temp)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
subprocess.Popen(["C:\Program Files\eSpeak\command_line\espeak.exe", "-z", "-w", "%04d.wav" % idx, str], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait()
|
subprocess.Popen(["C:\Program Files\eSpeak\command_line\espeak.exe", "-z", "-w", "%04d.wav" % idx, str], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait()
|
||||||
if not "speak" in sys.argv:
|
if not "speak" in sys.argv:
|
||||||
|
@ -39,13 +51,9 @@ def generate(str, idx):
|
||||||
subprocess.Popen(["D:\Perso\workspace\companion9x\AD4CONVERTER.EXE", "-E4", result], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait()
|
subprocess.Popen(["D:\Perso\workspace\companion9x\AD4CONVERTER.EXE", "-E4", result], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait()
|
||||||
result = result.replace(".wav", ".ad4")
|
result = result.replace(".wav", ".ad4")
|
||||||
else:
|
else:
|
||||||
try:
|
os.rename(result, temp)
|
||||||
os.remove("_"+result)
|
subprocess.Popen(["C:/Programs/ffmpeg/bin/ffmpeg.exe", "-y", "-i", temp, "-acodec", "pcm_alaw", "-ar", "16000", result], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait()
|
||||||
except:
|
os.remove(temp)
|
||||||
pass
|
|
||||||
os.rename(result, "_"+result)
|
|
||||||
subprocess.Popen(["C:/Programs/ffmpeg/bin/ffmpeg.exe", "-y", "-i", "_"+result, "-acodec", "pcm_alaw", result], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait()
|
|
||||||
os.remove("_"+result)
|
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
return [result]
|
return [result]
|
||||||
|
@ -60,9 +68,9 @@ if __name__ == "__main__":
|
||||||
if "sapi" in sys.argv:
|
if "sapi" in sys.argv:
|
||||||
import pyTTS
|
import pyTTS
|
||||||
tts = pyTTS.Create()
|
tts = pyTTS.Create()
|
||||||
tts.SetOutputFormat(16, 16, 1)
|
# tts.SetOutputFormat(16, 16, 1)
|
||||||
# tts.Volume = 40
|
# tts.Volume = 40
|
||||||
tts.SetRate(1)
|
# tts.SetRate(1)
|
||||||
if "list" in sys.argv:
|
if "list" in sys.argv:
|
||||||
print tts.GetVoiceNames()
|
print tts.GetVoiceNames()
|
||||||
|
|
||||||
|
@ -85,22 +93,20 @@ if __name__ == "__main__":
|
||||||
if "sapi" in sys.argv:
|
if "sapi" in sys.argv:
|
||||||
tts.SetVoiceByName("ScanSoftVirginie_Full_22kHz")
|
tts.SetVoiceByName("ScanSoftVirginie_Full_22kHz")
|
||||||
voice = "french"
|
voice = "french"
|
||||||
for i in range(20):
|
for i in range(101):
|
||||||
systemSounds.extend(generate(str(i), i))
|
systemSounds.extend(generate(str(i), i))
|
||||||
for i in range(20, 100, 10):
|
systemSounds.extend(generate("1000", 101))
|
||||||
systemSounds.extend(generate(str(i), 20+(i-20)/10))
|
for i, s in enumerate(["une", "onze", "vingt et une", "trente et une", "quarante et une", "cinquante et une", "soixante et une", "soixante et onze", "quatre vingt une"]):
|
||||||
systemSounds.extend(generate("cent", 28))
|
systemSounds.extend(generate(s, 102+i))
|
||||||
systemSounds.extend(generate("mille", 29))
|
for i, s in enumerate(["et", "moins"]):
|
||||||
for i, s in enumerate(["heure", "minute", "seconde", "", "", "", "", "et", "moins"]):
|
systemSounds.extend(generate(s, 117+i))
|
||||||
systemSounds.extend(generate(s, 40+i))
|
|
||||||
|
|
||||||
for i, s in enumerate(["timer", "", "tension", "tension", "émission", u"réception", "altitude", "moteur",
|
for i, s in enumerate(["timer", "", "tension", "tension", "émission", u"réception", "altitude", "moteur",
|
||||||
"essence", u"température", "température", "vitesse", "distance", "altitude", "élément lipo",
|
"essence", u"température", "température", "vitesse", "distance", "altitude", "élément lipo",
|
||||||
"total lipo", "tension", "courant", "consommation", "puissance", "accelération X", "accelération Y", "accelération Z",
|
"total lipo", "tension", "courant", "consommation", "puissance", "accelération X", "accelération Y", "accelération Z",
|
||||||
"orientation", "vario"]):
|
"orientation", "vario"]):
|
||||||
systemSounds.extend(generate(s, 101+i))
|
systemSounds.extend(generate(s, 141+i))
|
||||||
for i, s in enumerate(["volts", u"ampères", u"mètres seconde", "", "km heure", u"mètres", u"degrés", "pourcents", u"milli ampères", u"milli ampères / heure", "watt", "", "pieds", "knotts"]):
|
for i, s in enumerate(["volts", u"ampères", u"mètres seconde", "", "km heure", u"mètres", u"degrés", "pourcents", u"milli ampères", u"milli ampères / heure", "watt", "", "pieds", "knotts", "heure", "minute", "seconde"]):
|
||||||
systemSounds.extend(generate(s, 50+i))
|
systemSounds.extend(generate(s, 120+i))
|
||||||
for s, f in [(u"train rentré", "gearup"),
|
for s, f in [(u"train rentré", "gearup"),
|
||||||
(u"train sorti", "geardn"),
|
(u"train sorti", "geardn"),
|
||||||
(u"volets rentrés", "flapup"),
|
(u"volets rentrés", "flapup"),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue