mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-27 15:44:12 +08:00
update
This commit is contained in:
parent
3b000950bd
commit
8761f09c0f
@ -68,6 +68,7 @@ class MAINUI:
|
||||
self.translators = {}
|
||||
self.cishus = {}
|
||||
self.reader = None
|
||||
self.specialreaders = {}
|
||||
self.textsource_p = None
|
||||
self.currentmd5 = "0"
|
||||
self.currenttext = ""
|
||||
@ -496,7 +497,7 @@ class MAINUI:
|
||||
text = parsemayberegexreplace(usedict["tts_repair_regex"], text)
|
||||
return text
|
||||
|
||||
def guessmaybeskip(self, dic: dict, res: str):
|
||||
def matchwhich(self, dic: dict, res: str):
|
||||
|
||||
for item in dic:
|
||||
if item["regex"]:
|
||||
@ -505,11 +506,11 @@ class MAINUI:
|
||||
)
|
||||
if item["condition"] == 1:
|
||||
if re.search(retext, res):
|
||||
return True
|
||||
return item
|
||||
elif item["condition"] == 0:
|
||||
if re.match(retext, res) or re.search(retext + "$", res):
|
||||
# 用^xxx|xxx$有可能有点危险
|
||||
return True
|
||||
return item
|
||||
else:
|
||||
if item["condition"] == 1:
|
||||
if (
|
||||
@ -520,55 +521,78 @@ class MAINUI:
|
||||
resx = res.split(" ")
|
||||
for i in range(len(resx)):
|
||||
if resx[i] == item["key"]:
|
||||
return True
|
||||
return item
|
||||
else:
|
||||
if item["key"] in res:
|
||||
return True
|
||||
return item
|
||||
elif item["condition"] == 0:
|
||||
if res.startswith(item["key"]) or res.endswith(item["key"]):
|
||||
return True
|
||||
return False
|
||||
return item
|
||||
return None
|
||||
|
||||
def ttsskip(self, text, usedict):
|
||||
def ttsskip(self, text, usedict) -> dict:
|
||||
if usedict["tts_skip"]:
|
||||
return self.guessmaybeskip(usedict["tts_skip_regex"], text)
|
||||
return False
|
||||
return self.matchwhich(usedict["tts_skip_regex"], text)
|
||||
return None
|
||||
|
||||
@threader
|
||||
def readcurrent(self, force=False):
|
||||
if not self.reader:
|
||||
if (not force) and (not globalconfig["autoread"]):
|
||||
return
|
||||
if not (force or globalconfig["autoread"]):
|
||||
return
|
||||
if (not force) and self.ttsskip(self.currentread, self.__usewhich()):
|
||||
matchitme = self.ttsskip(self.currentread, self.__usewhich())
|
||||
reader = None
|
||||
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
|
||||
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
|
||||
def startreader(self, use=None, checked=True):
|
||||
try:
|
||||
self.reader.end()
|
||||
except:
|
||||
pass
|
||||
|
||||
self.reader = None
|
||||
self.settin_ui.voicelistsignal.emit([], -1)
|
||||
if checked:
|
||||
if use is None:
|
||||
|
||||
for key in globalconfig["reader"]:
|
||||
if globalconfig["reader"][key]["use"] and os.path.exists(
|
||||
("./LunaTranslator/tts/" + key + ".py")
|
||||
):
|
||||
use = key
|
||||
break
|
||||
if use:
|
||||
aclass = importlib.import_module("tts." + use).TTS
|
||||
|
||||
self.reader_usevoice = use
|
||||
self.reader = aclass(
|
||||
use, self.settin_ui.voicelistsignal, self.audioplayer.play
|
||||
)
|
||||
self.settin_ui.voicelistsignal.emit(None)
|
||||
if not checked:
|
||||
return
|
||||
if use is None:
|
||||
for key in globalconfig["reader"]:
|
||||
if globalconfig["reader"][key]["use"] and os.path.exists(
|
||||
("./LunaTranslator/tts/" + key + ".py")
|
||||
):
|
||||
use = key
|
||||
break
|
||||
if not use:
|
||||
return
|
||||
self.reader = self.loadreader(use)
|
||||
self.reader_usevoice = use
|
||||
|
||||
def selectprocess(self, selectedp, title):
|
||||
self.textsource = None
|
||||
@ -899,57 +923,6 @@ class MAINUI:
|
||||
)
|
||||
except:
|
||||
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):
|
||||
gameinternalid = self.get_gameinternalid(uid2gamepath[gameuid])
|
||||
|
@ -41,7 +41,7 @@ from myutils.audioplayer import player_mci
|
||||
from gui.codeacceptdialog import codeacceptdialog
|
||||
from gui.inputdialog import (
|
||||
noundictconfigdialog1,
|
||||
noundictconfigdialog2,
|
||||
yuyinzhidingsetting,
|
||||
autoinitdialog,
|
||||
autoinitdialog_items,
|
||||
postconfigdialog,
|
||||
@ -1052,16 +1052,13 @@ class dialog_setting_game_internal(QWidget):
|
||||
)
|
||||
|
||||
formLayout2.addRow(
|
||||
"语音跳过",
|
||||
"语音指定",
|
||||
getboxlayout(
|
||||
[
|
||||
getsimpleswitch(savehook_new_data[gameuid], "tts_skip"),
|
||||
getIconButton(
|
||||
callback=lambda: noundictconfigdialog2(
|
||||
self,
|
||||
savehook_new_data[gameuid]["tts_skip_regex"],
|
||||
"语音跳过",
|
||||
["正则", "条件", "内容"],
|
||||
callback=lambda: yuyinzhidingsetting(
|
||||
self, savehook_new_data[gameuid]["tts_skip_regex"]
|
||||
),
|
||||
icon="fa.gear",
|
||||
),
|
||||
|
@ -152,6 +152,14 @@ class LFormLayout(QFormLayout):
|
||||
argc = text, widget
|
||||
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):
|
||||
|
||||
@ -167,7 +175,7 @@ class LDialog(QDialog):
|
||||
if self._title:
|
||||
super().setWindowTitle(_TR(self._title))
|
||||
|
||||
|
||||
|
||||
class LMainWindow(QMainWindow):
|
||||
|
||||
def __init__(self, *argc, **kwarg):
|
||||
|
@ -1,10 +1,11 @@
|
||||
from qtsymbols import *
|
||||
import functools, importlib
|
||||
from traceback import print_exc
|
||||
import qtawesome
|
||||
import qtawesome, os, gobject
|
||||
from myutils.config import globalconfig, _TR
|
||||
from myutils.utils import makehtml
|
||||
from myutils.wrapper import Singleton_close
|
||||
from tts.basettsclass import getvisidx
|
||||
from gui.usefulwidget import (
|
||||
MySwitch,
|
||||
selectcolor,
|
||||
@ -82,7 +83,6 @@ class noundictconfigdialog1(LDialog):
|
||||
|
||||
def __init__(self, parent, reflist, title, label) -> None:
|
||||
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
|
||||
self.label = label
|
||||
self.setWindowTitle(title)
|
||||
# self.setWindowModality(Qt.ApplicationModal)
|
||||
self.reflist = reflist
|
||||
@ -181,19 +181,107 @@ class noundictconfigdialog1(LDialog):
|
||||
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
|
||||
class noundictconfigdialog2(LDialog):
|
||||
class yuyinzhidingsetting(LDialog):
|
||||
def newline(self, row, item):
|
||||
|
||||
self.model.insertRow(
|
||||
row,
|
||||
[QStandardItem(), QStandardItem(), QStandardItem(item["key"])],
|
||||
[
|
||||
QStandardItem(),
|
||||
QStandardItem(),
|
||||
QStandardItem(item["key"]),
|
||||
QStandardItem(),
|
||||
],
|
||||
)
|
||||
self.table.setIndexWidget(
|
||||
self.model.index(row, 0), getsimpleswitch(item, "regex")
|
||||
)
|
||||
com = getsimplecombobox(["首尾", "包含"], item, "condition")
|
||||
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, _):
|
||||
r = table.currentIndex().row()
|
||||
@ -222,7 +310,12 @@ class noundictconfigdialog2(LDialog):
|
||||
item = self.reflist.pop(curr.row())
|
||||
self.reflist.insert(
|
||||
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())
|
||||
@ -233,20 +326,67 @@ class noundictconfigdialog2(LDialog):
|
||||
)
|
||||
com = getsimplecombobox(["首尾", "包含"], item, "condition")
|
||||
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)
|
||||
self.label = label
|
||||
self.setWindowTitle(title)
|
||||
|
||||
self.setWindowTitle("语音指定")
|
||||
|
||||
# self.setWindowModality(Qt.ApplicationModal)
|
||||
self.reflist = reflist
|
||||
formLayout = QVBoxLayout(self) # 配置layout
|
||||
|
||||
self.model = LStandardItemModel()
|
||||
self.model.setHorizontalHeaderLabels(label)
|
||||
self.model.setHorizontalHeaderLabels(["正则", "条件", "目标", "指定为"])
|
||||
table = TableViewW(self)
|
||||
table.setModel(self.model)
|
||||
table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch)
|
||||
table.horizontalHeader().setSectionResizeMode(
|
||||
3, QHeaderView.ResizeMode.ResizeToContents
|
||||
)
|
||||
table.horizontalHeader().setSectionResizeMode(
|
||||
1, QHeaderView.ResizeMode.ResizeToContents
|
||||
)
|
||||
@ -286,7 +426,9 @@ class noundictconfigdialog2(LDialog):
|
||||
button = threebuttons(texts=["添加行", "删除行", "上移", "下移", "立即应用"])
|
||||
|
||||
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])
|
||||
|
||||
|
@ -65,7 +65,7 @@ class TabWidget(QWidget):
|
||||
|
||||
|
||||
class Setting(closeashidewindow):
|
||||
voicelistsignal = pyqtSignal(list, int)
|
||||
voicelistsignal = pyqtSignal(object)
|
||||
versiontextsignal = pyqtSignal(str)
|
||||
progresssignal = pyqtSignal(str, int)
|
||||
showandsolvesig = pyqtSignal(str)
|
||||
|
@ -1,12 +1,13 @@
|
||||
from qtsymbols import *
|
||||
import os, functools
|
||||
import gobject
|
||||
from tts.basettsclass import getvisidx
|
||||
from myutils.config import globalconfig, static_data
|
||||
from gui.inputdialog import (
|
||||
autoinitdialog_items,
|
||||
noundictconfigdialog1,
|
||||
autoinitdialog,
|
||||
noundictconfigdialog2,
|
||||
yuyinzhidingsetting,
|
||||
)
|
||||
from gui.usefulwidget import (
|
||||
D_getsimplecombobox,
|
||||
@ -19,7 +20,8 @@ from gui.usefulwidget import (
|
||||
)
|
||||
|
||||
|
||||
def showvoicelist(self, vl, idx):
|
||||
def showvoicelist(self, obj):
|
||||
vl, idx = getvisidx(obj)
|
||||
try:
|
||||
self.voicecombo.blockSignals(True)
|
||||
self.voicecombo.clear()
|
||||
@ -205,14 +207,11 @@ def setTab5lz(self):
|
||||
),
|
||||
],
|
||||
[
|
||||
"语音跳过",
|
||||
"语音指定",
|
||||
D_getsimpleswitch(globalconfig["ttscommon"], "tts_skip"),
|
||||
D_getIconButton(
|
||||
callback=lambda: noundictconfigdialog2(
|
||||
self,
|
||||
globalconfig["ttscommon"]["tts_skip_regex"],
|
||||
"语音跳过",
|
||||
["正则", "条件", "内容"],
|
||||
callback=lambda: yuyinzhidingsetting(
|
||||
self, globalconfig["ttscommon"]["tts_skip_regex"]
|
||||
),
|
||||
icon="fa.gear",
|
||||
),
|
||||
|
@ -728,7 +728,6 @@ def comboboxcallbackwrap(internal, d, k, call, _):
|
||||
print_exc()
|
||||
|
||||
|
||||
@tryprint
|
||||
def getsimplecombobox(
|
||||
lst, d, k, callback=None, fixedsize=False, internal=None, static=False, emit=False
|
||||
):
|
||||
@ -740,18 +739,20 @@ def getsimplecombobox(
|
||||
s.addItems(lst)
|
||||
|
||||
if internal:
|
||||
if (k not in d) or (d[k] not in internal):
|
||||
d[k] = internal[0]
|
||||
if len(internal):
|
||||
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(
|
||||
functools.partial(comboboxcallbackwrap, internal, d, k, callback)
|
||||
)
|
||||
else:
|
||||
if (k not in d) or (d[k] >= len(lst)):
|
||||
d[k] = 0
|
||||
if len(lst):
|
||||
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))
|
||||
if fixedsize:
|
||||
s.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
|
||||
@ -1743,6 +1744,9 @@ class listediter(LDialog):
|
||||
table.customContextMenuRequested.connect(self.showmenu)
|
||||
self.hctable = table
|
||||
self.internalrealname = []
|
||||
formLayout = QVBoxLayout()
|
||||
self.setLayout(formLayout)
|
||||
formLayout.addWidget(self.hctable)
|
||||
for row, k in enumerate(lst): # 2
|
||||
try:
|
||||
if namemapfunction:
|
||||
@ -1752,9 +1756,20 @@ class listediter(LDialog):
|
||||
self.internalrealname.append(k)
|
||||
if namemapfunction:
|
||||
k = namemapfunction(k)
|
||||
self.hcmodel.insertRow(row, [QStandardItem(k)])
|
||||
formLayout = QVBoxLayout()
|
||||
formLayout.addWidget(self.hctable)
|
||||
item = QStandardItem(k)
|
||||
self.hcmodel.insertRow(row, [item])
|
||||
|
||||
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:
|
||||
self.buttons = threebuttons(texts=["上移", "下移"])
|
||||
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))
|
||||
|
||||
formLayout.addWidget(self.buttons)
|
||||
self.setLayout(formLayout)
|
||||
self.resize(600, self.sizeHint().height())
|
||||
self.show()
|
||||
except:
|
||||
@ -1811,28 +1825,23 @@ class listediter(LDialog):
|
||||
|
||||
def __cb(self, paths):
|
||||
for path in paths:
|
||||
self.internalrealname.insert(0, paths)
|
||||
self.internalrealname.insert(0, path)
|
||||
self.hcmodel.insertRow(0, [QStandardItem(path)])
|
||||
|
||||
def __changed(self, idx):
|
||||
self.internalrealname[self.hctable.currentIndex().row()] = self.candidates[idx]
|
||||
def __changed(self, item: QStandardItem, idx):
|
||||
self.internalrealname[item.row()] = self.candidates[idx]
|
||||
|
||||
def click1(self):
|
||||
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.hcmodel.insertRow(0, [QStandardItem("")])
|
||||
item = QStandardItem("")
|
||||
self.hcmodel.insertRow(0, [item])
|
||||
combo = LFocusCombo()
|
||||
_vis = self.candidates
|
||||
if self.namemapfunction:
|
||||
_vis = [self.namemapfunction(_) for _ in _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)
|
||||
elif self.ispathsedit is None:
|
||||
self.internalrealname.insert(0, "")
|
||||
@ -1920,8 +1929,10 @@ def getsimplepatheditor(
|
||||
e.setReadOnly(True)
|
||||
if useiconbutton:
|
||||
bu = getIconButton(icon="fa.gear")
|
||||
clear = getIconButton(icon="fa.remove")
|
||||
else:
|
||||
bu = LPushButton("选择" + ("文件夹" if isdir else "文件"))
|
||||
clear = LPushButton("清除")
|
||||
bu.clicked.connect(
|
||||
functools.partial(
|
||||
openfiledirectory,
|
||||
@ -1933,8 +1944,15 @@ def getsimplepatheditor(
|
||||
callback,
|
||||
)
|
||||
)
|
||||
|
||||
def __(_cb, _e):
|
||||
_cb("")
|
||||
_e.setText("")
|
||||
|
||||
clear.clicked.connect(functools.partial(__, callback, e))
|
||||
lay.addWidget(e)
|
||||
lay.addWidget(bu)
|
||||
lay.addWidget(clear)
|
||||
return lay
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@ allsubprocess2 = {}
|
||||
|
||||
|
||||
class autoproc:
|
||||
def __init__(self, proc) -> None:
|
||||
def __init__(self, proc: subprocess.Popen) -> None:
|
||||
self.proc = proc
|
||||
|
||||
def __del__(self):
|
||||
@ -15,7 +15,9 @@ class autoproc:
|
||||
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
|
||||
startupinfo = subprocess.STARTUPINFO()
|
||||
|
@ -67,19 +67,6 @@ class TS(basetrans):
|
||||
)
|
||||
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):
|
||||
if self.tgtlang not in ["936", "950"]:
|
||||
return ""
|
||||
@ -93,7 +80,8 @@ class TS(basetrans):
|
||||
if len(line) == 0:
|
||||
continue
|
||||
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 = xx.decode("utf-16-le", errors="ignore")
|
||||
ress.append(xx)
|
||||
|
@ -8,65 +8,47 @@ from ctypes import cast, POINTER, c_char, c_int32
|
||||
|
||||
|
||||
class TTS(TTSbase):
|
||||
def checkchange(self):
|
||||
def init(self):
|
||||
exepath = os.path.join(os.getcwd(), "files/plugins/shareddllproxy32.exe")
|
||||
t = time.time()
|
||||
t = str(t)
|
||||
pipename = "\\\\.\\Pipe\\voiceroid2_" + t
|
||||
waitsignal = "voiceroid2waitload_" + t
|
||||
mapname = "voiceroid2filemap" + t
|
||||
idx = self.privateconfig["voice"].split("_")[-1]
|
||||
hkey = self.privateconfig["voice"][: -len(idx) - 1]
|
||||
|
||||
if self.voicexx != (hkey, idx):
|
||||
self.voicexx = (hkey, idx)
|
||||
cmd = '"{}" neospeech {} {} {} {} {} '.format(
|
||||
exepath, pipename, waitsignal, mapname, hkey, idx
|
||||
)
|
||||
cmd = '"{}" neospeech {} {} {}'.format(exepath, pipename, waitsignal, mapname)
|
||||
|
||||
self.engine = autoproc(subproc_w(cmd, name="neospeech"))
|
||||
self.engine = autoproc(subproc_w(cmd, name=str(time.time())))
|
||||
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
windows.GENERIC_READ | windows.GENERIC_WRITE,
|
||||
0,
|
||||
0,
|
||||
1024 * 1024 * 10,
|
||||
None,
|
||||
windows.OPEN_EXISTING,
|
||||
windows.FILE_ATTRIBUTE_NORMAL,
|
||||
None,
|
||||
)
|
||||
)
|
||||
|
||||
def init(self):
|
||||
|
||||
self.voicexx = (0, 0)
|
||||
self.voicelist = self.getvoicelist()
|
||||
|
||||
def voiceshowmap(self, voice):
|
||||
|
||||
idx = voice.split("_")[-1]
|
||||
hk = voice[: -len(idx) - 1]
|
||||
|
||||
return self.mapx[(hk, idx)]
|
||||
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,
|
||||
1024 * 1024 * 10,
|
||||
)
|
||||
|
||||
def getvoicelist(self):
|
||||
cachefname = gobject.gettempdir(f"{time.time()}.txt")
|
||||
@ -75,23 +57,22 @@ class TTS(TTSbase):
|
||||
|
||||
with open(cachefname, "r", encoding="utf-16-le") as ff:
|
||||
readf = ff.read()
|
||||
|
||||
print(readf)
|
||||
os.remove(cachefname)
|
||||
datas = (readf.split("\n"))[:-1]
|
||||
|
||||
self.mapx = {}
|
||||
xx = []
|
||||
internal = []
|
||||
vis = []
|
||||
for i in range(len(datas) // 3):
|
||||
self.mapx[(datas[i * 3 + 1], datas[i * 3 + 2])] = datas[i * 3]
|
||||
xx.append("{}_{}".format(datas[i * 3 + 1], datas[i * 3 + 2]))
|
||||
internal.append((datas[i * 3 + 1], datas[i * 3 + 2]))
|
||||
vis.append(datas[i * 3])
|
||||
return internal, vis
|
||||
|
||||
return xx
|
||||
|
||||
def speak(self, content, rate, voice, voice_idx):
|
||||
self.checkchange()
|
||||
def speak(self, content, rate, voice):
|
||||
hkey, idx = voice
|
||||
windows.WriteFile(self.hPipe, bytes(ctypes.c_uint(rate)))
|
||||
buf = ctypes.create_unicode_buffer(content, 10000)
|
||||
windows.WriteFile(self.hPipe, bytes(buf))
|
||||
windows.WriteFile(self.hPipe, content.encode("utf-16-le"))
|
||||
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
|
||||
|
||||
return cast(self.mem, POINTER(c_char))[:size]
|
||||
|
@ -1,5 +1,5 @@
|
||||
from myutils.config import globalconfig
|
||||
import threading, os, functools
|
||||
import functools, threading
|
||||
from myutils.wrapper import threader
|
||||
from traceback import print_exc
|
||||
from myutils.proxy import getproxy
|
||||
@ -8,16 +8,12 @@ from myutils.proxy import getproxy
|
||||
class TTSbase:
|
||||
typename = None
|
||||
|
||||
def init(self):
|
||||
pass
|
||||
|
||||
def init(self): ...
|
||||
def getvoicelist(self):
|
||||
return []
|
||||
# 分别返回内部标识名,显示
|
||||
return [], []
|
||||
|
||||
def voiceshowmap(self, voice):
|
||||
return voice
|
||||
|
||||
def speak(self, content, rate, volume, voice, voiceindex):
|
||||
def speak(self, content, rate, voice):
|
||||
return None # fname ,若为None则是不需要文件直接朗读
|
||||
|
||||
####################
|
||||
@ -28,68 +24,79 @@ class TTSbase:
|
||||
|
||||
@property
|
||||
def config(self):
|
||||
return self.privateconfig["args"]
|
||||
return globalconfig["reader"][self.typename]["args"]
|
||||
|
||||
@property
|
||||
def privateconfig(self):
|
||||
return globalconfig["reader"][self.typename]
|
||||
def volume(self):
|
||||
return globalconfig["ttscommon"]["volume"]
|
||||
|
||||
@property
|
||||
def publicconfig(self):
|
||||
return globalconfig["ttscommon"]
|
||||
def rate(self):
|
||||
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.showlistsignal = showlistsignal
|
||||
self.voicelistsignal = voicelistsignal
|
||||
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.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):
|
||||
volume = self.publicconfig["volume"]
|
||||
|
||||
def _(force, volume, data):
|
||||
self.playaudiofunction(data, volume, force)
|
||||
|
||||
self.ttscallback(content, functools.partial(_, force, volume))
|
||||
self.ttscallback(content, functools.partial(_, force, self.volume))
|
||||
|
||||
@threader
|
||||
def ttscallback(self, content, callback):
|
||||
if self.loadok == False:
|
||||
return
|
||||
|
||||
if len(content) == 0:
|
||||
return
|
||||
if len(self.voicelist) == 0:
|
||||
return
|
||||
rate = self.publicconfig["rate"]
|
||||
voice = self.privateconfig["voice"]
|
||||
voice_index = self.voicelist.index(voice)
|
||||
try:
|
||||
data = self.speak(content, rate, voice, voice_index)
|
||||
data = self.speak(content, self.rate, self.voice)
|
||||
if data and len(data):
|
||||
callback(data)
|
||||
except:
|
||||
print_exc()
|
||||
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):
|
||||
|
||||
def getvoicelist(self):
|
||||
self.alllist = requests.get(
|
||||
alllist = requests.get(
|
||||
"https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list?trustedclienttoken=6A5AA1D4EAFF4E9FB37E23D68491D6F4",
|
||||
proxies=self.proxy,
|
||||
).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)
|
||||
|
||||
|
||||
|
@ -603,8 +603,8 @@ from myutils.utils import getlangsrc
|
||||
|
||||
class TTS(TTSbase):
|
||||
def getvoicelist(self):
|
||||
return [""]
|
||||
return [""], [""]
|
||||
|
||||
def speak(self, content, rate, voice, voiceidx):
|
||||
def speak(self, content, rate, voice):
|
||||
tts = gTTS(self, content, lang=getlangsrc())
|
||||
return tts.save()
|
||||
|
@ -6,7 +6,7 @@ from tts.basettsclass import TTSbase
|
||||
|
||||
class TTS(TTSbase):
|
||||
def getvoicelist(self):
|
||||
return [
|
||||
_= [
|
||||
"jp_male_satoshi",
|
||||
"jp_female_mai",
|
||||
"zh_male_rap",
|
||||
@ -20,8 +20,9 @@ class TTS(TTSbase):
|
||||
"en_male_bob",
|
||||
"en_female_sarah",
|
||||
]
|
||||
return _, _
|
||||
|
||||
def speak(self, content, rate, voice, voiceidx):
|
||||
def speak(self, content, rate, voice):
|
||||
|
||||
headers = {
|
||||
"authority": "translate.volcengine.com",
|
||||
|
@ -9,7 +9,7 @@ class TTS(TTSbase):
|
||||
responseVits = requests.get(
|
||||
f"http://127.0.0.1:{self.config['Port']}/voice/speakers"
|
||||
).json()
|
||||
self.voicelist = []
|
||||
voicelist = []
|
||||
|
||||
# 获取所有模型类型,对于每个模型类型下的模型信息,将其 modelType、id、name 合成一个字符串
|
||||
modelTypes = responseVits.keys()
|
||||
@ -17,13 +17,10 @@ class TTS(TTSbase):
|
||||
vits_data = responseVits[modelType]
|
||||
for item in vits_data:
|
||||
model_info = f'{modelType}_{item["id"]}_{item["name"]}'
|
||||
self.voicelist.append(model_info)
|
||||
return self.voicelist
|
||||
voicelist.append(model_info)
|
||||
return voicelist, voicelist
|
||||
|
||||
def voiceshowmap(self, voice):
|
||||
return voice
|
||||
|
||||
def speak(self, content, rate, voice, voiceidx):
|
||||
def speak(self, content, rate, voice):
|
||||
encoded_content = quote(content)
|
||||
idx = int(voice.split("_")[1])
|
||||
model = str.lower(voice.split("_")[0])
|
||||
|
@ -2,19 +2,11 @@ import time
|
||||
import os
|
||||
import windows
|
||||
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
|
||||
import threading
|
||||
|
||||
|
||||
class TTS(TTSbase):
|
||||
|
||||
def init(self):
|
||||
self.status = None
|
||||
|
||||
self.voicelist = self.getvoicelist()
|
||||
threading.Thread(target=self.checkpath).start()
|
||||
|
||||
def getvoicelist(self):
|
||||
voicelist = []
|
||||
if os.path.exists(self.config["path"]) == False:
|
||||
@ -27,7 +19,7 @@ class TTS(TTSbase):
|
||||
if len(_l) >= 2:
|
||||
if _l[-1] == "44" or _l[-1] == "22":
|
||||
voicelist.append(_)
|
||||
return voicelist
|
||||
return voicelist, [self.voiceshowmap(_) for _ in voicelist]
|
||||
|
||||
def voiceshowmap(self, voice):
|
||||
name = voice.split("_")[0]
|
||||
@ -56,98 +48,77 @@ class TTS(TTSbase):
|
||||
vv += "(関西弁)"
|
||||
return vv
|
||||
|
||||
def checkpath(self):
|
||||
if self.config["path"] == "":
|
||||
return False
|
||||
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")
|
||||
def init(self):
|
||||
dllpath = os.path.join(self.config["path"], "aitalked.dll")
|
||||
exepath = os.path.join(os.getcwd(), "files/plugins/shareddllproxy32.exe")
|
||||
|
||||
t = time.time()
|
||||
t = str(t)
|
||||
pipename = "\\\\.\\Pipe\\voiceroid2_" + t
|
||||
waitsignal = "voiceroid2waitload_" + t
|
||||
mapname = "voiceroid2filemap" + t
|
||||
t = time.time()
|
||||
t = str(t)
|
||||
pipename = "\\\\.\\Pipe\\voiceroid2_" + t
|
||||
waitsignal = "voiceroid2waitload_" + t
|
||||
mapname = "voiceroid2filemap" + t
|
||||
|
||||
def linear_map(x):
|
||||
if x >= 0:
|
||||
x = 0.1 * x + 1.0
|
||||
else:
|
||||
x = 0.05 * x + 1.0
|
||||
return x
|
||||
|
||||
"".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(
|
||||
self.engine = autoproc(
|
||||
subproc_w(
|
||||
'"{}" voiceroid2 "{}" "{}" {} {} {}'.format(
|
||||
exepath,
|
||||
self.config["path"],
|
||||
dllpath,
|
||||
pipename,
|
||||
windows.GENERIC_READ | windows.GENERIC_WRITE,
|
||||
0,
|
||||
None,
|
||||
windows.OPEN_EXISTING,
|
||||
windows.FILE_ATTRIBUTE_NORMAL,
|
||||
None,
|
||||
)
|
||||
waitsignal,
|
||||
mapname,
|
||||
),
|
||||
name=str(time.time()),
|
||||
)
|
||||
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,
|
||||
)
|
||||
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,
|
||||
windows.GENERIC_READ | windows.GENERIC_WRITE,
|
||||
0,
|
||||
0,
|
||||
1024 * 1024 * 10,
|
||||
None,
|
||||
windows.OPEN_EXISTING,
|
||||
windows.FILE_ATTRIBUTE_NORMAL,
|
||||
None,
|
||||
)
|
||||
|
||||
self.status = (
|
||||
self.config["path"],
|
||||
self.privateconfig["voice"],
|
||||
self.publicconfig["rate"],
|
||||
)
|
||||
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,
|
||||
1024 * 1024 * 10,
|
||||
)
|
||||
|
||||
def speak(self, content, rate, voice, voice_idx):
|
||||
self.checkpath()
|
||||
def linear_map(self, x):
|
||||
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:
|
||||
code1 = content.encode("shift-jis")
|
||||
except:
|
||||
return
|
||||
windows.WriteFile(self.hPipe, voice.encode())
|
||||
windows.WriteFile(self.hPipe, bytes(c_float(_2)))
|
||||
windows.WriteFile(self.hPipe, code1)
|
||||
|
||||
size = c_int32.from_buffer_copy(windows.ReadFile(self.hPipe, 4)).value
|
||||
|
@ -1,31 +1,11 @@
|
||||
import time
|
||||
import os
|
||||
import requests, json
|
||||
from traceback import print_exc
|
||||
from tts.basettsclass import TTSbase
|
||||
|
||||
from myutils.subproc import subproc_w, autoproc
|
||||
|
||||
|
||||
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):
|
||||
while True:
|
||||
try:
|
||||
@ -53,32 +33,27 @@ class TTS(TTSbase):
|
||||
proxies={"http": None, "https": None},
|
||||
).json()
|
||||
print(response)
|
||||
# self.voicelist=[_['name'] for _ in response]
|
||||
# return self.voicelist
|
||||
voicedict = {}
|
||||
vis=[]
|
||||
idxs=[]
|
||||
for speaker in response:
|
||||
name=speaker['name']
|
||||
styles = speaker["styles"]
|
||||
for style in styles:
|
||||
voicedict[style["id"]] = "%s(%s)" % (
|
||||
speaker["name"],
|
||||
style["name"],
|
||||
)
|
||||
self.voicelist = [
|
||||
"%02d %s" % (i, voicedict[i]) for i in range(len(voicedict))
|
||||
]
|
||||
return self.voicelist
|
||||
idxs.append(style['id'])
|
||||
vis.append(name+ ' '+ style["name"])
|
||||
|
||||
return idxs, vis
|
||||
except:
|
||||
print_exc()
|
||||
time.sleep(1)
|
||||
break
|
||||
|
||||
def speak(self, content, rate, voice, voiceidx):
|
||||
|
||||
def speak(self, content, rate, voice):
|
||||
headers = {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
}
|
||||
|
||||
params = {"speaker": voiceidx, "text": content}
|
||||
params = {"speaker": voice, "text": content}
|
||||
|
||||
response = requests.post(
|
||||
f"http://localhost:{self.config['Port']}/audio_query",
|
||||
@ -87,12 +62,11 @@ class TTS(TTSbase):
|
||||
proxies={"http": None, "https": None},
|
||||
)
|
||||
print(response.json())
|
||||
fname = str(time.time())
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
params = {
|
||||
"speaker": voiceidx,
|
||||
"speaker": voice,
|
||||
}
|
||||
response = requests.post(
|
||||
f"http://localhost:{self.config['Port']}/synthesis",
|
||||
@ -100,4 +74,4 @@ class TTS(TTSbase):
|
||||
headers=headers,
|
||||
data=json.dumps(response.json()),
|
||||
)
|
||||
return response.content
|
||||
return response.content
|
||||
|
@ -24,9 +24,9 @@ class TTS(TTSbase):
|
||||
|
||||
for _ in needremove:
|
||||
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:
|
||||
version = 10
|
||||
voice_idx = self._10m[voice]
|
||||
|
@ -1,16 +1,12 @@
|
||||
import requests
|
||||
import time, os
|
||||
from tts.basettsclass import TTSbase
|
||||
|
||||
|
||||
class TTS(TTSbase):
|
||||
def getvoicelist(self):
|
||||
return ["ja", "zh", "en"]
|
||||
return ["ja", "zh", "en"], ["Japanese","Chinese","English"]
|
||||
|
||||
def voiceshowmap(self, voice):
|
||||
return {"ja": "Japanese", "zh": "Chinese", "en": "English"}[voice]
|
||||
|
||||
def speak(self, content, rate, voice, voiceidx):
|
||||
def speak(self, content, rate, voice):
|
||||
|
||||
headers = {
|
||||
"Accept": "*/*",
|
||||
|
@ -1088,7 +1088,6 @@
|
||||
"name": "VOICEVOX",
|
||||
"type": "offline",
|
||||
"args": {
|
||||
"path": "",
|
||||
"Port": 50021
|
||||
},
|
||||
"argstype": {
|
||||
@ -1098,11 +1097,6 @@
|
||||
"max": 65535,
|
||||
"step": 1,
|
||||
"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",
|
||||
"延申": "Yanshen.",
|
||||
"进入时才显示": "Zobrazeno pouze při vstupu",
|
||||
"语音跳过": "Přeskakování hlasu",
|
||||
"条件": "stav",
|
||||
"指定人名翻译": "Překlad označeného názvu",
|
||||
"专有名词翻译": "Překlad vlastnických pojmů",
|
||||
@ -845,5 +844,9 @@
|
||||
"识别方向": "Určit směr",
|
||||
"横向": "příčná",
|
||||
"竖向": "vertikální",
|
||||
"自适应": "samostatná adaptace"
|
||||
"自适应": "samostatná adaptace",
|
||||
"清除": "eliminovat",
|
||||
"语音指定": "Označení hlasu",
|
||||
"指定为": "Určeno jako",
|
||||
"跳过": "přeskočit"
|
||||
}
|
@ -779,7 +779,6 @@
|
||||
"安装": "installieren",
|
||||
"延申": "Yanshen",
|
||||
"进入时才显示": "Nur bei Eingabe angezeigt",
|
||||
"语音跳过": "Sprachüberspringen",
|
||||
"条件": "Zustand",
|
||||
"指定人名翻译": "Übersetzung benannter Namen",
|
||||
"专有名词翻译": "Übersetzung von geschützten Begriffen",
|
||||
@ -845,5 +844,9 @@
|
||||
"识别方向": "Richtung bestimmen",
|
||||
"横向": "quer",
|
||||
"竖向": "vertikal",
|
||||
"自适应": "Selbstanpassung"
|
||||
"自适应": "Selbstanpassung",
|
||||
"清除": "eliminieren",
|
||||
"语音指定": "Sprachbezeichnung",
|
||||
"指定为": "Bestimmt als",
|
||||
"跳过": "überspringen"
|
||||
}
|
@ -777,7 +777,6 @@
|
||||
"安装": "install",
|
||||
"延申": "Extension",
|
||||
"进入时才显示": "Displayed only upon entry",
|
||||
"语音跳过": "Voice skipping",
|
||||
"条件": "condition",
|
||||
"指定人名翻译": "Designated Name Translation",
|
||||
"专有名词翻译": "Translation of proprietary terms",
|
||||
@ -845,5 +844,9 @@
|
||||
"识别方向": "Identify direction",
|
||||
"横向": "transverse",
|
||||
"竖向": "vertical ",
|
||||
"自适应": "self-adaption"
|
||||
"自适应": "self-adaption",
|
||||
"清除": "eliminate",
|
||||
"语音指定": "Voice designation",
|
||||
"指定为": "Designated as",
|
||||
"跳过": "skip"
|
||||
}
|
@ -777,7 +777,6 @@
|
||||
"安装": "Instalación",
|
||||
"延申": "Extensión",
|
||||
"进入时才显示": "Se muestra al entrar",
|
||||
"语音跳过": "Salto de voz",
|
||||
"条件": "Condiciones",
|
||||
"指定人名翻译": "Traducción de nombre designado",
|
||||
"专有名词翻译": "Traducción de términos propios",
|
||||
@ -845,5 +844,9 @@
|
||||
"识别方向": "Identificar la dirección",
|
||||
"横向": "Horizontal",
|
||||
"竖向": "Vertical",
|
||||
"自适应": "Autoadaptación"
|
||||
"自适应": "Autoadaptación",
|
||||
"清除": "Eliminar",
|
||||
"语音指定": "Designación de voz",
|
||||
"指定为": "Designado como",
|
||||
"跳过": "Saltar"
|
||||
}
|
@ -777,7 +777,6 @@
|
||||
"安装": "Installation",
|
||||
"延申": "Yanshin",
|
||||
"进入时才显示": "Ne s'affiche qu'à l'entrée",
|
||||
"语音跳过": "Voix skip",
|
||||
"条件": "Conditions",
|
||||
"指定人名翻译": "Nom de la personne désignée traduction",
|
||||
"专有名词翻译": "Traduction de noms propres",
|
||||
@ -845,5 +844,9 @@
|
||||
"识别方向": "Identification des directions",
|
||||
"横向": "Latéralement",
|
||||
"竖向": "Verticalement",
|
||||
"自适应": "Adaptatif"
|
||||
"自适应": "Adaptatif",
|
||||
"清除": "Effacer",
|
||||
"语音指定": "Désignation vocale",
|
||||
"指定为": "Désigné comme",
|
||||
"跳过": "Sauter"
|
||||
}
|
@ -777,7 +777,6 @@
|
||||
"安装": "installa",
|
||||
"延申": "Estensione",
|
||||
"进入时才显示": "Visualizzato solo all'entrata",
|
||||
"语音跳过": "Salto vocale",
|
||||
"条件": "condizione",
|
||||
"指定人名翻译": "Traduzione del nome designato",
|
||||
"专有名词翻译": "Traduzione di termini proprietari",
|
||||
@ -845,5 +844,9 @@
|
||||
"识别方向": "Identifica la direzione",
|
||||
"横向": "trasversale",
|
||||
"竖向": "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",
|
||||
"延申": "Yanshen.",
|
||||
"进入时才显示": "Alleen weergegeven bij binnenkomst",
|
||||
"语音跳过": "Stem overslaan",
|
||||
"条件": "conditie",
|
||||
"指定人名翻译": "Vertaling van aangewezen naam",
|
||||
"专有名词翻译": "Vertaling van eigendomstermen",
|
||||
@ -845,5 +844,9 @@
|
||||
"识别方向": "Identificeer richting",
|
||||
"横向": "dwars",
|
||||
"竖向": "verticaal",
|
||||
"自适应": "zelfaanpassing"
|
||||
"自适应": "zelfaanpassing",
|
||||
"清除": "elimineren",
|
||||
"语音指定": "Stembepaling",
|
||||
"指定为": "Aangeduid als",
|
||||
"跳过": "overslaan"
|
||||
}
|
@ -777,7 +777,6 @@
|
||||
"安装": "instaluj",
|
||||
"延申": "Rozszerzenie",
|
||||
"进入时才显示": "Wyświetlane tylko przy wejściu",
|
||||
"语音跳过": "Przeskakiwanie głosu",
|
||||
"条件": "stan",
|
||||
"指定人名翻译": "Tłumaczenie oznaczonej nazwy",
|
||||
"专有名词翻译": "Tłumaczenie terminów własności",
|
||||
@ -845,5 +844,9 @@
|
||||
"识别方向": "Określić kierunek",
|
||||
"横向": "poprzeczne",
|
||||
"竖向": "pionowy",
|
||||
"自适应": "samodzielna adaptacja"
|
||||
"自适应": "samodzielna adaptacja",
|
||||
"清除": "wyeliminować",
|
||||
"语音指定": "Oznaczenie głosu",
|
||||
"指定为": "Wyznaczony jako",
|
||||
"跳过": "pominięcie"
|
||||
}
|
@ -779,7 +779,6 @@
|
||||
"安装": "instalar",
|
||||
"延申": "Yanshen",
|
||||
"进入时才显示": "Apresentado apenas no momento da entrada",
|
||||
"语音跳过": "Saltar a voz",
|
||||
"条件": "condição",
|
||||
"指定人名翻译": "Tradução de Nomes Designados",
|
||||
"专有名词翻译": "Tradução de termos proprietários",
|
||||
@ -845,5 +844,9 @@
|
||||
"识别方向": "Identificar a direcção",
|
||||
"横向": "transversal",
|
||||
"竖向": "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",
|
||||
"延申": "Yanshen",
|
||||
"进入时才显示": "Visas endast vid inmatning",
|
||||
"语音跳过": "Rösthoppande",
|
||||
"条件": "tillstånd",
|
||||
"指定人名翻译": "Översättning av betecknat namn",
|
||||
"专有名词翻译": "Översättning av egendomsbenämningar",
|
||||
@ -845,5 +844,9 @@
|
||||
"识别方向": "Identifiera riktning",
|
||||
"横向": "tvärgående",
|
||||
"竖向": "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",
|
||||
"延申": "Uzantı",
|
||||
"进入时才显示": "Sadece giriş üzerinde gösterilir",
|
||||
"语音跳过": "Ses atlama",
|
||||
"条件": "durum",
|
||||
"指定人名翻译": "Tasarlanmış İsim Çevirmesi",
|
||||
"专有名词翻译": "Özel terimlerin çevirimi",
|
||||
@ -845,5 +844,9 @@
|
||||
"识别方向": "Doğru belirle",
|
||||
"横向": "transverse",
|
||||
"竖向": "dikey",
|
||||
"自适应": "kendi uygulama"
|
||||
"自适应": "kendi uygulama",
|
||||
"清除": "sil",
|
||||
"语音指定": "Ses tasarımı",
|
||||
"指定为": "Şöyle tasarlanmıştır",
|
||||
"跳过": "atla"
|
||||
}
|
@ -777,7 +777,6 @@
|
||||
"安装": "встановити",
|
||||
"延申": "Розширення",
|
||||
"进入时才显示": "Показано лише після запису",
|
||||
"语音跳过": "Пропускання голосу",
|
||||
"条件": "умови",
|
||||
"指定人名翻译": "Переклад визначеної назви",
|
||||
"专有名词翻译": "Переклад приєднаних термінів",
|
||||
@ -845,5 +844,9 @@
|
||||
"识别方向": "Визначити напрямок",
|
||||
"横向": "transverse",
|
||||
"竖向": "вертикальна",
|
||||
"自适应": "самоадаптація"
|
||||
"自适应": "самоадаптація",
|
||||
"清除": "вилучити",
|
||||
"语音指定": "Визначення голосу",
|
||||
"指定为": "Визначено як",
|
||||
"跳过": "пропустити"
|
||||
}
|
@ -777,7 +777,6 @@
|
||||
"安装": "Cài đặt",
|
||||
"延申": "Dương Thân",
|
||||
"进入时才显示": "Hiển thị khi vào",
|
||||
"语音跳过": "Bỏ qua giọng nói",
|
||||
"条件": "Điều kiện",
|
||||
"指定人名翻译": "Name",
|
||||
"专有名词翻译": "Bản dịch của proprietary noun",
|
||||
@ -845,5 +844,9 @@
|
||||
"识别方向": "Xác định hướng",
|
||||
"横向": "Phong cảnh",
|
||||
"竖向": "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)
|
||||
|
||||
set(VERSION_MAJOR 5)
|
||||
set(VERSION_MINOR 21)
|
||||
set(VERSION_PATCH 2)
|
||||
set(VERSION_MINOR 22)
|
||||
set(VERSION_PATCH 0)
|
||||
|
||||
add_library(pch pch.cpp)
|
||||
target_precompile_headers(pch PUBLIC pch.h)
|
||||
|
@ -4,24 +4,10 @@
|
||||
|
||||
#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[])
|
||||
{
|
||||
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");
|
||||
HMODULE module = LoadLibraryW(argv[1]);
|
||||
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 *to = new wchar_t[3000];
|
||||
wchar_t *buf = new wchar_t[3000];
|
||||
|
||||
|
||||
SetEvent(CreateEvent(&allAccess, FALSE, FALSE, argv[3]));
|
||||
if (ConnectNamedPipe(hPipe, NULL) != NULL)
|
||||
{
|
||||
@ -64,13 +50,10 @@ int jbjwmain(int argc, wchar_t *argv[])
|
||||
memset(buf, 0, 3000 * sizeof(wchar_t));
|
||||
int a = 3000;
|
||||
int b = 3000;
|
||||
char codec[4] = {0};
|
||||
UINT code;
|
||||
DWORD _;
|
||||
|
||||
ReadFile(hPipe, intcache, 4, &_, NULL);
|
||||
|
||||
code = unpackuint32(intcache);
|
||||
ReadFile(hPipe, &code, 4, &_, NULL);
|
||||
|
||||
if (!ReadFile(hPipe, (unsigned char *)fr, 6000, &_, NULL))
|
||||
break;
|
||||
|
@ -26,8 +26,6 @@ int neospeechlist(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);
|
||||
|
||||
@ -41,12 +39,11 @@ int neospeech(int argc, wchar_t *argv[])
|
||||
{
|
||||
DWORD len = 0;
|
||||
}
|
||||
int II = 0;
|
||||
wchar_t text[10000];
|
||||
DWORD _;
|
||||
while (true)
|
||||
{
|
||||
wchar_t text[10000];
|
||||
II += 1;
|
||||
DWORD _;
|
||||
ZeroMemory(text, sizeof(text));
|
||||
int speed;
|
||||
if (!ReadFile(hPipe, (unsigned char *)&speed, 4, &_, NULL))
|
||||
break;
|
||||
@ -54,7 +51,15 @@ int neospeech(int argc, wchar_t *argv[])
|
||||
break;
|
||||
std::wstring content = text;
|
||||
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)
|
||||
{
|
||||
memcpy(mapview, data.value().data(), data.value().size());
|
||||
|
@ -299,9 +299,6 @@ namespace ebyroid
|
||||
param->lenRawBufBytes = kConfigRawbufSize;
|
||||
|
||||
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);
|
||||
printf("SetParam ok %d\n", result);
|
||||
if (result != ERR_SUCCESS)
|
||||
|
@ -15,34 +15,56 @@ int voiceroid2wmain(int argc, wchar_t *wargv[])
|
||||
argv[i] = new char[length];
|
||||
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",
|
||||
(const char *)argv[2],
|
||||
(const char *)argv[3], //"yukari_emo_44",
|
||||
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]);
|
||||
std::string last;
|
||||
float rate = -1;
|
||||
auto handle = CreateFileMappingA(INVALID_HANDLE_VALUE, &allAccess, PAGE_EXECUTE_READWRITE, 0, 1024 * 1024 * 10, argv[5]);
|
||||
|
||||
auto mapview = (char *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 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);
|
||||
int freq1 = atoi(argv[4]);
|
||||
int freq1;
|
||||
unsigned char input_j[4096] = {0};
|
||||
DWORD _;
|
||||
while (true)
|
||||
{
|
||||
ZeroMemory(input_j, sizeof(input_j));
|
||||
unsigned char *out;
|
||||
size_t output_size;
|
||||
int16_t *out2;
|
||||
|
||||
unsigned char input_j[4096] = {0};
|
||||
DWORD _;
|
||||
if (!ReadFile(hPipe, input_j, 4096, &_, NULL))
|
||||
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 *)input_j, &out, &output_size);
|
||||
|
||||
@ -83,6 +105,5 @@ int voiceroid2wmain(int argc, wchar_t *wargv[])
|
||||
free(out);
|
||||
free(out2);
|
||||
}
|
||||
// sndPlaySound((const char*)argv[6], SND_SYNC);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user