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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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",
"延申": "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"
}

View File

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

View File

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

View File

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

View File

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

View File

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

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",
"延申": "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"
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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