This commit is contained in:
恍兮惚兮 2024-08-05 19:56:47 +08:00
parent 3b000950bd
commit 8761f09c0f
45 changed files with 608 additions and 494 deletions

View File

@ -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])

View File

@ -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",
), ),

View File

@ -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):

View File

@ -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])

View File

@ -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)

View File

@ -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",
), ),

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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]

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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",

View File

@ -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])

View File

@ -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

View File

@ -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

View File

@ -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]

View File

@ -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": "*/*",

View File

@ -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
} }
} }
}, },

View File

@ -777,7 +777,6 @@
"安装": "تركيب .", "安装": "تركيب .",
"延申": "تمديد", "延申": "تمديد",
"进入时才显示": "عرض فقط عند الدخول", "进入时才显示": "عرض فقط عند الدخول",
"语音跳过": "صوت تخطي",
"条件": "شرط .", "条件": "شرط .",
"指定人名翻译": "تعيين اسم المترجم", "指定人名翻译": "تعيين اسم المترجم",
"专有名词翻译": "ترجمة الأسماء الصحيحة", "专有名词翻译": "ترجمة الأسماء الصحيحة",
@ -845,5 +844,9 @@
"识别方向": "تحديد الاتجاه", "识别方向": "تحديد الاتجاه",
"横向": "بشكل مستعرض", "横向": "بشكل مستعرض",
"竖向": "عمودي", "竖向": "عمودي",
"自适应": "تكيف ذاتي" "自适应": "تكيف ذاتي",
"清除": "مسح",
"语音指定": "صوت محدد",
"指定为": "تعيين",
"跳过": "تخطي"
} }

View File

@ -777,7 +777,6 @@
"安装": "安裝", "安装": "安裝",
"延申": "延伸", "延申": "延伸",
"进入时才显示": "進入時才顯示", "进入时才显示": "進入時才顯示",
"语音跳过": "語音跳過",
"条件": "條件", "条件": "條件",
"指定人名翻译": "指定人名翻譯", "指定人名翻译": "指定人名翻譯",
"专有名词翻译": "專有名詞翻譯", "专有名词翻译": "專有名詞翻譯",
@ -845,5 +844,9 @@
"识别方向": "識別方向", "识别方向": "識別方向",
"横向": "橫向", "横向": "橫向",
"竖向": "豎向", "竖向": "豎向",
"自适应": "自我調整" "自适应": "自我調整",
"清除": "清除",
"语音指定": "語音指定",
"指定为": "指定為",
"跳过": "跳過"
} }

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -777,7 +777,6 @@
"安装": "インストール", "安装": "インストール",
"延申": "に言及", "延申": "に言及",
"进入时才显示": "入力時に表示", "进入时才显示": "入力時に表示",
"语音跳过": "音声スキップ",
"条件": "条件#ジョウケン#", "条件": "条件#ジョウケン#",
"指定人名翻译": "指定人名翻訳", "指定人名翻译": "指定人名翻訳",
"专有名词翻译": "固有名詞の翻訳", "专有名词翻译": "固有名詞の翻訳",
@ -845,5 +844,9 @@
"识别方向": "方向を識別する", "识别方向": "方向を識別する",
"横向": "横方向", "横向": "横方向",
"竖向": "垂直方向", "竖向": "垂直方向",
"自适应": "てきおう" "自适应": "てきおう",
"清除": "パージ",
"语音指定": "音声指定",
"指定为": "指定#シテイ#",
"跳过": "スキップ"
} }

View File

@ -777,7 +777,6 @@
"安装": "설치", "安装": "설치",
"延申": "연장", "延申": "연장",
"进入时才显示": "들어갈 때만 표시", "进入时才显示": "들어갈 때만 표시",
"语音跳过": "음성 건너뛰기",
"条件": "조건", "条件": "조건",
"指定人名翻译": "사용자 이름 번역 지정", "指定人名翻译": "사용자 이름 번역 지정",
"专有名词翻译": "고유명사 번역", "专有名词翻译": "고유명사 번역",
@ -845,5 +844,9 @@
"识别方向": "방향 식별", "识别方向": "방향 식별",
"横向": "가로", "横向": "가로",
"竖向": "세로 방향", "竖向": "세로 방향",
"自适应": "적응성" "自适应": "적응성",
"清除": "지우기",
"语音指定": "음성 지정",
"指定为": "다음으로 지정",
"跳过": "건너뛰기"
} }

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -777,7 +777,6 @@
"安装": "Монтаж", "安装": "Монтаж",
"延申": "Яньшэнь", "延申": "Яньшэнь",
"进入时才显示": "Показать при входе", "进入时才显示": "Показать при входе",
"语音跳过": "Голос скачать",
"条件": "Условия", "条件": "Условия",
"指定人名翻译": "Имя назначенного переводчика", "指定人名翻译": "Имя назначенного переводчика",
"专有名词翻译": "Перевод терминов", "专有名词翻译": "Перевод терминов",
@ -845,5 +844,9 @@
"识别方向": "Распознать направление", "识别方向": "Распознать направление",
"横向": "Горизонтальный", "横向": "Горизонтальный",
"竖向": "Вертикально", "竖向": "Вертикально",
"自适应": "Самоадаптация" "自适应": "Самоадаптация",
"清除": "Очистить",
"语音指定": "Голосовое назначение",
"指定为": "Назначено",
"跳过": "Пропустить"
} }

View File

@ -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"
} }

View File

@ -777,7 +777,6 @@
"安装": "การติดตั้ง", "安装": "การติดตั้ง",
"延申": "ยันชิน", "延申": "ยันชิน",
"进入时才显示": "แสดงเฉพาะเมื่อเข้า", "进入时才显示": "แสดงเฉพาะเมื่อเข้า",
"语音跳过": "ข้ามเสียง",
"条件": "เงื่อนไข", "条件": "เงื่อนไข",
"指定人名翻译": "ระบุการแปลชื่อบุคคล", "指定人名翻译": "ระบุการแปลชื่อบุคคล",
"专有名词翻译": "การแปลคำนามที่เป็นกรรมสิทธิ์", "专有名词翻译": "การแปลคำนามที่เป็นกรรมสิทธิ์",
@ -845,5 +844,9 @@
"识别方向": "ระบุทิศทาง", "识别方向": "ระบุทิศทาง",
"横向": "แนวนอน", "横向": "แนวนอน",
"竖向": "แนวตรง", "竖向": "แนวตรง",
"自适应": "การปรับตัว" "自适应": "การปรับตัว",
"清除": "ล้าง",
"语音指定": "การกำหนดเสียง",
"指定为": "กำหนดให้เป็น",
"跳过": "ข้าม"
} }

View File

@ -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"
} }

View File

@ -777,7 +777,6 @@
"安装": "встановити", "安装": "встановити",
"延申": "Розширення", "延申": "Розширення",
"进入时才显示": "Показано лише після запису", "进入时才显示": "Показано лише після запису",
"语音跳过": "Пропускання голосу",
"条件": "умови", "条件": "умови",
"指定人名翻译": "Переклад визначеної назви", "指定人名翻译": "Переклад визначеної назви",
"专有名词翻译": "Переклад приєднаних термінів", "专有名词翻译": "Переклад приєднаних термінів",
@ -845,5 +844,9 @@
"识别方向": "Визначити напрямок", "识别方向": "Визначити напрямок",
"横向": "transverse", "横向": "transverse",
"竖向": "вертикальна", "竖向": "вертикальна",
"自适应": "самоадаптація" "自适应": "самоадаптація",
"清除": "вилучити",
"语音指定": "Визначення голосу",
"指定为": "Визначено як",
"跳过": "пропустити"
} }

View File

@ -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"
} }

View File

@ -780,7 +780,6 @@
"安装": "", "安装": "",
"延申": "", "延申": "",
"进入时才显示": "", "进入时才显示": "",
"语音跳过": "",
"条件": "", "条件": "",
"指定人名翻译": "", "指定人名翻译": "",
"专有名词翻译": "", "专有名词翻译": "",
@ -845,5 +844,9 @@
"识别方向": "", "识别方向": "",
"横向": "", "横向": "",
"竖向": "", "竖向": "",
"自适应": "" "自适应": "",
"清除": "",
"语音指定": "",
"指定为": "",
"跳过": ""
} }

View File

@ -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)

View File

@ -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;

View File

@ -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());

View File

@ -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)

View File

@ -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;
} }