mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-28 08:04:13 +08:00
update
This commit is contained in:
parent
3b000950bd
commit
8761f09c0f
@ -68,6 +68,7 @@ class MAINUI:
|
|||||||
self.translators = {}
|
self.translators = {}
|
||||||
self.cishus = {}
|
self.cishus = {}
|
||||||
self.reader = None
|
self.reader = None
|
||||||
|
self.specialreaders = {}
|
||||||
self.textsource_p = None
|
self.textsource_p = None
|
||||||
self.currentmd5 = "0"
|
self.currentmd5 = "0"
|
||||||
self.currenttext = ""
|
self.currenttext = ""
|
||||||
@ -496,7 +497,7 @@ class MAINUI:
|
|||||||
text = parsemayberegexreplace(usedict["tts_repair_regex"], text)
|
text = parsemayberegexreplace(usedict["tts_repair_regex"], text)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def guessmaybeskip(self, dic: dict, res: str):
|
def matchwhich(self, dic: dict, res: str):
|
||||||
|
|
||||||
for item in dic:
|
for item in dic:
|
||||||
if item["regex"]:
|
if item["regex"]:
|
||||||
@ -505,11 +506,11 @@ class MAINUI:
|
|||||||
)
|
)
|
||||||
if item["condition"] == 1:
|
if item["condition"] == 1:
|
||||||
if re.search(retext, res):
|
if re.search(retext, res):
|
||||||
return True
|
return item
|
||||||
elif item["condition"] == 0:
|
elif item["condition"] == 0:
|
||||||
if re.match(retext, res) or re.search(retext + "$", res):
|
if re.match(retext, res) or re.search(retext + "$", res):
|
||||||
# 用^xxx|xxx$有可能有点危险
|
# 用^xxx|xxx$有可能有点危险
|
||||||
return True
|
return item
|
||||||
else:
|
else:
|
||||||
if item["condition"] == 1:
|
if item["condition"] == 1:
|
||||||
if (
|
if (
|
||||||
@ -520,55 +521,78 @@ class MAINUI:
|
|||||||
resx = res.split(" ")
|
resx = res.split(" ")
|
||||||
for i in range(len(resx)):
|
for i in range(len(resx)):
|
||||||
if resx[i] == item["key"]:
|
if resx[i] == item["key"]:
|
||||||
return True
|
return item
|
||||||
else:
|
else:
|
||||||
if item["key"] in res:
|
if item["key"] in res:
|
||||||
return True
|
return item
|
||||||
elif item["condition"] == 0:
|
elif item["condition"] == 0:
|
||||||
if res.startswith(item["key"]) or res.endswith(item["key"]):
|
if res.startswith(item["key"]) or res.endswith(item["key"]):
|
||||||
return True
|
return item
|
||||||
return False
|
return None
|
||||||
|
|
||||||
def ttsskip(self, text, usedict):
|
def ttsskip(self, text, usedict) -> dict:
|
||||||
if usedict["tts_skip"]:
|
if usedict["tts_skip"]:
|
||||||
return self.guessmaybeskip(usedict["tts_skip_regex"], text)
|
return self.matchwhich(usedict["tts_skip_regex"], text)
|
||||||
return False
|
return None
|
||||||
|
|
||||||
@threader
|
@threader
|
||||||
def readcurrent(self, force=False):
|
def readcurrent(self, force=False):
|
||||||
if not self.reader:
|
if (not force) and (not globalconfig["autoread"]):
|
||||||
return
|
return
|
||||||
if not (force or globalconfig["autoread"]):
|
matchitme = self.ttsskip(self.currentread, self.__usewhich())
|
||||||
return
|
reader = None
|
||||||
if (not force) and self.ttsskip(self.currentread, self.__usewhich()):
|
if matchitme is None:
|
||||||
|
reader = self.reader
|
||||||
|
else:
|
||||||
|
target = matchitme.get("target", "default")
|
||||||
|
if target == "default":
|
||||||
|
reader = self.reader
|
||||||
|
elif target == "skip":
|
||||||
|
if not force:
|
||||||
|
return
|
||||||
|
reader = self.reader
|
||||||
|
else:
|
||||||
|
engine, voice, _ = target
|
||||||
|
reader = self.specialreaders.get((engine, voice), None)
|
||||||
|
if reader == -1:
|
||||||
|
reader = self.reader
|
||||||
|
elif reader is None:
|
||||||
|
try:
|
||||||
|
reader = self.loadreader(engine, privateconfig={"voice": voice})
|
||||||
|
self.specialreaders[(engine, voice)] = reader
|
||||||
|
except:
|
||||||
|
reader = self.reader
|
||||||
|
self.specialreaders[(engine, voice)] = -1
|
||||||
|
if reader is None:
|
||||||
return
|
return
|
||||||
text = self.ttsrepair(self.currentread, self.__usewhich())
|
text = self.ttsrepair(self.currentread, self.__usewhich())
|
||||||
self.reader.read(text, force)
|
reader.read(text, force)
|
||||||
|
|
||||||
|
def loadreader(self, use, voicelistsignal=None, privateconfig=None, init=True):
|
||||||
|
if voicelistsignal is None:
|
||||||
|
voicelistsignal = self.settin_ui.voicelistsignal
|
||||||
|
aclass = importlib.import_module("tts." + use).TTS
|
||||||
|
obj = aclass(use, voicelistsignal, self.audioplayer.play, privateconfig, init)
|
||||||
|
return obj
|
||||||
|
|
||||||
@threader
|
@threader
|
||||||
def startreader(self, use=None, checked=True):
|
def startreader(self, use=None, checked=True):
|
||||||
try:
|
|
||||||
self.reader.end()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
self.reader = None
|
self.reader = None
|
||||||
self.settin_ui.voicelistsignal.emit([], -1)
|
self.settin_ui.voicelistsignal.emit(None)
|
||||||
if checked:
|
if not checked:
|
||||||
if use is None:
|
return
|
||||||
|
if use is None:
|
||||||
for key in globalconfig["reader"]:
|
for key in globalconfig["reader"]:
|
||||||
if globalconfig["reader"][key]["use"] and os.path.exists(
|
if globalconfig["reader"][key]["use"] and os.path.exists(
|
||||||
("./LunaTranslator/tts/" + key + ".py")
|
("./LunaTranslator/tts/" + key + ".py")
|
||||||
):
|
):
|
||||||
use = key
|
use = key
|
||||||
break
|
break
|
||||||
if use:
|
if not use:
|
||||||
aclass = importlib.import_module("tts." + use).TTS
|
return
|
||||||
|
self.reader = self.loadreader(use)
|
||||||
self.reader_usevoice = use
|
self.reader_usevoice = use
|
||||||
self.reader = aclass(
|
|
||||||
use, self.settin_ui.voicelistsignal, self.audioplayer.play
|
|
||||||
)
|
|
||||||
|
|
||||||
def selectprocess(self, selectedp, title):
|
def selectprocess(self, selectedp, title):
|
||||||
self.textsource = None
|
self.textsource = None
|
||||||
@ -899,57 +923,6 @@ class MAINUI:
|
|||||||
)
|
)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
self.migrate_info()
|
|
||||||
|
|
||||||
@threader
|
|
||||||
def migrate_info(self):
|
|
||||||
for k in savehook_new_data:
|
|
||||||
self.migrate_traceplaytime_v2(k)
|
|
||||||
self.migrate_vndbtags(k)
|
|
||||||
self.migrate_images(k)
|
|
||||||
|
|
||||||
def migrate_traceplaytime_v2(self, k):
|
|
||||||
|
|
||||||
if "traceplaytime_v2" not in savehook_new_data[k]:
|
|
||||||
return
|
|
||||||
traceplaytime_v2 = savehook_new_data[k].get("traceplaytime_v2", [])
|
|
||||||
for slice in traceplaytime_v2.copy():
|
|
||||||
self.traceplaytime(k, slice[0], slice[1], True)
|
|
||||||
savehook_new_data[k]["traceplaytime_v2"].pop(0)
|
|
||||||
savehook_new_data[k].pop("traceplaytime_v2")
|
|
||||||
|
|
||||||
def migrate_vndbtags(self, k):
|
|
||||||
def getvndbrealtags(vndbtags_naive):
|
|
||||||
vndbtagdata = tryreadconfig("vndbtagdata.json")
|
|
||||||
vndbtags = []
|
|
||||||
for tagid in vndbtags_naive:
|
|
||||||
if tagid in vndbtagdata:
|
|
||||||
vndbtags.append(vndbtagdata[tagid])
|
|
||||||
return vndbtags
|
|
||||||
|
|
||||||
if "vndbtags" not in savehook_new_data[k]:
|
|
||||||
return
|
|
||||||
vndbtags = savehook_new_data[k].get("vndbtags", [])
|
|
||||||
vndbtags = getvndbrealtags(vndbtags)
|
|
||||||
savehook_new_data[k]["webtags"] = vndbtags
|
|
||||||
savehook_new_data[k].pop("vndbtags")
|
|
||||||
|
|
||||||
def migrate_images(self, k):
|
|
||||||
|
|
||||||
if (
|
|
||||||
"imagepath" not in savehook_new_data[k]
|
|
||||||
and "imagepath_much2" not in savehook_new_data[k]
|
|
||||||
):
|
|
||||||
return
|
|
||||||
single = savehook_new_data[k].get("imagepath", None)
|
|
||||||
much = savehook_new_data[k].get("imagepath_much2", [])
|
|
||||||
__ = []
|
|
||||||
if single:
|
|
||||||
__.append(single)
|
|
||||||
__ += much
|
|
||||||
savehook_new_data[k]["imagepath_all"] = __
|
|
||||||
savehook_new_data[k].pop("imagepath")
|
|
||||||
savehook_new_data[k].pop("imagepath_much2")
|
|
||||||
|
|
||||||
def querytraceplaytime_v4(self, gameuid):
|
def querytraceplaytime_v4(self, gameuid):
|
||||||
gameinternalid = self.get_gameinternalid(uid2gamepath[gameuid])
|
gameinternalid = self.get_gameinternalid(uid2gamepath[gameuid])
|
||||||
|
@ -41,7 +41,7 @@ from myutils.audioplayer import player_mci
|
|||||||
from gui.codeacceptdialog import codeacceptdialog
|
from gui.codeacceptdialog import codeacceptdialog
|
||||||
from gui.inputdialog import (
|
from gui.inputdialog import (
|
||||||
noundictconfigdialog1,
|
noundictconfigdialog1,
|
||||||
noundictconfigdialog2,
|
yuyinzhidingsetting,
|
||||||
autoinitdialog,
|
autoinitdialog,
|
||||||
autoinitdialog_items,
|
autoinitdialog_items,
|
||||||
postconfigdialog,
|
postconfigdialog,
|
||||||
@ -1052,16 +1052,13 @@ class dialog_setting_game_internal(QWidget):
|
|||||||
)
|
)
|
||||||
|
|
||||||
formLayout2.addRow(
|
formLayout2.addRow(
|
||||||
"语音跳过",
|
"语音指定",
|
||||||
getboxlayout(
|
getboxlayout(
|
||||||
[
|
[
|
||||||
getsimpleswitch(savehook_new_data[gameuid], "tts_skip"),
|
getsimpleswitch(savehook_new_data[gameuid], "tts_skip"),
|
||||||
getIconButton(
|
getIconButton(
|
||||||
callback=lambda: noundictconfigdialog2(
|
callback=lambda: yuyinzhidingsetting(
|
||||||
self,
|
self, savehook_new_data[gameuid]["tts_skip_regex"]
|
||||||
savehook_new_data[gameuid]["tts_skip_regex"],
|
|
||||||
"语音跳过",
|
|
||||||
["正则", "条件", "内容"],
|
|
||||||
),
|
),
|
||||||
icon="fa.gear",
|
icon="fa.gear",
|
||||||
),
|
),
|
||||||
|
@ -152,6 +152,14 @@ class LFormLayout(QFormLayout):
|
|||||||
argc = text, widget
|
argc = text, widget
|
||||||
super().addRow(*argc)
|
super().addRow(*argc)
|
||||||
|
|
||||||
|
def insertRow(self, row, *argc):
|
||||||
|
if len(argc) == 2:
|
||||||
|
text, widget = argc
|
||||||
|
if isinstance(text, str):
|
||||||
|
text = LLabel(text)
|
||||||
|
argc = text, widget
|
||||||
|
super().insertRow(row, *argc)
|
||||||
|
|
||||||
|
|
||||||
class LDialog(QDialog):
|
class LDialog(QDialog):
|
||||||
|
|
||||||
@ -167,7 +175,7 @@ class LDialog(QDialog):
|
|||||||
if self._title:
|
if self._title:
|
||||||
super().setWindowTitle(_TR(self._title))
|
super().setWindowTitle(_TR(self._title))
|
||||||
|
|
||||||
|
|
||||||
class LMainWindow(QMainWindow):
|
class LMainWindow(QMainWindow):
|
||||||
|
|
||||||
def __init__(self, *argc, **kwarg):
|
def __init__(self, *argc, **kwarg):
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
from qtsymbols import *
|
from qtsymbols import *
|
||||||
import functools, importlib
|
import functools, importlib
|
||||||
from traceback import print_exc
|
from traceback import print_exc
|
||||||
import qtawesome
|
import qtawesome, os, gobject
|
||||||
from myutils.config import globalconfig, _TR
|
from myutils.config import globalconfig, _TR
|
||||||
from myutils.utils import makehtml
|
from myutils.utils import makehtml
|
||||||
from myutils.wrapper import Singleton_close
|
from myutils.wrapper import Singleton_close
|
||||||
|
from tts.basettsclass import getvisidx
|
||||||
from gui.usefulwidget import (
|
from gui.usefulwidget import (
|
||||||
MySwitch,
|
MySwitch,
|
||||||
selectcolor,
|
selectcolor,
|
||||||
@ -82,7 +83,6 @@ class noundictconfigdialog1(LDialog):
|
|||||||
|
|
||||||
def __init__(self, parent, reflist, title, label) -> None:
|
def __init__(self, parent, reflist, title, label) -> None:
|
||||||
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
|
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
|
||||||
self.label = label
|
|
||||||
self.setWindowTitle(title)
|
self.setWindowTitle(title)
|
||||||
# self.setWindowModality(Qt.ApplicationModal)
|
# self.setWindowModality(Qt.ApplicationModal)
|
||||||
self.reflist = reflist
|
self.reflist = reflist
|
||||||
@ -181,19 +181,107 @@ class noundictconfigdialog1(LDialog):
|
|||||||
self.apply()
|
self.apply()
|
||||||
|
|
||||||
|
|
||||||
|
class voiceselect(LDialog):
|
||||||
|
voicelistsignal = pyqtSignal(object)
|
||||||
|
|
||||||
|
def __init__(self, *argc, **kwarg):
|
||||||
|
super().__init__(*argc, **kwarg)
|
||||||
|
self.setWindowTitle("选择声音")
|
||||||
|
self.setWindowFlags(
|
||||||
|
self.windowFlags()
|
||||||
|
& ~Qt.WindowContextHelpButtonHint
|
||||||
|
& ~Qt.WindowType.WindowCloseButtonHint
|
||||||
|
| Qt.WindowStaysOnTopHint
|
||||||
|
)
|
||||||
|
_layout = LFormLayout(self)
|
||||||
|
|
||||||
|
button = QDialogButtonBox(
|
||||||
|
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
|
||||||
|
)
|
||||||
|
button.accepted.connect(self.accept)
|
||||||
|
button.rejected.connect(self.reject)
|
||||||
|
|
||||||
|
self.engine_vis = []
|
||||||
|
self.engine_internal = []
|
||||||
|
for name in globalconfig["reader"]:
|
||||||
|
|
||||||
|
_f = "./LunaTranslator/tts/{}.py".format(name)
|
||||||
|
if os.path.exists(_f) == False:
|
||||||
|
continue
|
||||||
|
self.engine_vis.append(globalconfig["reader"][name]["name"])
|
||||||
|
self.engine_internal.append(name)
|
||||||
|
self.datas = {
|
||||||
|
"engine": self.engine_internal[0],
|
||||||
|
"voice": "",
|
||||||
|
"vis": "",
|
||||||
|
"visx": "",
|
||||||
|
}
|
||||||
|
combo = getsimplecombobox(
|
||||||
|
self.engine_vis,
|
||||||
|
self.datas,
|
||||||
|
"engine",
|
||||||
|
internal=self.engine_internal,
|
||||||
|
callback=self.__engine_cb,
|
||||||
|
)
|
||||||
|
_layout.addRow("引擎", combo)
|
||||||
|
self._layout = _layout
|
||||||
|
combo.currentIndexChanged.emit(combo.currentIndex())
|
||||||
|
_layout.addRow(button)
|
||||||
|
self.voicelistsignal.connect(self.loadedvoice)
|
||||||
|
self.object = None
|
||||||
|
self.lastwidget = None
|
||||||
|
|
||||||
|
def loadedvoice(self, obj):
|
||||||
|
vl, idx = getvisidx(obj)
|
||||||
|
self.datas["voice"] = obj.voice
|
||||||
|
if self._layout.rowCount() == 3:
|
||||||
|
self._layout.removeRow(1)
|
||||||
|
if len(vl) == 0:
|
||||||
|
return
|
||||||
|
voices = getsimplecombobox(
|
||||||
|
vl,
|
||||||
|
self.datas,
|
||||||
|
"voice",
|
||||||
|
internal=obj.voicelist,
|
||||||
|
callback=functools.partial(self._selectvoice, obj),
|
||||||
|
)
|
||||||
|
self._layout.insertRow(1, "语音", voices)
|
||||||
|
voices.currentIndexChanged.emit(voices.currentIndex())
|
||||||
|
|
||||||
|
def _selectvoice(self, obj, internal):
|
||||||
|
vis = obj.voiceshowlist[obj.voicelist.index(internal)]
|
||||||
|
self.datas["vis"] = self.datas["visx"] + " " + vis
|
||||||
|
|
||||||
|
def __engine_cb(self, internal):
|
||||||
|
self.datas["visx"] = self.engine_vis[self.engine_internal.index(internal)]
|
||||||
|
self.datas["vis"] = self.datas["visx"]
|
||||||
|
try:
|
||||||
|
self.object = gobject.baseobject.loadreader(internal, self.voicelistsignal, init=False)
|
||||||
|
except:
|
||||||
|
|
||||||
|
if self._layout.rowCount() == 3:
|
||||||
|
self._layout.removeRow(1)
|
||||||
|
|
||||||
|
|
||||||
@Singleton_close
|
@Singleton_close
|
||||||
class noundictconfigdialog2(LDialog):
|
class yuyinzhidingsetting(LDialog):
|
||||||
def newline(self, row, item):
|
def newline(self, row, item):
|
||||||
|
|
||||||
self.model.insertRow(
|
self.model.insertRow(
|
||||||
row,
|
row,
|
||||||
[QStandardItem(), QStandardItem(), QStandardItem(item["key"])],
|
[
|
||||||
|
QStandardItem(),
|
||||||
|
QStandardItem(),
|
||||||
|
QStandardItem(item["key"]),
|
||||||
|
QStandardItem(),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
self.table.setIndexWidget(
|
self.table.setIndexWidget(
|
||||||
self.model.index(row, 0), getsimpleswitch(item, "regex")
|
self.model.index(row, 0), getsimpleswitch(item, "regex")
|
||||||
)
|
)
|
||||||
com = getsimplecombobox(["首尾", "包含"], item, "condition")
|
com = getsimplecombobox(["首尾", "包含"], item, "condition")
|
||||||
self.table.setIndexWidget(self.model.index(row, 1), com)
|
self.table.setIndexWidget(self.model.index(row, 1), com)
|
||||||
|
self.table.setIndexWidget(self.model.index(row, 3), self.createacombox(item))
|
||||||
|
|
||||||
def showmenu(self, table: TableViewW, _):
|
def showmenu(self, table: TableViewW, _):
|
||||||
r = table.currentIndex().row()
|
r = table.currentIndex().row()
|
||||||
@ -222,7 +310,12 @@ class noundictconfigdialog2(LDialog):
|
|||||||
item = self.reflist.pop(curr.row())
|
item = self.reflist.pop(curr.row())
|
||||||
self.reflist.insert(
|
self.reflist.insert(
|
||||||
target,
|
target,
|
||||||
{"key": texts[1], "condition": item["condition"], "regex": item["regex"]},
|
{
|
||||||
|
"key": texts[1],
|
||||||
|
"condition": item["condition"],
|
||||||
|
"regex": item["regex"],
|
||||||
|
"target": item["target"],
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
model.removeRow(curr.row())
|
model.removeRow(curr.row())
|
||||||
@ -233,20 +326,67 @@ class noundictconfigdialog2(LDialog):
|
|||||||
)
|
)
|
||||||
com = getsimplecombobox(["首尾", "包含"], item, "condition")
|
com = getsimplecombobox(["首尾", "包含"], item, "condition")
|
||||||
table.setIndexWidget(self.model.index(target, 1), com)
|
table.setIndexWidget(self.model.index(target, 1), com)
|
||||||
|
table.setIndexWidget(self.model.index(target, 3), self.createacombox(item))
|
||||||
|
|
||||||
def __init__(self, parent, reflist, title, label) -> None:
|
def createacombox(self, config):
|
||||||
|
com = LFocusCombo()
|
||||||
|
com.addItems(["跳过", "默认", "选择声音"])
|
||||||
|
target = config.get("target", "skip")
|
||||||
|
if target == "skip":
|
||||||
|
com.setCurrentIndex(0)
|
||||||
|
elif target == "default":
|
||||||
|
com.setCurrentIndex(1)
|
||||||
|
else:
|
||||||
|
ttsklass, ttsvoice, voicename = target
|
||||||
|
com.addItem(voicename)
|
||||||
|
com.setCurrentIndex(3)
|
||||||
|
com.currentIndexChanged.connect(
|
||||||
|
functools.partial(self.__comchange, com, config)
|
||||||
|
)
|
||||||
|
return com
|
||||||
|
|
||||||
|
def __comchange(self, com: LFocusCombo, config, idx):
|
||||||
|
if idx == 0:
|
||||||
|
config["target"] = "skip"
|
||||||
|
if com.count() > 3:
|
||||||
|
com.removeItem(com.count() - 1)
|
||||||
|
elif idx == 1:
|
||||||
|
config["target"] = "default"
|
||||||
|
if com.count() > 3:
|
||||||
|
com.removeItem(com.count() - 1)
|
||||||
|
elif idx == 2:
|
||||||
|
voice = voiceselect(self)
|
||||||
|
if voice.exec():
|
||||||
|
config["target"] = (
|
||||||
|
voice.datas["engine"],
|
||||||
|
voice.datas["voice"],
|
||||||
|
voice.datas["vis"],
|
||||||
|
)
|
||||||
|
com.blockSignals(True)
|
||||||
|
com.clear()
|
||||||
|
com.addItems(["跳过", "默认", "选择声音", voice.datas["vis"]])
|
||||||
|
com.setCurrentIndex(3)
|
||||||
|
com.blockSignals(False)
|
||||||
|
else:
|
||||||
|
com.setCurrentIndex(1)
|
||||||
|
|
||||||
|
def __init__(self, parent, reflist) -> None:
|
||||||
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
|
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
|
||||||
self.label = label
|
|
||||||
self.setWindowTitle(title)
|
self.setWindowTitle("语音指定")
|
||||||
|
|
||||||
# self.setWindowModality(Qt.ApplicationModal)
|
# self.setWindowModality(Qt.ApplicationModal)
|
||||||
self.reflist = reflist
|
self.reflist = reflist
|
||||||
formLayout = QVBoxLayout(self) # 配置layout
|
formLayout = QVBoxLayout(self) # 配置layout
|
||||||
|
|
||||||
self.model = LStandardItemModel()
|
self.model = LStandardItemModel()
|
||||||
self.model.setHorizontalHeaderLabels(label)
|
self.model.setHorizontalHeaderLabels(["正则", "条件", "目标", "指定为"])
|
||||||
table = TableViewW(self)
|
table = TableViewW(self)
|
||||||
table.setModel(self.model)
|
table.setModel(self.model)
|
||||||
table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch)
|
table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch)
|
||||||
|
table.horizontalHeader().setSectionResizeMode(
|
||||||
|
3, QHeaderView.ResizeMode.ResizeToContents
|
||||||
|
)
|
||||||
table.horizontalHeader().setSectionResizeMode(
|
table.horizontalHeader().setSectionResizeMode(
|
||||||
1, QHeaderView.ResizeMode.ResizeToContents
|
1, QHeaderView.ResizeMode.ResizeToContents
|
||||||
)
|
)
|
||||||
@ -286,7 +426,9 @@ class noundictconfigdialog2(LDialog):
|
|||||||
button = threebuttons(texts=["添加行", "删除行", "上移", "下移", "立即应用"])
|
button = threebuttons(texts=["添加行", "删除行", "上移", "下移", "立即应用"])
|
||||||
|
|
||||||
def clicked1():
|
def clicked1():
|
||||||
self.reflist.insert(0, {"key": "", "condition": 0, "regex": False})
|
self.reflist.insert(
|
||||||
|
0, {"key": "", "condition": 0, "regex": False, "target": "skip"}
|
||||||
|
)
|
||||||
|
|
||||||
self.newline(0, self.reflist[0])
|
self.newline(0, self.reflist[0])
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ class TabWidget(QWidget):
|
|||||||
|
|
||||||
|
|
||||||
class Setting(closeashidewindow):
|
class Setting(closeashidewindow):
|
||||||
voicelistsignal = pyqtSignal(list, int)
|
voicelistsignal = pyqtSignal(object)
|
||||||
versiontextsignal = pyqtSignal(str)
|
versiontextsignal = pyqtSignal(str)
|
||||||
progresssignal = pyqtSignal(str, int)
|
progresssignal = pyqtSignal(str, int)
|
||||||
showandsolvesig = pyqtSignal(str)
|
showandsolvesig = pyqtSignal(str)
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
from qtsymbols import *
|
from qtsymbols import *
|
||||||
import os, functools
|
import os, functools
|
||||||
import gobject
|
import gobject
|
||||||
|
from tts.basettsclass import getvisidx
|
||||||
from myutils.config import globalconfig, static_data
|
from myutils.config import globalconfig, static_data
|
||||||
from gui.inputdialog import (
|
from gui.inputdialog import (
|
||||||
autoinitdialog_items,
|
autoinitdialog_items,
|
||||||
noundictconfigdialog1,
|
noundictconfigdialog1,
|
||||||
autoinitdialog,
|
autoinitdialog,
|
||||||
noundictconfigdialog2,
|
yuyinzhidingsetting,
|
||||||
)
|
)
|
||||||
from gui.usefulwidget import (
|
from gui.usefulwidget import (
|
||||||
D_getsimplecombobox,
|
D_getsimplecombobox,
|
||||||
@ -19,7 +20,8 @@ from gui.usefulwidget import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def showvoicelist(self, vl, idx):
|
def showvoicelist(self, obj):
|
||||||
|
vl, idx = getvisidx(obj)
|
||||||
try:
|
try:
|
||||||
self.voicecombo.blockSignals(True)
|
self.voicecombo.blockSignals(True)
|
||||||
self.voicecombo.clear()
|
self.voicecombo.clear()
|
||||||
@ -205,14 +207,11 @@ def setTab5lz(self):
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"语音跳过",
|
"语音指定",
|
||||||
D_getsimpleswitch(globalconfig["ttscommon"], "tts_skip"),
|
D_getsimpleswitch(globalconfig["ttscommon"], "tts_skip"),
|
||||||
D_getIconButton(
|
D_getIconButton(
|
||||||
callback=lambda: noundictconfigdialog2(
|
callback=lambda: yuyinzhidingsetting(
|
||||||
self,
|
self, globalconfig["ttscommon"]["tts_skip_regex"]
|
||||||
globalconfig["ttscommon"]["tts_skip_regex"],
|
|
||||||
"语音跳过",
|
|
||||||
["正则", "条件", "内容"],
|
|
||||||
),
|
),
|
||||||
icon="fa.gear",
|
icon="fa.gear",
|
||||||
),
|
),
|
||||||
|
@ -728,7 +728,6 @@ def comboboxcallbackwrap(internal, d, k, call, _):
|
|||||||
print_exc()
|
print_exc()
|
||||||
|
|
||||||
|
|
||||||
@tryprint
|
|
||||||
def getsimplecombobox(
|
def getsimplecombobox(
|
||||||
lst, d, k, callback=None, fixedsize=False, internal=None, static=False, emit=False
|
lst, d, k, callback=None, fixedsize=False, internal=None, static=False, emit=False
|
||||||
):
|
):
|
||||||
@ -740,18 +739,20 @@ def getsimplecombobox(
|
|||||||
s.addItems(lst)
|
s.addItems(lst)
|
||||||
|
|
||||||
if internal:
|
if internal:
|
||||||
if (k not in d) or (d[k] not in internal):
|
if len(internal):
|
||||||
d[k] = internal[0]
|
if (k not in d) or (d[k] not in internal):
|
||||||
|
d[k] = internal[0]
|
||||||
|
|
||||||
s.setCurrentIndex(internal.index(d[k]))
|
s.setCurrentIndex(internal.index(d[k]))
|
||||||
s.currentIndexChanged.connect(
|
s.currentIndexChanged.connect(
|
||||||
functools.partial(comboboxcallbackwrap, internal, d, k, callback)
|
functools.partial(comboboxcallbackwrap, internal, d, k, callback)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if (k not in d) or (d[k] >= len(lst)):
|
if len(lst):
|
||||||
d[k] = 0
|
if (k not in d) or (d[k] >= len(lst)):
|
||||||
|
d[k] = 0
|
||||||
|
|
||||||
s.setCurrentIndex(d[k])
|
s.setCurrentIndex(d[k])
|
||||||
s.currentIndexChanged.connect(functools.partial(callbackwrap, d, k, callback))
|
s.currentIndexChanged.connect(functools.partial(callbackwrap, d, k, callback))
|
||||||
if fixedsize:
|
if fixedsize:
|
||||||
s.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
|
s.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
|
||||||
@ -1743,6 +1744,9 @@ class listediter(LDialog):
|
|||||||
table.customContextMenuRequested.connect(self.showmenu)
|
table.customContextMenuRequested.connect(self.showmenu)
|
||||||
self.hctable = table
|
self.hctable = table
|
||||||
self.internalrealname = []
|
self.internalrealname = []
|
||||||
|
formLayout = QVBoxLayout()
|
||||||
|
self.setLayout(formLayout)
|
||||||
|
formLayout.addWidget(self.hctable)
|
||||||
for row, k in enumerate(lst): # 2
|
for row, k in enumerate(lst): # 2
|
||||||
try:
|
try:
|
||||||
if namemapfunction:
|
if namemapfunction:
|
||||||
@ -1752,9 +1756,20 @@ class listediter(LDialog):
|
|||||||
self.internalrealname.append(k)
|
self.internalrealname.append(k)
|
||||||
if namemapfunction:
|
if namemapfunction:
|
||||||
k = namemapfunction(k)
|
k = namemapfunction(k)
|
||||||
self.hcmodel.insertRow(row, [QStandardItem(k)])
|
item = QStandardItem(k)
|
||||||
formLayout = QVBoxLayout()
|
self.hcmodel.insertRow(row, [item])
|
||||||
formLayout.addWidget(self.hctable)
|
|
||||||
|
if candidates:
|
||||||
|
combo = LFocusCombo()
|
||||||
|
_vis = self.candidates
|
||||||
|
if self.namemapfunction:
|
||||||
|
_vis = [self.namemapfunction(_) for _ in _vis]
|
||||||
|
combo.addItems(_vis)
|
||||||
|
combo.setCurrentIndex(self.candidates.index(lst[row]))
|
||||||
|
combo.currentIndexChanged.connect(
|
||||||
|
functools.partial(self.__changed, item)
|
||||||
|
)
|
||||||
|
self.hctable.setIndexWidget(self.hcmodel.index(row, 0), combo)
|
||||||
if isrankeditor:
|
if isrankeditor:
|
||||||
self.buttons = threebuttons(texts=["上移", "下移"])
|
self.buttons = threebuttons(texts=["上移", "下移"])
|
||||||
self.buttons.btn1clicked.connect(functools.partial(self.moverank, -1))
|
self.buttons.btn1clicked.connect(functools.partial(self.moverank, -1))
|
||||||
@ -1771,7 +1786,6 @@ class listediter(LDialog):
|
|||||||
self.buttons.btn4clicked.connect(functools.partial(self.moverank, 1))
|
self.buttons.btn4clicked.connect(functools.partial(self.moverank, 1))
|
||||||
|
|
||||||
formLayout.addWidget(self.buttons)
|
formLayout.addWidget(self.buttons)
|
||||||
self.setLayout(formLayout)
|
|
||||||
self.resize(600, self.sizeHint().height())
|
self.resize(600, self.sizeHint().height())
|
||||||
self.show()
|
self.show()
|
||||||
except:
|
except:
|
||||||
@ -1811,28 +1825,23 @@ class listediter(LDialog):
|
|||||||
|
|
||||||
def __cb(self, paths):
|
def __cb(self, paths):
|
||||||
for path in paths:
|
for path in paths:
|
||||||
self.internalrealname.insert(0, paths)
|
self.internalrealname.insert(0, path)
|
||||||
self.hcmodel.insertRow(0, [QStandardItem(path)])
|
self.hcmodel.insertRow(0, [QStandardItem(path)])
|
||||||
|
|
||||||
def __changed(self, idx):
|
def __changed(self, item: QStandardItem, idx):
|
||||||
self.internalrealname[self.hctable.currentIndex().row()] = self.candidates[idx]
|
self.internalrealname[item.row()] = self.candidates[idx]
|
||||||
|
|
||||||
def click1(self):
|
def click1(self):
|
||||||
if self.candidates:
|
if self.candidates:
|
||||||
if len(self.internalrealname):
|
|
||||||
_vis = self.internalrealname[0]
|
|
||||||
self.hctable.setIndexWidget(self.hcmodel.index(0, 0), None)
|
|
||||||
if self.namemapfunction:
|
|
||||||
_vis = self.namemapfunction(_vis)
|
|
||||||
self.hcmodel.setItem(0, 0, QStandardItem(_vis))
|
|
||||||
self.internalrealname.insert(0, self.candidates[0])
|
self.internalrealname.insert(0, self.candidates[0])
|
||||||
self.hcmodel.insertRow(0, [QStandardItem("")])
|
item = QStandardItem("")
|
||||||
|
self.hcmodel.insertRow(0, [item])
|
||||||
combo = LFocusCombo()
|
combo = LFocusCombo()
|
||||||
_vis = self.candidates
|
_vis = self.candidates
|
||||||
if self.namemapfunction:
|
if self.namemapfunction:
|
||||||
_vis = [self.namemapfunction(_) for _ in _vis]
|
_vis = [self.namemapfunction(_) for _ in _vis]
|
||||||
combo.addItems(_vis)
|
combo.addItems(_vis)
|
||||||
combo.currentIndexChanged.connect(self.__changed)
|
combo.currentIndexChanged.connect(functools.partial(self.__changed, item))
|
||||||
self.hctable.setIndexWidget(self.hcmodel.index(0, 0), combo)
|
self.hctable.setIndexWidget(self.hcmodel.index(0, 0), combo)
|
||||||
elif self.ispathsedit is None:
|
elif self.ispathsedit is None:
|
||||||
self.internalrealname.insert(0, "")
|
self.internalrealname.insert(0, "")
|
||||||
@ -1920,8 +1929,10 @@ def getsimplepatheditor(
|
|||||||
e.setReadOnly(True)
|
e.setReadOnly(True)
|
||||||
if useiconbutton:
|
if useiconbutton:
|
||||||
bu = getIconButton(icon="fa.gear")
|
bu = getIconButton(icon="fa.gear")
|
||||||
|
clear = getIconButton(icon="fa.remove")
|
||||||
else:
|
else:
|
||||||
bu = LPushButton("选择" + ("文件夹" if isdir else "文件"))
|
bu = LPushButton("选择" + ("文件夹" if isdir else "文件"))
|
||||||
|
clear = LPushButton("清除")
|
||||||
bu.clicked.connect(
|
bu.clicked.connect(
|
||||||
functools.partial(
|
functools.partial(
|
||||||
openfiledirectory,
|
openfiledirectory,
|
||||||
@ -1933,8 +1944,15 @@ def getsimplepatheditor(
|
|||||||
callback,
|
callback,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __(_cb, _e):
|
||||||
|
_cb("")
|
||||||
|
_e.setText("")
|
||||||
|
|
||||||
|
clear.clicked.connect(functools.partial(__, callback, e))
|
||||||
lay.addWidget(e)
|
lay.addWidget(e)
|
||||||
lay.addWidget(bu)
|
lay.addWidget(bu)
|
||||||
|
lay.addWidget(clear)
|
||||||
return lay
|
return lay
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ allsubprocess2 = {}
|
|||||||
|
|
||||||
|
|
||||||
class autoproc:
|
class autoproc:
|
||||||
def __init__(self, proc) -> None:
|
def __init__(self, proc: subprocess.Popen) -> None:
|
||||||
self.proc = proc
|
self.proc = proc
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
@ -15,7 +15,9 @@ class autoproc:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def subproc_w(cmd, cwd=None, needstdio=False, name=None, encoding=None, run=False):
|
def subproc_w(
|
||||||
|
cmd, cwd=None, needstdio=False, name=None, encoding=None, run=False
|
||||||
|
) -> subprocess.Popen:
|
||||||
|
|
||||||
_pipe = subprocess.PIPE if needstdio else None
|
_pipe = subprocess.PIPE if needstdio else None
|
||||||
startupinfo = subprocess.STARTUPINFO()
|
startupinfo = subprocess.STARTUPINFO()
|
||||||
|
@ -67,19 +67,6 @@ class TS(basetrans):
|
|||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def packuint32(self, i): # int -> str
|
|
||||||
return bytes(
|
|
||||||
chr((i >> 24) & 0xFF)
|
|
||||||
+ chr((i >> 16) & 0xFF)
|
|
||||||
+ chr((i >> 8) & 0xFF)
|
|
||||||
+ chr(i & 0xFF),
|
|
||||||
encoding="latin-1",
|
|
||||||
)
|
|
||||||
|
|
||||||
def unpackuint32(self, s): #
|
|
||||||
print(s)
|
|
||||||
return ((s[0]) << 24) | ((s[1]) << 16) | ((s[2]) << 8) | (s[3])
|
|
||||||
|
|
||||||
def x64(self, content: str):
|
def x64(self, content: str):
|
||||||
if self.tgtlang not in ["936", "950"]:
|
if self.tgtlang not in ["936", "950"]:
|
||||||
return ""
|
return ""
|
||||||
@ -93,7 +80,8 @@ class TS(basetrans):
|
|||||||
if len(line) == 0:
|
if len(line) == 0:
|
||||||
continue
|
continue
|
||||||
code1 = line.encode("utf-16-le")
|
code1 = line.encode("utf-16-le")
|
||||||
windows.WriteFile(self.hPipe, self.packuint32(int(self.tgtlang)) + code1)
|
windows.WriteFile(self.hPipe, bytes(ctypes.c_uint(int(self.tgtlang))))
|
||||||
|
windows.WriteFile(self.hPipe, code1)
|
||||||
xx = windows.ReadFile(self.hPipe, 65535)
|
xx = windows.ReadFile(self.hPipe, 65535)
|
||||||
xx = xx.decode("utf-16-le", errors="ignore")
|
xx = xx.decode("utf-16-le", errors="ignore")
|
||||||
ress.append(xx)
|
ress.append(xx)
|
||||||
|
@ -8,65 +8,47 @@ from ctypes import cast, POINTER, c_char, c_int32
|
|||||||
|
|
||||||
|
|
||||||
class TTS(TTSbase):
|
class TTS(TTSbase):
|
||||||
def checkchange(self):
|
def init(self):
|
||||||
exepath = os.path.join(os.getcwd(), "files/plugins/shareddllproxy32.exe")
|
exepath = os.path.join(os.getcwd(), "files/plugins/shareddllproxy32.exe")
|
||||||
t = time.time()
|
t = time.time()
|
||||||
t = str(t)
|
t = str(t)
|
||||||
pipename = "\\\\.\\Pipe\\voiceroid2_" + t
|
pipename = "\\\\.\\Pipe\\voiceroid2_" + t
|
||||||
waitsignal = "voiceroid2waitload_" + t
|
waitsignal = "voiceroid2waitload_" + t
|
||||||
mapname = "voiceroid2filemap" + t
|
mapname = "voiceroid2filemap" + t
|
||||||
idx = self.privateconfig["voice"].split("_")[-1]
|
|
||||||
hkey = self.privateconfig["voice"][: -len(idx) - 1]
|
|
||||||
|
|
||||||
if self.voicexx != (hkey, idx):
|
cmd = '"{}" neospeech {} {} {}'.format(exepath, pipename, waitsignal, mapname)
|
||||||
self.voicexx = (hkey, idx)
|
|
||||||
cmd = '"{}" neospeech {} {} {} {} {} '.format(
|
|
||||||
exepath, pipename, waitsignal, mapname, hkey, idx
|
|
||||||
)
|
|
||||||
|
|
||||||
self.engine = autoproc(subproc_w(cmd, name="neospeech"))
|
self.engine = autoproc(subproc_w(cmd, name=str(time.time())))
|
||||||
|
|
||||||
windows.WaitForSingleObject(
|
windows.WaitForSingleObject(
|
||||||
windows.AutoHandle(windows.CreateEvent(False, False, waitsignal)),
|
windows.AutoHandle(windows.CreateEvent(False, False, waitsignal)),
|
||||||
windows.INFINITE,
|
windows.INFINITE,
|
||||||
)
|
)
|
||||||
windows.WaitNamedPipe(pipename, windows.NMPWAIT_WAIT_FOREVER)
|
windows.WaitNamedPipe(pipename, windows.NMPWAIT_WAIT_FOREVER)
|
||||||
self.hPipe = windows.AutoHandle(
|
self.hPipe = windows.AutoHandle(
|
||||||
windows.CreateFile(
|
windows.CreateFile(
|
||||||
pipename,
|
pipename,
|
||||||
windows.GENERIC_READ | windows.GENERIC_WRITE,
|
windows.GENERIC_READ | windows.GENERIC_WRITE,
|
||||||
0,
|
|
||||||
None,
|
|
||||||
windows.OPEN_EXISTING,
|
|
||||||
windows.FILE_ATTRIBUTE_NORMAL,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.mappedFile2 = windows.AutoHandle(
|
|
||||||
windows.OpenFileMapping(
|
|
||||||
windows.FILE_MAP_READ | windows.FILE_MAP_WRITE, False, mapname
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self.mem = windows.MapViewOfFile(
|
|
||||||
self.mappedFile2,
|
|
||||||
windows.FILE_MAP_READ | windows.FILE_MAP_WRITE,
|
|
||||||
0,
|
0,
|
||||||
0,
|
None,
|
||||||
1024 * 1024 * 10,
|
windows.OPEN_EXISTING,
|
||||||
|
windows.FILE_ATTRIBUTE_NORMAL,
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def init(self):
|
self.mappedFile2 = windows.AutoHandle(
|
||||||
|
windows.OpenFileMapping(
|
||||||
self.voicexx = (0, 0)
|
windows.FILE_MAP_READ | windows.FILE_MAP_WRITE, False, mapname
|
||||||
self.voicelist = self.getvoicelist()
|
)
|
||||||
|
)
|
||||||
def voiceshowmap(self, voice):
|
self.mem = windows.MapViewOfFile(
|
||||||
|
self.mappedFile2,
|
||||||
idx = voice.split("_")[-1]
|
windows.FILE_MAP_READ | windows.FILE_MAP_WRITE,
|
||||||
hk = voice[: -len(idx) - 1]
|
0,
|
||||||
|
0,
|
||||||
return self.mapx[(hk, idx)]
|
1024 * 1024 * 10,
|
||||||
|
)
|
||||||
|
|
||||||
def getvoicelist(self):
|
def getvoicelist(self):
|
||||||
cachefname = gobject.gettempdir(f"{time.time()}.txt")
|
cachefname = gobject.gettempdir(f"{time.time()}.txt")
|
||||||
@ -75,23 +57,22 @@ class TTS(TTSbase):
|
|||||||
|
|
||||||
with open(cachefname, "r", encoding="utf-16-le") as ff:
|
with open(cachefname, "r", encoding="utf-16-le") as ff:
|
||||||
readf = ff.read()
|
readf = ff.read()
|
||||||
|
print(readf)
|
||||||
os.remove(cachefname)
|
os.remove(cachefname)
|
||||||
datas = (readf.split("\n"))[:-1]
|
datas = (readf.split("\n"))[:-1]
|
||||||
|
internal = []
|
||||||
self.mapx = {}
|
vis = []
|
||||||
xx = []
|
|
||||||
for i in range(len(datas) // 3):
|
for i in range(len(datas) // 3):
|
||||||
self.mapx[(datas[i * 3 + 1], datas[i * 3 + 2])] = datas[i * 3]
|
internal.append((datas[i * 3 + 1], datas[i * 3 + 2]))
|
||||||
xx.append("{}_{}".format(datas[i * 3 + 1], datas[i * 3 + 2]))
|
vis.append(datas[i * 3])
|
||||||
|
return internal, vis
|
||||||
|
|
||||||
return xx
|
def speak(self, content, rate, voice):
|
||||||
|
hkey, idx = voice
|
||||||
def speak(self, content, rate, voice, voice_idx):
|
|
||||||
self.checkchange()
|
|
||||||
windows.WriteFile(self.hPipe, bytes(ctypes.c_uint(rate)))
|
windows.WriteFile(self.hPipe, bytes(ctypes.c_uint(rate)))
|
||||||
buf = ctypes.create_unicode_buffer(content, 10000)
|
windows.WriteFile(self.hPipe, content.encode("utf-16-le"))
|
||||||
windows.WriteFile(self.hPipe, bytes(buf))
|
windows.WriteFile(self.hPipe, hkey.encode("utf-16-le"))
|
||||||
|
windows.WriteFile(self.hPipe, bytes(ctypes.c_uint(int(idx))))
|
||||||
size = c_int32.from_buffer_copy(windows.ReadFile(self.hPipe, 4)).value
|
size = c_int32.from_buffer_copy(windows.ReadFile(self.hPipe, 4)).value
|
||||||
|
|
||||||
return cast(self.mem, POINTER(c_char))[:size]
|
return cast(self.mem, POINTER(c_char))[:size]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from myutils.config import globalconfig
|
from myutils.config import globalconfig
|
||||||
import threading, os, functools
|
import functools, threading
|
||||||
from myutils.wrapper import threader
|
from myutils.wrapper import threader
|
||||||
from traceback import print_exc
|
from traceback import print_exc
|
||||||
from myutils.proxy import getproxy
|
from myutils.proxy import getproxy
|
||||||
@ -8,16 +8,12 @@ from myutils.proxy import getproxy
|
|||||||
class TTSbase:
|
class TTSbase:
|
||||||
typename = None
|
typename = None
|
||||||
|
|
||||||
def init(self):
|
def init(self): ...
|
||||||
pass
|
|
||||||
|
|
||||||
def getvoicelist(self):
|
def getvoicelist(self):
|
||||||
return []
|
# 分别返回内部标识名,显示
|
||||||
|
return [], []
|
||||||
|
|
||||||
def voiceshowmap(self, voice):
|
def speak(self, content, rate, voice):
|
||||||
return voice
|
|
||||||
|
|
||||||
def speak(self, content, rate, volume, voice, voiceindex):
|
|
||||||
return None # fname ,若为None则是不需要文件直接朗读
|
return None # fname ,若为None则是不需要文件直接朗读
|
||||||
|
|
||||||
####################
|
####################
|
||||||
@ -28,68 +24,79 @@ class TTSbase:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def config(self):
|
def config(self):
|
||||||
return self.privateconfig["args"]
|
return globalconfig["reader"][self.typename]["args"]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def privateconfig(self):
|
def volume(self):
|
||||||
return globalconfig["reader"][self.typename]
|
return globalconfig["ttscommon"]["volume"]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def publicconfig(self):
|
def rate(self):
|
||||||
return globalconfig["ttscommon"]
|
return globalconfig["ttscommon"]["rate"]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def voice(self):
|
||||||
|
_v = self.privateconfig["voice"]
|
||||||
|
if len(self.voicelist) == 0:
|
||||||
|
return None
|
||||||
|
if _v not in self.voicelist:
|
||||||
|
_v = self.voicelist[0]
|
||||||
|
return _v
|
||||||
|
|
||||||
########################
|
########################
|
||||||
|
|
||||||
def __init__(self, typename, showlistsignal, playaudiofunction) -> None:
|
def __init__(
|
||||||
|
self,
|
||||||
|
typename,
|
||||||
|
voicelistsignal,
|
||||||
|
playaudiofunction,
|
||||||
|
privateconfig=None,
|
||||||
|
init=True,
|
||||||
|
) -> None:
|
||||||
self.typename = typename
|
self.typename = typename
|
||||||
self.showlistsignal = showlistsignal
|
self.voicelistsignal = voicelistsignal
|
||||||
self.playaudiofunction = playaudiofunction
|
self.playaudiofunction = playaudiofunction
|
||||||
self.loadok = False
|
|
||||||
|
|
||||||
def _():
|
if privateconfig is None:
|
||||||
|
self.privateconfig = globalconfig["reader"][self.typename]
|
||||||
|
else:
|
||||||
|
self.privateconfig = privateconfig
|
||||||
|
self.voicelist, self.voiceshowlist = self.getvoicelist()
|
||||||
|
voicelistsignal.emit(self)
|
||||||
|
if init:
|
||||||
self.init()
|
self.init()
|
||||||
self.voicelist = self.getvoicelist()
|
|
||||||
self.voiceshowlist = []
|
|
||||||
for k in self.voicelist:
|
|
||||||
try:
|
|
||||||
_v = self.voiceshowmap(k)
|
|
||||||
except:
|
|
||||||
_v = k
|
|
||||||
self.voiceshowlist.append(_v)
|
|
||||||
if self.privateconfig["voice"] not in self.voicelist:
|
|
||||||
self.privateconfig["voice"] = self.voicelist[0]
|
|
||||||
|
|
||||||
showlistsignal.emit(
|
|
||||||
self.voiceshowlist,
|
|
||||||
self.voicelist.index(self.privateconfig["voice"]),
|
|
||||||
)
|
|
||||||
self.loadok = True
|
|
||||||
|
|
||||||
threading.Thread(target=_).start()
|
|
||||||
|
|
||||||
def read(self, content, force=False):
|
def read(self, content, force=False):
|
||||||
volume = self.publicconfig["volume"]
|
|
||||||
|
|
||||||
def _(force, volume, data):
|
def _(force, volume, data):
|
||||||
self.playaudiofunction(data, volume, force)
|
self.playaudiofunction(data, volume, force)
|
||||||
|
|
||||||
self.ttscallback(content, functools.partial(_, force, volume))
|
self.ttscallback(content, functools.partial(_, force, self.volume))
|
||||||
|
|
||||||
@threader
|
@threader
|
||||||
def ttscallback(self, content, callback):
|
def ttscallback(self, content, callback):
|
||||||
if self.loadok == False:
|
|
||||||
return
|
|
||||||
if len(content) == 0:
|
if len(content) == 0:
|
||||||
return
|
return
|
||||||
if len(self.voicelist) == 0:
|
if len(self.voicelist) == 0:
|
||||||
return
|
return
|
||||||
rate = self.publicconfig["rate"]
|
|
||||||
voice = self.privateconfig["voice"]
|
|
||||||
voice_index = self.voicelist.index(voice)
|
|
||||||
try:
|
try:
|
||||||
data = self.speak(content, rate, voice, voice_index)
|
data = self.speak(content, self.rate, self.voice)
|
||||||
if data and len(data):
|
if data and len(data):
|
||||||
callback(data)
|
callback(data)
|
||||||
except:
|
except:
|
||||||
print_exc()
|
print_exc()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def getvisidx(obj: TTSbase):
|
||||||
|
if obj is None:
|
||||||
|
vl = []
|
||||||
|
idx = -1
|
||||||
|
else:
|
||||||
|
vl = obj.voiceshowlist
|
||||||
|
if obj.voice:
|
||||||
|
idx = obj.voicelist.index(obj.voice)
|
||||||
|
else:
|
||||||
|
idx = -1
|
||||||
|
return vl, idx
|
||||||
|
@ -14,13 +14,13 @@ from tts.basettsclass import TTSbase
|
|||||||
class TTS(TTSbase):
|
class TTS(TTSbase):
|
||||||
|
|
||||||
def getvoicelist(self):
|
def getvoicelist(self):
|
||||||
self.alllist = requests.get(
|
alllist = requests.get(
|
||||||
"https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list?trustedclienttoken=6A5AA1D4EAFF4E9FB37E23D68491D6F4",
|
"https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list?trustedclienttoken=6A5AA1D4EAFF4E9FB37E23D68491D6F4",
|
||||||
proxies=self.proxy,
|
proxies=self.proxy,
|
||||||
).json()
|
).json()
|
||||||
return [_["ShortName"] for _ in self.alllist]
|
return [_["ShortName"] for _ in alllist], [_["ShortName"] for _ in alllist]
|
||||||
|
|
||||||
def speak(self, content, rate, voice, voiceidx):
|
def speak(self, content, rate, voice):
|
||||||
return transferMsTTSData(rate, content, voice, self.proxy)
|
return transferMsTTSData(rate, content, voice, self.proxy)
|
||||||
|
|
||||||
|
|
||||||
|
@ -603,8 +603,8 @@ from myutils.utils import getlangsrc
|
|||||||
|
|
||||||
class TTS(TTSbase):
|
class TTS(TTSbase):
|
||||||
def getvoicelist(self):
|
def getvoicelist(self):
|
||||||
return [""]
|
return [""], [""]
|
||||||
|
|
||||||
def speak(self, content, rate, voice, voiceidx):
|
def speak(self, content, rate, voice):
|
||||||
tts = gTTS(self, content, lang=getlangsrc())
|
tts = gTTS(self, content, lang=getlangsrc())
|
||||||
return tts.save()
|
return tts.save()
|
||||||
|
@ -6,7 +6,7 @@ from tts.basettsclass import TTSbase
|
|||||||
|
|
||||||
class TTS(TTSbase):
|
class TTS(TTSbase):
|
||||||
def getvoicelist(self):
|
def getvoicelist(self):
|
||||||
return [
|
_= [
|
||||||
"jp_male_satoshi",
|
"jp_male_satoshi",
|
||||||
"jp_female_mai",
|
"jp_female_mai",
|
||||||
"zh_male_rap",
|
"zh_male_rap",
|
||||||
@ -20,8 +20,9 @@ class TTS(TTSbase):
|
|||||||
"en_male_bob",
|
"en_male_bob",
|
||||||
"en_female_sarah",
|
"en_female_sarah",
|
||||||
]
|
]
|
||||||
|
return _, _
|
||||||
|
|
||||||
def speak(self, content, rate, voice, voiceidx):
|
def speak(self, content, rate, voice):
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
"authority": "translate.volcengine.com",
|
"authority": "translate.volcengine.com",
|
||||||
|
@ -9,7 +9,7 @@ class TTS(TTSbase):
|
|||||||
responseVits = requests.get(
|
responseVits = requests.get(
|
||||||
f"http://127.0.0.1:{self.config['Port']}/voice/speakers"
|
f"http://127.0.0.1:{self.config['Port']}/voice/speakers"
|
||||||
).json()
|
).json()
|
||||||
self.voicelist = []
|
voicelist = []
|
||||||
|
|
||||||
# 获取所有模型类型,对于每个模型类型下的模型信息,将其 modelType、id、name 合成一个字符串
|
# 获取所有模型类型,对于每个模型类型下的模型信息,将其 modelType、id、name 合成一个字符串
|
||||||
modelTypes = responseVits.keys()
|
modelTypes = responseVits.keys()
|
||||||
@ -17,13 +17,10 @@ class TTS(TTSbase):
|
|||||||
vits_data = responseVits[modelType]
|
vits_data = responseVits[modelType]
|
||||||
for item in vits_data:
|
for item in vits_data:
|
||||||
model_info = f'{modelType}_{item["id"]}_{item["name"]}'
|
model_info = f'{modelType}_{item["id"]}_{item["name"]}'
|
||||||
self.voicelist.append(model_info)
|
voicelist.append(model_info)
|
||||||
return self.voicelist
|
return voicelist, voicelist
|
||||||
|
|
||||||
def voiceshowmap(self, voice):
|
def speak(self, content, rate, voice):
|
||||||
return voice
|
|
||||||
|
|
||||||
def speak(self, content, rate, voice, voiceidx):
|
|
||||||
encoded_content = quote(content)
|
encoded_content = quote(content)
|
||||||
idx = int(voice.split("_")[1])
|
idx = int(voice.split("_")[1])
|
||||||
model = str.lower(voice.split("_")[0])
|
model = str.lower(voice.split("_")[0])
|
||||||
|
@ -2,19 +2,11 @@ import time
|
|||||||
import os
|
import os
|
||||||
import windows
|
import windows
|
||||||
from tts.basettsclass import TTSbase
|
from tts.basettsclass import TTSbase
|
||||||
from ctypes import cast, POINTER, c_char, c_int32
|
from ctypes import cast, POINTER, c_char, c_int32, c_float
|
||||||
from myutils.subproc import subproc_w, autoproc
|
from myutils.subproc import subproc_w, autoproc
|
||||||
import threading
|
|
||||||
|
|
||||||
|
|
||||||
class TTS(TTSbase):
|
class TTS(TTSbase):
|
||||||
|
|
||||||
def init(self):
|
|
||||||
self.status = None
|
|
||||||
|
|
||||||
self.voicelist = self.getvoicelist()
|
|
||||||
threading.Thread(target=self.checkpath).start()
|
|
||||||
|
|
||||||
def getvoicelist(self):
|
def getvoicelist(self):
|
||||||
voicelist = []
|
voicelist = []
|
||||||
if os.path.exists(self.config["path"]) == False:
|
if os.path.exists(self.config["path"]) == False:
|
||||||
@ -27,7 +19,7 @@ class TTS(TTSbase):
|
|||||||
if len(_l) >= 2:
|
if len(_l) >= 2:
|
||||||
if _l[-1] == "44" or _l[-1] == "22":
|
if _l[-1] == "44" or _l[-1] == "22":
|
||||||
voicelist.append(_)
|
voicelist.append(_)
|
||||||
return voicelist
|
return voicelist, [self.voiceshowmap(_) for _ in voicelist]
|
||||||
|
|
||||||
def voiceshowmap(self, voice):
|
def voiceshowmap(self, voice):
|
||||||
name = voice.split("_")[0]
|
name = voice.split("_")[0]
|
||||||
@ -56,98 +48,77 @@ class TTS(TTSbase):
|
|||||||
vv += "(関西弁)"
|
vv += "(関西弁)"
|
||||||
return vv
|
return vv
|
||||||
|
|
||||||
def checkpath(self):
|
def init(self):
|
||||||
if self.config["path"] == "":
|
dllpath = os.path.join(self.config["path"], "aitalked.dll")
|
||||||
return False
|
exepath = os.path.join(os.getcwd(), "files/plugins/shareddllproxy32.exe")
|
||||||
if os.path.exists(self.config["path"]) == False:
|
|
||||||
return False
|
|
||||||
if (
|
|
||||||
self.config["path"],
|
|
||||||
self.privateconfig["voice"],
|
|
||||||
self.publicconfig["rate"],
|
|
||||||
) != self.status:
|
|
||||||
dllpath = os.path.join(self.config["path"], "aitalked.dll")
|
|
||||||
##dllpath=r'C:\Users\wcy\Downloads\zunko\aitalked.dll'
|
|
||||||
exepath = os.path.join(os.getcwd(), "files/plugins/shareddllproxy32.exe")
|
|
||||||
|
|
||||||
t = time.time()
|
t = time.time()
|
||||||
t = str(t)
|
t = str(t)
|
||||||
pipename = "\\\\.\\Pipe\\voiceroid2_" + t
|
pipename = "\\\\.\\Pipe\\voiceroid2_" + t
|
||||||
waitsignal = "voiceroid2waitload_" + t
|
waitsignal = "voiceroid2waitload_" + t
|
||||||
mapname = "voiceroid2filemap" + t
|
mapname = "voiceroid2filemap" + t
|
||||||
|
|
||||||
def linear_map(x):
|
self.engine = autoproc(
|
||||||
if x >= 0:
|
subproc_w(
|
||||||
x = 0.1 * x + 1.0
|
'"{}" voiceroid2 "{}" "{}" {} {} {}'.format(
|
||||||
else:
|
exepath,
|
||||||
x = 0.05 * x + 1.0
|
self.config["path"],
|
||||||
return x
|
dllpath,
|
||||||
|
|
||||||
"".endswith
|
|
||||||
if self.privateconfig["voice"].endswith("_44"):
|
|
||||||
_1 = 44100
|
|
||||||
_2 = linear_map(self.publicconfig["rate"])
|
|
||||||
elif self.privateconfig["voice"].endswith("_22"):
|
|
||||||
_1 = 22050
|
|
||||||
_2 = 0
|
|
||||||
self.engine = autoproc(
|
|
||||||
subproc_w(
|
|
||||||
'"{}" voiceroid2 "{}" "{}" {} {} {} {} {} {}'.format(
|
|
||||||
exepath,
|
|
||||||
self.config["path"],
|
|
||||||
dllpath,
|
|
||||||
self.privateconfig["voice"],
|
|
||||||
_1,
|
|
||||||
_2,
|
|
||||||
pipename,
|
|
||||||
waitsignal,
|
|
||||||
mapname,
|
|
||||||
),
|
|
||||||
name="voicevoid2",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
windows.WaitForSingleObject(
|
|
||||||
windows.AutoHandle(windows.CreateEvent(False, False, waitsignal)),
|
|
||||||
windows.INFINITE,
|
|
||||||
)
|
|
||||||
windows.WaitNamedPipe(pipename, windows.NMPWAIT_WAIT_FOREVER)
|
|
||||||
self.hPipe = windows.AutoHandle(
|
|
||||||
windows.CreateFile(
|
|
||||||
pipename,
|
pipename,
|
||||||
windows.GENERIC_READ | windows.GENERIC_WRITE,
|
waitsignal,
|
||||||
0,
|
mapname,
|
||||||
None,
|
),
|
||||||
windows.OPEN_EXISTING,
|
name=str(time.time()),
|
||||||
windows.FILE_ATTRIBUTE_NORMAL,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
self.mappedFile2 = windows.AutoHandle(
|
)
|
||||||
windows.OpenFileMapping(
|
windows.WaitForSingleObject(
|
||||||
windows.FILE_MAP_READ | windows.FILE_MAP_WRITE, False, mapname
|
windows.AutoHandle(windows.CreateEvent(False, False, waitsignal)),
|
||||||
)
|
windows.INFINITE,
|
||||||
)
|
)
|
||||||
self.mem = windows.MapViewOfFile(
|
windows.WaitNamedPipe(pipename, windows.NMPWAIT_WAIT_FOREVER)
|
||||||
self.mappedFile2,
|
self.hPipe = windows.AutoHandle(
|
||||||
windows.FILE_MAP_READ | windows.FILE_MAP_WRITE,
|
windows.CreateFile(
|
||||||
|
pipename,
|
||||||
|
windows.GENERIC_READ | windows.GENERIC_WRITE,
|
||||||
0,
|
0,
|
||||||
0,
|
None,
|
||||||
1024 * 1024 * 10,
|
windows.OPEN_EXISTING,
|
||||||
|
windows.FILE_ATTRIBUTE_NORMAL,
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
|
)
|
||||||
self.status = (
|
self.mappedFile2 = windows.AutoHandle(
|
||||||
self.config["path"],
|
windows.OpenFileMapping(
|
||||||
self.privateconfig["voice"],
|
windows.FILE_MAP_READ | windows.FILE_MAP_WRITE, False, mapname
|
||||||
self.publicconfig["rate"],
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
self.mem = windows.MapViewOfFile(
|
||||||
|
self.mappedFile2,
|
||||||
|
windows.FILE_MAP_READ | windows.FILE_MAP_WRITE,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1024 * 1024 * 10,
|
||||||
|
)
|
||||||
|
|
||||||
def speak(self, content, rate, voice, voice_idx):
|
def linear_map(self, x):
|
||||||
self.checkpath()
|
if x >= 0:
|
||||||
|
x = 0.1 * x + 1.0
|
||||||
|
else:
|
||||||
|
x = 0.05 * x + 1.0
|
||||||
|
return x
|
||||||
|
|
||||||
|
def speak(self, content, rate, voice):
|
||||||
|
|
||||||
|
if voice.endswith("_44"):
|
||||||
|
_2 = self.linear_map(rate)
|
||||||
|
elif voice.endswith("_22"):
|
||||||
|
_2 = 0
|
||||||
try:
|
try:
|
||||||
code1 = content.encode("shift-jis")
|
code1 = content.encode("shift-jis")
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
|
windows.WriteFile(self.hPipe, voice.encode())
|
||||||
|
windows.WriteFile(self.hPipe, bytes(c_float(_2)))
|
||||||
windows.WriteFile(self.hPipe, code1)
|
windows.WriteFile(self.hPipe, code1)
|
||||||
|
|
||||||
size = c_int32.from_buffer_copy(windows.ReadFile(self.hPipe, 4)).value
|
size = c_int32.from_buffer_copy(windows.ReadFile(self.hPipe, 4)).value
|
||||||
|
@ -1,31 +1,11 @@
|
|||||||
import time
|
import time
|
||||||
import os
|
|
||||||
import requests, json
|
import requests, json
|
||||||
from traceback import print_exc
|
from traceback import print_exc
|
||||||
from tts.basettsclass import TTSbase
|
from tts.basettsclass import TTSbase
|
||||||
|
|
||||||
from myutils.subproc import subproc_w, autoproc
|
|
||||||
|
|
||||||
|
|
||||||
class TTS(TTSbase):
|
class TTS(TTSbase):
|
||||||
|
|
||||||
def init(self):
|
|
||||||
for cwd in (
|
|
||||||
self.config["path"],
|
|
||||||
os.path.join(self.config["path"], "vv-engine"),
|
|
||||||
):
|
|
||||||
run = os.path.join(cwd, "run.exe")
|
|
||||||
if os.path.exists(run) == False:
|
|
||||||
return
|
|
||||||
self.engine = autoproc(
|
|
||||||
subproc_w(
|
|
||||||
run,
|
|
||||||
cwd=cwd,
|
|
||||||
name="voicevox",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
break
|
|
||||||
|
|
||||||
def getvoicelist(self):
|
def getvoicelist(self):
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
@ -53,32 +33,27 @@ class TTS(TTSbase):
|
|||||||
proxies={"http": None, "https": None},
|
proxies={"http": None, "https": None},
|
||||||
).json()
|
).json()
|
||||||
print(response)
|
print(response)
|
||||||
# self.voicelist=[_['name'] for _ in response]
|
vis=[]
|
||||||
# return self.voicelist
|
idxs=[]
|
||||||
voicedict = {}
|
|
||||||
for speaker in response:
|
for speaker in response:
|
||||||
|
name=speaker['name']
|
||||||
styles = speaker["styles"]
|
styles = speaker["styles"]
|
||||||
for style in styles:
|
for style in styles:
|
||||||
voicedict[style["id"]] = "%s(%s)" % (
|
idxs.append(style['id'])
|
||||||
speaker["name"],
|
vis.append(name+ ' '+ style["name"])
|
||||||
style["name"],
|
|
||||||
)
|
return idxs, vis
|
||||||
self.voicelist = [
|
|
||||||
"%02d %s" % (i, voicedict[i]) for i in range(len(voicedict))
|
|
||||||
]
|
|
||||||
return self.voicelist
|
|
||||||
except:
|
except:
|
||||||
print_exc()
|
print_exc()
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
break
|
break
|
||||||
|
|
||||||
def speak(self, content, rate, voice, voiceidx):
|
def speak(self, content, rate, voice):
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
}
|
}
|
||||||
|
|
||||||
params = {"speaker": voiceidx, "text": content}
|
params = {"speaker": voice, "text": content}
|
||||||
|
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
f"http://localhost:{self.config['Port']}/audio_query",
|
f"http://localhost:{self.config['Port']}/audio_query",
|
||||||
@ -87,12 +62,11 @@ class TTS(TTSbase):
|
|||||||
proxies={"http": None, "https": None},
|
proxies={"http": None, "https": None},
|
||||||
)
|
)
|
||||||
print(response.json())
|
print(response.json())
|
||||||
fname = str(time.time())
|
|
||||||
headers = {
|
headers = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
}
|
}
|
||||||
params = {
|
params = {
|
||||||
"speaker": voiceidx,
|
"speaker": voice,
|
||||||
}
|
}
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
f"http://localhost:{self.config['Port']}/synthesis",
|
f"http://localhost:{self.config['Port']}/synthesis",
|
||||||
@ -100,4 +74,4 @@ class TTS(TTSbase):
|
|||||||
headers=headers,
|
headers=headers,
|
||||||
data=json.dumps(response.json()),
|
data=json.dumps(response.json()),
|
||||||
)
|
)
|
||||||
return response.content
|
return response.content
|
||||||
|
@ -24,9 +24,9 @@ class TTS(TTSbase):
|
|||||||
|
|
||||||
for _ in needremove:
|
for _ in needremove:
|
||||||
self._7.remove(_)
|
self._7.remove(_)
|
||||||
return self._7 + self._10
|
return (self._7 + self._10), (self._7 + self._10)
|
||||||
|
|
||||||
def speak(self, content, rate, voice, voice_idx):
|
def speak(self, content, rate, voice):
|
||||||
if voice in self._10m:
|
if voice in self._10m:
|
||||||
version = 10
|
version = 10
|
||||||
voice_idx = self._10m[voice]
|
voice_idx = self._10m[voice]
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
import requests
|
import requests
|
||||||
import time, os
|
|
||||||
from tts.basettsclass import TTSbase
|
from tts.basettsclass import TTSbase
|
||||||
|
|
||||||
|
|
||||||
class TTS(TTSbase):
|
class TTS(TTSbase):
|
||||||
def getvoicelist(self):
|
def getvoicelist(self):
|
||||||
return ["ja", "zh", "en"]
|
return ["ja", "zh", "en"], ["Japanese","Chinese","English"]
|
||||||
|
|
||||||
def voiceshowmap(self, voice):
|
def speak(self, content, rate, voice):
|
||||||
return {"ja": "Japanese", "zh": "Chinese", "en": "English"}[voice]
|
|
||||||
|
|
||||||
def speak(self, content, rate, voice, voiceidx):
|
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
"Accept": "*/*",
|
"Accept": "*/*",
|
||||||
|
@ -1088,7 +1088,6 @@
|
|||||||
"name": "VOICEVOX",
|
"name": "VOICEVOX",
|
||||||
"type": "offline",
|
"type": "offline",
|
||||||
"args": {
|
"args": {
|
||||||
"path": "",
|
|
||||||
"Port": 50021
|
"Port": 50021
|
||||||
},
|
},
|
||||||
"argstype": {
|
"argstype": {
|
||||||
@ -1098,11 +1097,6 @@
|
|||||||
"max": 65535,
|
"max": 65535,
|
||||||
"step": 1,
|
"step": 1,
|
||||||
"name": "端口号"
|
"name": "端口号"
|
||||||
},
|
|
||||||
"path": {
|
|
||||||
"type": "file",
|
|
||||||
"name": "路径",
|
|
||||||
"dir": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -777,7 +777,6 @@
|
|||||||
"安装": "تركيب .",
|
"安装": "تركيب .",
|
||||||
"延申": "تمديد",
|
"延申": "تمديد",
|
||||||
"进入时才显示": "عرض فقط عند الدخول",
|
"进入时才显示": "عرض فقط عند الدخول",
|
||||||
"语音跳过": "صوت تخطي",
|
|
||||||
"条件": "شرط .",
|
"条件": "شرط .",
|
||||||
"指定人名翻译": "تعيين اسم المترجم",
|
"指定人名翻译": "تعيين اسم المترجم",
|
||||||
"专有名词翻译": "ترجمة الأسماء الصحيحة",
|
"专有名词翻译": "ترجمة الأسماء الصحيحة",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "تحديد الاتجاه",
|
"识别方向": "تحديد الاتجاه",
|
||||||
"横向": "بشكل مستعرض",
|
"横向": "بشكل مستعرض",
|
||||||
"竖向": "عمودي",
|
"竖向": "عمودي",
|
||||||
"自适应": "تكيف ذاتي"
|
"自适应": "تكيف ذاتي",
|
||||||
|
"清除": "مسح",
|
||||||
|
"语音指定": "صوت محدد",
|
||||||
|
"指定为": "تعيين",
|
||||||
|
"跳过": "تخطي"
|
||||||
}
|
}
|
@ -777,7 +777,6 @@
|
|||||||
"安装": "安裝",
|
"安装": "安裝",
|
||||||
"延申": "延伸",
|
"延申": "延伸",
|
||||||
"进入时才显示": "進入時才顯示",
|
"进入时才显示": "進入時才顯示",
|
||||||
"语音跳过": "語音跳過",
|
|
||||||
"条件": "條件",
|
"条件": "條件",
|
||||||
"指定人名翻译": "指定人名翻譯",
|
"指定人名翻译": "指定人名翻譯",
|
||||||
"专有名词翻译": "專有名詞翻譯",
|
"专有名词翻译": "專有名詞翻譯",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "識別方向",
|
"识别方向": "識別方向",
|
||||||
"横向": "橫向",
|
"横向": "橫向",
|
||||||
"竖向": "豎向",
|
"竖向": "豎向",
|
||||||
"自适应": "自我調整"
|
"自适应": "自我調整",
|
||||||
|
"清除": "清除",
|
||||||
|
"语音指定": "語音指定",
|
||||||
|
"指定为": "指定為",
|
||||||
|
"跳过": "跳過"
|
||||||
}
|
}
|
@ -779,7 +779,6 @@
|
|||||||
"安装": "instalovat",
|
"安装": "instalovat",
|
||||||
"延申": "Yanshen.",
|
"延申": "Yanshen.",
|
||||||
"进入时才显示": "Zobrazeno pouze při vstupu",
|
"进入时才显示": "Zobrazeno pouze při vstupu",
|
||||||
"语音跳过": "Přeskakování hlasu",
|
|
||||||
"条件": "stav",
|
"条件": "stav",
|
||||||
"指定人名翻译": "Překlad označeného názvu",
|
"指定人名翻译": "Překlad označeného názvu",
|
||||||
"专有名词翻译": "Překlad vlastnických pojmů",
|
"专有名词翻译": "Překlad vlastnických pojmů",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "Určit směr",
|
"识别方向": "Určit směr",
|
||||||
"横向": "příčná",
|
"横向": "příčná",
|
||||||
"竖向": "vertikální",
|
"竖向": "vertikální",
|
||||||
"自适应": "samostatná adaptace"
|
"自适应": "samostatná adaptace",
|
||||||
|
"清除": "eliminovat",
|
||||||
|
"语音指定": "Označení hlasu",
|
||||||
|
"指定为": "Určeno jako",
|
||||||
|
"跳过": "přeskočit"
|
||||||
}
|
}
|
@ -779,7 +779,6 @@
|
|||||||
"安装": "installieren",
|
"安装": "installieren",
|
||||||
"延申": "Yanshen",
|
"延申": "Yanshen",
|
||||||
"进入时才显示": "Nur bei Eingabe angezeigt",
|
"进入时才显示": "Nur bei Eingabe angezeigt",
|
||||||
"语音跳过": "Sprachüberspringen",
|
|
||||||
"条件": "Zustand",
|
"条件": "Zustand",
|
||||||
"指定人名翻译": "Übersetzung benannter Namen",
|
"指定人名翻译": "Übersetzung benannter Namen",
|
||||||
"专有名词翻译": "Übersetzung von geschützten Begriffen",
|
"专有名词翻译": "Übersetzung von geschützten Begriffen",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "Richtung bestimmen",
|
"识别方向": "Richtung bestimmen",
|
||||||
"横向": "quer",
|
"横向": "quer",
|
||||||
"竖向": "vertikal",
|
"竖向": "vertikal",
|
||||||
"自适应": "Selbstanpassung"
|
"自适应": "Selbstanpassung",
|
||||||
|
"清除": "eliminieren",
|
||||||
|
"语音指定": "Sprachbezeichnung",
|
||||||
|
"指定为": "Bestimmt als",
|
||||||
|
"跳过": "überspringen"
|
||||||
}
|
}
|
@ -777,7 +777,6 @@
|
|||||||
"安装": "install",
|
"安装": "install",
|
||||||
"延申": "Extension",
|
"延申": "Extension",
|
||||||
"进入时才显示": "Displayed only upon entry",
|
"进入时才显示": "Displayed only upon entry",
|
||||||
"语音跳过": "Voice skipping",
|
|
||||||
"条件": "condition",
|
"条件": "condition",
|
||||||
"指定人名翻译": "Designated Name Translation",
|
"指定人名翻译": "Designated Name Translation",
|
||||||
"专有名词翻译": "Translation of proprietary terms",
|
"专有名词翻译": "Translation of proprietary terms",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "Identify direction",
|
"识别方向": "Identify direction",
|
||||||
"横向": "transverse",
|
"横向": "transverse",
|
||||||
"竖向": "vertical ",
|
"竖向": "vertical ",
|
||||||
"自适应": "self-adaption"
|
"自适应": "self-adaption",
|
||||||
|
"清除": "eliminate",
|
||||||
|
"语音指定": "Voice designation",
|
||||||
|
"指定为": "Designated as",
|
||||||
|
"跳过": "skip"
|
||||||
}
|
}
|
@ -777,7 +777,6 @@
|
|||||||
"安装": "Instalación",
|
"安装": "Instalación",
|
||||||
"延申": "Extensión",
|
"延申": "Extensión",
|
||||||
"进入时才显示": "Se muestra al entrar",
|
"进入时才显示": "Se muestra al entrar",
|
||||||
"语音跳过": "Salto de voz",
|
|
||||||
"条件": "Condiciones",
|
"条件": "Condiciones",
|
||||||
"指定人名翻译": "Traducción de nombre designado",
|
"指定人名翻译": "Traducción de nombre designado",
|
||||||
"专有名词翻译": "Traducción de términos propios",
|
"专有名词翻译": "Traducción de términos propios",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "Identificar la dirección",
|
"识别方向": "Identificar la dirección",
|
||||||
"横向": "Horizontal",
|
"横向": "Horizontal",
|
||||||
"竖向": "Vertical",
|
"竖向": "Vertical",
|
||||||
"自适应": "Autoadaptación"
|
"自适应": "Autoadaptación",
|
||||||
|
"清除": "Eliminar",
|
||||||
|
"语音指定": "Designación de voz",
|
||||||
|
"指定为": "Designado como",
|
||||||
|
"跳过": "Saltar"
|
||||||
}
|
}
|
@ -777,7 +777,6 @@
|
|||||||
"安装": "Installation",
|
"安装": "Installation",
|
||||||
"延申": "Yanshin",
|
"延申": "Yanshin",
|
||||||
"进入时才显示": "Ne s'affiche qu'à l'entrée",
|
"进入时才显示": "Ne s'affiche qu'à l'entrée",
|
||||||
"语音跳过": "Voix skip",
|
|
||||||
"条件": "Conditions",
|
"条件": "Conditions",
|
||||||
"指定人名翻译": "Nom de la personne désignée traduction",
|
"指定人名翻译": "Nom de la personne désignée traduction",
|
||||||
"专有名词翻译": "Traduction de noms propres",
|
"专有名词翻译": "Traduction de noms propres",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "Identification des directions",
|
"识别方向": "Identification des directions",
|
||||||
"横向": "Latéralement",
|
"横向": "Latéralement",
|
||||||
"竖向": "Verticalement",
|
"竖向": "Verticalement",
|
||||||
"自适应": "Adaptatif"
|
"自适应": "Adaptatif",
|
||||||
|
"清除": "Effacer",
|
||||||
|
"语音指定": "Désignation vocale",
|
||||||
|
"指定为": "Désigné comme",
|
||||||
|
"跳过": "Sauter"
|
||||||
}
|
}
|
@ -777,7 +777,6 @@
|
|||||||
"安装": "installa",
|
"安装": "installa",
|
||||||
"延申": "Estensione",
|
"延申": "Estensione",
|
||||||
"进入时才显示": "Visualizzato solo all'entrata",
|
"进入时才显示": "Visualizzato solo all'entrata",
|
||||||
"语音跳过": "Salto vocale",
|
|
||||||
"条件": "condizione",
|
"条件": "condizione",
|
||||||
"指定人名翻译": "Traduzione del nome designato",
|
"指定人名翻译": "Traduzione del nome designato",
|
||||||
"专有名词翻译": "Traduzione di termini proprietari",
|
"专有名词翻译": "Traduzione di termini proprietari",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "Identifica la direzione",
|
"识别方向": "Identifica la direzione",
|
||||||
"横向": "trasversale",
|
"横向": "trasversale",
|
||||||
"竖向": "verticale",
|
"竖向": "verticale",
|
||||||
"自适应": "auto-adattamento"
|
"自适应": "auto-adattamento",
|
||||||
|
"清除": "eliminare",
|
||||||
|
"语音指定": "Denominazione vocale",
|
||||||
|
"指定为": "Designato come",
|
||||||
|
"跳过": "salta"
|
||||||
}
|
}
|
@ -777,7 +777,6 @@
|
|||||||
"安装": "インストール",
|
"安装": "インストール",
|
||||||
"延申": "に言及",
|
"延申": "に言及",
|
||||||
"进入时才显示": "入力時に表示",
|
"进入时才显示": "入力時に表示",
|
||||||
"语音跳过": "音声スキップ",
|
|
||||||
"条件": "条件#ジョウケン#",
|
"条件": "条件#ジョウケン#",
|
||||||
"指定人名翻译": "指定人名翻訳",
|
"指定人名翻译": "指定人名翻訳",
|
||||||
"专有名词翻译": "固有名詞の翻訳",
|
"专有名词翻译": "固有名詞の翻訳",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "方向を識別する",
|
"识别方向": "方向を識別する",
|
||||||
"横向": "横方向",
|
"横向": "横方向",
|
||||||
"竖向": "垂直方向",
|
"竖向": "垂直方向",
|
||||||
"自适应": "てきおう"
|
"自适应": "てきおう",
|
||||||
|
"清除": "パージ",
|
||||||
|
"语音指定": "音声指定",
|
||||||
|
"指定为": "指定#シテイ#",
|
||||||
|
"跳过": "スキップ"
|
||||||
}
|
}
|
@ -777,7 +777,6 @@
|
|||||||
"安装": "설치",
|
"安装": "설치",
|
||||||
"延申": "연장",
|
"延申": "연장",
|
||||||
"进入时才显示": "들어갈 때만 표시",
|
"进入时才显示": "들어갈 때만 표시",
|
||||||
"语音跳过": "음성 건너뛰기",
|
|
||||||
"条件": "조건",
|
"条件": "조건",
|
||||||
"指定人名翻译": "사용자 이름 번역 지정",
|
"指定人名翻译": "사용자 이름 번역 지정",
|
||||||
"专有名词翻译": "고유명사 번역",
|
"专有名词翻译": "고유명사 번역",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "방향 식별",
|
"识别方向": "방향 식별",
|
||||||
"横向": "가로",
|
"横向": "가로",
|
||||||
"竖向": "세로 방향",
|
"竖向": "세로 방향",
|
||||||
"自适应": "적응성"
|
"自适应": "적응성",
|
||||||
|
"清除": "지우기",
|
||||||
|
"语音指定": "음성 지정",
|
||||||
|
"指定为": "다음으로 지정",
|
||||||
|
"跳过": "건너뛰기"
|
||||||
}
|
}
|
@ -779,7 +779,6 @@
|
|||||||
"安装": "installeren",
|
"安装": "installeren",
|
||||||
"延申": "Yanshen.",
|
"延申": "Yanshen.",
|
||||||
"进入时才显示": "Alleen weergegeven bij binnenkomst",
|
"进入时才显示": "Alleen weergegeven bij binnenkomst",
|
||||||
"语音跳过": "Stem overslaan",
|
|
||||||
"条件": "conditie",
|
"条件": "conditie",
|
||||||
"指定人名翻译": "Vertaling van aangewezen naam",
|
"指定人名翻译": "Vertaling van aangewezen naam",
|
||||||
"专有名词翻译": "Vertaling van eigendomstermen",
|
"专有名词翻译": "Vertaling van eigendomstermen",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "Identificeer richting",
|
"识别方向": "Identificeer richting",
|
||||||
"横向": "dwars",
|
"横向": "dwars",
|
||||||
"竖向": "verticaal",
|
"竖向": "verticaal",
|
||||||
"自适应": "zelfaanpassing"
|
"自适应": "zelfaanpassing",
|
||||||
|
"清除": "elimineren",
|
||||||
|
"语音指定": "Stembepaling",
|
||||||
|
"指定为": "Aangeduid als",
|
||||||
|
"跳过": "overslaan"
|
||||||
}
|
}
|
@ -777,7 +777,6 @@
|
|||||||
"安装": "instaluj",
|
"安装": "instaluj",
|
||||||
"延申": "Rozszerzenie",
|
"延申": "Rozszerzenie",
|
||||||
"进入时才显示": "Wyświetlane tylko przy wejściu",
|
"进入时才显示": "Wyświetlane tylko przy wejściu",
|
||||||
"语音跳过": "Przeskakiwanie głosu",
|
|
||||||
"条件": "stan",
|
"条件": "stan",
|
||||||
"指定人名翻译": "Tłumaczenie oznaczonej nazwy",
|
"指定人名翻译": "Tłumaczenie oznaczonej nazwy",
|
||||||
"专有名词翻译": "Tłumaczenie terminów własności",
|
"专有名词翻译": "Tłumaczenie terminów własności",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "Określić kierunek",
|
"识别方向": "Określić kierunek",
|
||||||
"横向": "poprzeczne",
|
"横向": "poprzeczne",
|
||||||
"竖向": "pionowy",
|
"竖向": "pionowy",
|
||||||
"自适应": "samodzielna adaptacja"
|
"自适应": "samodzielna adaptacja",
|
||||||
|
"清除": "wyeliminować",
|
||||||
|
"语音指定": "Oznaczenie głosu",
|
||||||
|
"指定为": "Wyznaczony jako",
|
||||||
|
"跳过": "pominięcie"
|
||||||
}
|
}
|
@ -779,7 +779,6 @@
|
|||||||
"安装": "instalar",
|
"安装": "instalar",
|
||||||
"延申": "Yanshen",
|
"延申": "Yanshen",
|
||||||
"进入时才显示": "Apresentado apenas no momento da entrada",
|
"进入时才显示": "Apresentado apenas no momento da entrada",
|
||||||
"语音跳过": "Saltar a voz",
|
|
||||||
"条件": "condição",
|
"条件": "condição",
|
||||||
"指定人名翻译": "Tradução de Nomes Designados",
|
"指定人名翻译": "Tradução de Nomes Designados",
|
||||||
"专有名词翻译": "Tradução de termos proprietários",
|
"专有名词翻译": "Tradução de termos proprietários",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "Identificar a direcção",
|
"识别方向": "Identificar a direcção",
|
||||||
"横向": "transversal",
|
"横向": "transversal",
|
||||||
"竖向": "vertical",
|
"竖向": "vertical",
|
||||||
"自适应": "auto-adaptação"
|
"自适应": "auto-adaptação",
|
||||||
|
"清除": "eliminar",
|
||||||
|
"语音指定": "Designação da voz",
|
||||||
|
"指定为": "Designado como",
|
||||||
|
"跳过": "pular"
|
||||||
}
|
}
|
@ -777,7 +777,6 @@
|
|||||||
"安装": "Монтаж",
|
"安装": "Монтаж",
|
||||||
"延申": "Яньшэнь",
|
"延申": "Яньшэнь",
|
||||||
"进入时才显示": "Показать при входе",
|
"进入时才显示": "Показать при входе",
|
||||||
"语音跳过": "Голос скачать",
|
|
||||||
"条件": "Условия",
|
"条件": "Условия",
|
||||||
"指定人名翻译": "Имя назначенного переводчика",
|
"指定人名翻译": "Имя назначенного переводчика",
|
||||||
"专有名词翻译": "Перевод терминов",
|
"专有名词翻译": "Перевод терминов",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "Распознать направление",
|
"识别方向": "Распознать направление",
|
||||||
"横向": "Горизонтальный",
|
"横向": "Горизонтальный",
|
||||||
"竖向": "Вертикально",
|
"竖向": "Вертикально",
|
||||||
"自适应": "Самоадаптация"
|
"自适应": "Самоадаптация",
|
||||||
|
"清除": "Очистить",
|
||||||
|
"语音指定": "Голосовое назначение",
|
||||||
|
"指定为": "Назначено",
|
||||||
|
"跳过": "Пропустить"
|
||||||
}
|
}
|
@ -779,7 +779,6 @@
|
|||||||
"安装": "installera",
|
"安装": "installera",
|
||||||
"延申": "Yanshen",
|
"延申": "Yanshen",
|
||||||
"进入时才显示": "Visas endast vid inmatning",
|
"进入时才显示": "Visas endast vid inmatning",
|
||||||
"语音跳过": "Rösthoppande",
|
|
||||||
"条件": "tillstånd",
|
"条件": "tillstånd",
|
||||||
"指定人名翻译": "Översättning av betecknat namn",
|
"指定人名翻译": "Översättning av betecknat namn",
|
||||||
"专有名词翻译": "Översättning av egendomsbenämningar",
|
"专有名词翻译": "Översättning av egendomsbenämningar",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "Identifiera riktning",
|
"识别方向": "Identifiera riktning",
|
||||||
"横向": "tvärgående",
|
"横向": "tvärgående",
|
||||||
"竖向": "vertikal",
|
"竖向": "vertikal",
|
||||||
"自适应": "självanpassning"
|
"自适应": "självanpassning",
|
||||||
|
"清除": "eliminera",
|
||||||
|
"语音指定": "Röstbeteckning",
|
||||||
|
"指定为": "Utnämnd som",
|
||||||
|
"跳过": "hoppa över"
|
||||||
}
|
}
|
@ -777,7 +777,6 @@
|
|||||||
"安装": "การติดตั้ง",
|
"安装": "การติดตั้ง",
|
||||||
"延申": "ยันชิน",
|
"延申": "ยันชิน",
|
||||||
"进入时才显示": "แสดงเฉพาะเมื่อเข้า",
|
"进入时才显示": "แสดงเฉพาะเมื่อเข้า",
|
||||||
"语音跳过": "ข้ามเสียง",
|
|
||||||
"条件": "เงื่อนไข",
|
"条件": "เงื่อนไข",
|
||||||
"指定人名翻译": "ระบุการแปลชื่อบุคคล",
|
"指定人名翻译": "ระบุการแปลชื่อบุคคล",
|
||||||
"专有名词翻译": "การแปลคำนามที่เป็นกรรมสิทธิ์",
|
"专有名词翻译": "การแปลคำนามที่เป็นกรรมสิทธิ์",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "ระบุทิศทาง",
|
"识别方向": "ระบุทิศทาง",
|
||||||
"横向": "แนวนอน",
|
"横向": "แนวนอน",
|
||||||
"竖向": "แนวตรง",
|
"竖向": "แนวตรง",
|
||||||
"自适应": "การปรับตัว"
|
"自适应": "การปรับตัว",
|
||||||
|
"清除": "ล้าง",
|
||||||
|
"语音指定": "การกำหนดเสียง",
|
||||||
|
"指定为": "กำหนดให้เป็น",
|
||||||
|
"跳过": "ข้าม"
|
||||||
}
|
}
|
@ -777,7 +777,6 @@
|
|||||||
"安装": "Kur",
|
"安装": "Kur",
|
||||||
"延申": "Uzantı",
|
"延申": "Uzantı",
|
||||||
"进入时才显示": "Sadece giriş üzerinde gösterilir",
|
"进入时才显示": "Sadece giriş üzerinde gösterilir",
|
||||||
"语音跳过": "Ses atlama",
|
|
||||||
"条件": "durum",
|
"条件": "durum",
|
||||||
"指定人名翻译": "Tasarlanmış İsim Çevirmesi",
|
"指定人名翻译": "Tasarlanmış İsim Çevirmesi",
|
||||||
"专有名词翻译": "Özel terimlerin çevirimi",
|
"专有名词翻译": "Özel terimlerin çevirimi",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "Doğru belirle",
|
"识别方向": "Doğru belirle",
|
||||||
"横向": "transverse",
|
"横向": "transverse",
|
||||||
"竖向": "dikey",
|
"竖向": "dikey",
|
||||||
"自适应": "kendi uygulama"
|
"自适应": "kendi uygulama",
|
||||||
|
"清除": "sil",
|
||||||
|
"语音指定": "Ses tasarımı",
|
||||||
|
"指定为": "Şöyle tasarlanmıştır",
|
||||||
|
"跳过": "atla"
|
||||||
}
|
}
|
@ -777,7 +777,6 @@
|
|||||||
"安装": "встановити",
|
"安装": "встановити",
|
||||||
"延申": "Розширення",
|
"延申": "Розширення",
|
||||||
"进入时才显示": "Показано лише після запису",
|
"进入时才显示": "Показано лише після запису",
|
||||||
"语音跳过": "Пропускання голосу",
|
|
||||||
"条件": "умови",
|
"条件": "умови",
|
||||||
"指定人名翻译": "Переклад визначеної назви",
|
"指定人名翻译": "Переклад визначеної назви",
|
||||||
"专有名词翻译": "Переклад приєднаних термінів",
|
"专有名词翻译": "Переклад приєднаних термінів",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "Визначити напрямок",
|
"识别方向": "Визначити напрямок",
|
||||||
"横向": "transverse",
|
"横向": "transverse",
|
||||||
"竖向": "вертикальна",
|
"竖向": "вертикальна",
|
||||||
"自适应": "самоадаптація"
|
"自适应": "самоадаптація",
|
||||||
|
"清除": "вилучити",
|
||||||
|
"语音指定": "Визначення голосу",
|
||||||
|
"指定为": "Визначено як",
|
||||||
|
"跳过": "пропустити"
|
||||||
}
|
}
|
@ -777,7 +777,6 @@
|
|||||||
"安装": "Cài đặt",
|
"安装": "Cài đặt",
|
||||||
"延申": "Dương Thân",
|
"延申": "Dương Thân",
|
||||||
"进入时才显示": "Hiển thị khi vào",
|
"进入时才显示": "Hiển thị khi vào",
|
||||||
"语音跳过": "Bỏ qua giọng nói",
|
|
||||||
"条件": "Điều kiện",
|
"条件": "Điều kiện",
|
||||||
"指定人名翻译": "Name",
|
"指定人名翻译": "Name",
|
||||||
"专有名词翻译": "Bản dịch của proprietary noun",
|
"专有名词翻译": "Bản dịch của proprietary noun",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "Xác định hướng",
|
"识别方向": "Xác định hướng",
|
||||||
"横向": "Phong cảnh",
|
"横向": "Phong cảnh",
|
||||||
"竖向": "Dọc",
|
"竖向": "Dọc",
|
||||||
"自适应": "Thích ứng"
|
"自适应": "Thích ứng",
|
||||||
|
"清除": "Xoá",
|
||||||
|
"语音指定": "Chỉ định giọng nói",
|
||||||
|
"指定为": "Xác định là",
|
||||||
|
"跳过": "Bỏ qua"
|
||||||
}
|
}
|
@ -780,7 +780,6 @@
|
|||||||
"安装": "",
|
"安装": "",
|
||||||
"延申": "",
|
"延申": "",
|
||||||
"进入时才显示": "",
|
"进入时才显示": "",
|
||||||
"语音跳过": "",
|
|
||||||
"条件": "",
|
"条件": "",
|
||||||
"指定人名翻译": "",
|
"指定人名翻译": "",
|
||||||
"专有名词翻译": "",
|
"专有名词翻译": "",
|
||||||
@ -845,5 +844,9 @@
|
|||||||
"识别方向": "",
|
"识别方向": "",
|
||||||
"横向": "",
|
"横向": "",
|
||||||
"竖向": "",
|
"竖向": "",
|
||||||
"自适应": ""
|
"自适应": "",
|
||||||
|
"清除": "",
|
||||||
|
"语音指定": "",
|
||||||
|
"指定为": "",
|
||||||
|
"跳过": ""
|
||||||
}
|
}
|
@ -28,8 +28,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/version)
|
|||||||
include(generate_product_version)
|
include(generate_product_version)
|
||||||
|
|
||||||
set(VERSION_MAJOR 5)
|
set(VERSION_MAJOR 5)
|
||||||
set(VERSION_MINOR 21)
|
set(VERSION_MINOR 22)
|
||||||
set(VERSION_PATCH 2)
|
set(VERSION_PATCH 0)
|
||||||
|
|
||||||
add_library(pch pch.cpp)
|
add_library(pch pch.cpp)
|
||||||
target_precompile_headers(pch PUBLIC pch.h)
|
target_precompile_headers(pch PUBLIC pch.h)
|
||||||
|
@ -4,24 +4,10 @@
|
|||||||
|
|
||||||
#define CODEPAGE_BIG5 950
|
#define CODEPAGE_BIG5 950
|
||||||
|
|
||||||
UINT unpackuint32(unsigned char *s)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
return ((s[i]) << 24) | ((s[i + 1]) << 16) | ((s[i + 2]) << 8) | (s[i + 3]);
|
|
||||||
}
|
|
||||||
void packuint32(UINT i, unsigned char *b)
|
|
||||||
{
|
|
||||||
b[0] = (i >> 24) & 0xff;
|
|
||||||
b[1] = (i >> 16) & 0xff;
|
|
||||||
b[2] = (i >> 8) & 0xff;
|
|
||||||
b[3] = (i) & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
int jbjwmain(int argc, wchar_t *argv[])
|
int jbjwmain(int argc, wchar_t *argv[])
|
||||||
{
|
{
|
||||||
HANDLE hPipe = CreateNamedPipe(argv[2], PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 65535, 65535, NMPWAIT_WAIT_FOREVER, 0);
|
HANDLE hPipe = CreateNamedPipe(argv[2], PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 65535, 65535, NMPWAIT_WAIT_FOREVER, 0);
|
||||||
|
|
||||||
|
|
||||||
// system("chcp 932");
|
// system("chcp 932");
|
||||||
HMODULE module = LoadLibraryW(argv[1]);
|
HMODULE module = LoadLibraryW(argv[1]);
|
||||||
typedef int (*_JC_Transfer_Unicode)(int, UINT, UINT, int, int, LPCWSTR, LPWSTR, int &, LPWSTR, int &);
|
typedef int (*_JC_Transfer_Unicode)(int, UINT, UINT, int, int, LPCWSTR, LPWSTR, int &, LPWSTR, int &);
|
||||||
@ -50,7 +36,7 @@ int jbjwmain(int argc, wchar_t *argv[])
|
|||||||
wchar_t *fr = new wchar_t[3000];
|
wchar_t *fr = new wchar_t[3000];
|
||||||
wchar_t *to = new wchar_t[3000];
|
wchar_t *to = new wchar_t[3000];
|
||||||
wchar_t *buf = new wchar_t[3000];
|
wchar_t *buf = new wchar_t[3000];
|
||||||
|
|
||||||
SetEvent(CreateEvent(&allAccess, FALSE, FALSE, argv[3]));
|
SetEvent(CreateEvent(&allAccess, FALSE, FALSE, argv[3]));
|
||||||
if (ConnectNamedPipe(hPipe, NULL) != NULL)
|
if (ConnectNamedPipe(hPipe, NULL) != NULL)
|
||||||
{
|
{
|
||||||
@ -64,13 +50,10 @@ int jbjwmain(int argc, wchar_t *argv[])
|
|||||||
memset(buf, 0, 3000 * sizeof(wchar_t));
|
memset(buf, 0, 3000 * sizeof(wchar_t));
|
||||||
int a = 3000;
|
int a = 3000;
|
||||||
int b = 3000;
|
int b = 3000;
|
||||||
char codec[4] = {0};
|
|
||||||
UINT code;
|
UINT code;
|
||||||
DWORD _;
|
DWORD _;
|
||||||
|
|
||||||
ReadFile(hPipe, intcache, 4, &_, NULL);
|
ReadFile(hPipe, &code, 4, &_, NULL);
|
||||||
|
|
||||||
code = unpackuint32(intcache);
|
|
||||||
|
|
||||||
if (!ReadFile(hPipe, (unsigned char *)fr, 6000, &_, NULL))
|
if (!ReadFile(hPipe, (unsigned char *)fr, 6000, &_, NULL))
|
||||||
break;
|
break;
|
||||||
|
@ -26,8 +26,6 @@ int neospeechlist(int argc, wchar_t *argv[])
|
|||||||
}
|
}
|
||||||
int neospeech(int argc, wchar_t *argv[])
|
int neospeech(int argc, wchar_t *argv[])
|
||||||
{
|
{
|
||||||
auto hkey = argv[4];
|
|
||||||
auto idx = std::stoi(argv[5]);
|
|
||||||
|
|
||||||
HANDLE hPipe = CreateNamedPipe(argv[1], PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 65535, 65535, NMPWAIT_WAIT_FOREVER, 0);
|
HANDLE hPipe = CreateNamedPipe(argv[1], PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 65535, 65535, NMPWAIT_WAIT_FOREVER, 0);
|
||||||
|
|
||||||
@ -41,12 +39,11 @@ int neospeech(int argc, wchar_t *argv[])
|
|||||||
{
|
{
|
||||||
DWORD len = 0;
|
DWORD len = 0;
|
||||||
}
|
}
|
||||||
int II = 0;
|
wchar_t text[10000];
|
||||||
|
DWORD _;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
wchar_t text[10000];
|
ZeroMemory(text, sizeof(text));
|
||||||
II += 1;
|
|
||||||
DWORD _;
|
|
||||||
int speed;
|
int speed;
|
||||||
if (!ReadFile(hPipe, (unsigned char *)&speed, 4, &_, NULL))
|
if (!ReadFile(hPipe, (unsigned char *)&speed, 4, &_, NULL))
|
||||||
break;
|
break;
|
||||||
@ -54,7 +51,15 @@ int neospeech(int argc, wchar_t *argv[])
|
|||||||
break;
|
break;
|
||||||
std::wstring content = text;
|
std::wstring content = text;
|
||||||
int fsize;
|
int fsize;
|
||||||
auto data = std::move(_Speak(content, hkey, idx, speed, 100));
|
ZeroMemory(text, sizeof(text));
|
||||||
|
if (!ReadFile(hPipe, (unsigned char *)text, 10000 * 2, &_, NULL))
|
||||||
|
break;
|
||||||
|
std::wstring hkey = text;
|
||||||
|
int idx;
|
||||||
|
if (!ReadFile(hPipe, &idx, 4, &_, NULL))
|
||||||
|
break;
|
||||||
|
ZeroMemory(text, sizeof(text));
|
||||||
|
auto data = std::move(_Speak(content, hkey.c_str(), idx, speed, 100));
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
memcpy(mapview, data.value().data(), data.value().size());
|
memcpy(mapview, data.value().data(), data.value().size());
|
||||||
|
@ -299,9 +299,6 @@ namespace ebyroid
|
|||||||
param->lenRawBufBytes = kConfigRawbufSize;
|
param->lenRawBufBytes = kConfigRawbufSize;
|
||||||
|
|
||||||
param->volume = volume;
|
param->volume = volume;
|
||||||
auto f = fopen(R"(C:\Users\wcy\source\repos\ConsoleApplication1\Release\2.txt)", "wb");
|
|
||||||
fwrite(param, 1, param_size, f);
|
|
||||||
fclose(f);
|
|
||||||
result = adapter->SetParam(param);
|
result = adapter->SetParam(param);
|
||||||
printf("SetParam ok %d\n", result);
|
printf("SetParam ok %d\n", result);
|
||||||
if (result != ERR_SUCCESS)
|
if (result != ERR_SUCCESS)
|
||||||
|
@ -15,34 +15,56 @@ int voiceroid2wmain(int argc, wchar_t *wargv[])
|
|||||||
argv[i] = new char[length];
|
argv[i] = new char[length];
|
||||||
WideCharToMultiByte(CP_ACP, 0, wargv[i], -1, argv[i], length, NULL, NULL);
|
WideCharToMultiByte(CP_ACP, 0, wargv[i], -1, argv[i], length, NULL, NULL);
|
||||||
}
|
}
|
||||||
HANDLE hPipe = CreateNamedPipeA(argv[6], PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 65535, 65535, NMPWAIT_WAIT_FOREVER, 0);
|
HANDLE hPipe = CreateNamedPipeA(argv[3], PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 65535, 65535, NMPWAIT_WAIT_FOREVER, 0);
|
||||||
|
|
||||||
Ebyroid *ebyroid;
|
Ebyroid *ebyroid = nullptr;
|
||||||
|
|
||||||
ebyroid = Ebyroid::Create((const char *)argv[1], //"C:\\dataH\\Yukari2",
|
std::string last;
|
||||||
(const char *)argv[2],
|
float rate = -1;
|
||||||
(const char *)argv[3], //"yukari_emo_44",
|
auto handle = CreateFileMappingA(INVALID_HANDLE_VALUE, &allAccess, PAGE_EXECUTE_READWRITE, 0, 1024 * 1024 * 10, argv[5]);
|
||||||
2,
|
|
||||||
atof((const char *)argv[5])); // 1); //0.1-2,0.5-4
|
|
||||||
|
|
||||||
auto handle = CreateFileMappingA(INVALID_HANDLE_VALUE, &allAccess, PAGE_EXECUTE_READWRITE, 0, 1024 * 1024 * 10, argv[8]);
|
|
||||||
|
|
||||||
auto mapview = (char *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, 1024 * 1024 * 10);
|
auto mapview = (char *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, 1024 * 1024 * 10);
|
||||||
memset(mapview, 0, 1024 * 1024 * 10);
|
memset(mapview, 0, 1024 * 1024 * 10);
|
||||||
SetEvent(CreateEventA(&allAccess, FALSE, FALSE, argv[7]));
|
SetEvent(CreateEventA(&allAccess, FALSE, FALSE, argv[4]));
|
||||||
ConnectNamedPipe(hPipe, NULL);
|
ConnectNamedPipe(hPipe, NULL);
|
||||||
int freq1 = atoi(argv[4]);
|
int freq1;
|
||||||
|
unsigned char input_j[4096] = {0};
|
||||||
|
DWORD _;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
ZeroMemory(input_j, sizeof(input_j));
|
||||||
unsigned char *out;
|
unsigned char *out;
|
||||||
size_t output_size;
|
size_t output_size;
|
||||||
int16_t *out2;
|
int16_t *out2;
|
||||||
|
|
||||||
unsigned char input_j[4096] = {0};
|
|
||||||
DWORD _;
|
|
||||||
if (!ReadFile(hPipe, input_j, 4096, &_, NULL))
|
if (!ReadFile(hPipe, input_j, 4096, &_, NULL))
|
||||||
break;
|
break;
|
||||||
|
std::string voice = (char *)input_j;
|
||||||
|
float _rate;
|
||||||
|
if (!ReadFile(hPipe, &_rate, 4, &_, NULL))
|
||||||
|
break;
|
||||||
|
if ((voice != last) || (rate != _rate))
|
||||||
|
{
|
||||||
|
last = voice;
|
||||||
|
rate = _rate;
|
||||||
|
if (ebyroid)
|
||||||
|
{
|
||||||
|
delete ebyroid;
|
||||||
|
}
|
||||||
|
ebyroid = Ebyroid::Create((const char *)argv[1], //"C:\\dataH\\Yukari2",
|
||||||
|
(const char *)argv[2],
|
||||||
|
voice.c_str(),
|
||||||
|
2,
|
||||||
|
rate); // 1); //0.1-2,0.5-4
|
||||||
|
}
|
||||||
|
|
||||||
|
ZeroMemory(input_j, sizeof(input_j));
|
||||||
|
if (!ReadFile(hPipe, input_j, 4096, &_, NULL))
|
||||||
|
break;
|
||||||
|
if (voice.find("_44") != voice.npos)
|
||||||
|
freq1 = 44100;
|
||||||
|
else
|
||||||
|
freq1 = 22050;
|
||||||
// int result = ebyroid->Hiragana((const unsigned char*)UnicodeToShift_jis(input), &out, &output_size);
|
// int result = ebyroid->Hiragana((const unsigned char*)UnicodeToShift_jis(input), &out, &output_size);
|
||||||
int result = ebyroid->Hiragana((const unsigned char *)input_j, &out, &output_size);
|
int result = ebyroid->Hiragana((const unsigned char *)input_j, &out, &output_size);
|
||||||
|
|
||||||
@ -83,6 +105,5 @@ int voiceroid2wmain(int argc, wchar_t *wargv[])
|
|||||||
free(out);
|
free(out);
|
||||||
free(out2);
|
free(out2);
|
||||||
}
|
}
|
||||||
// sndPlaySound((const char*)argv[6], SND_SYNC);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user