diff --git a/LunaTranslator/LunaTranslator/gui/settin.py b/LunaTranslator/LunaTranslator/gui/settin.py index d3ed3ee9..e2849112 100644 --- a/LunaTranslator/LunaTranslator/gui/settin.py +++ b/LunaTranslator/LunaTranslator/gui/settin.py @@ -79,7 +79,7 @@ class TabWidget(QWidget): class Settin(closeashidewindow): voicelistsignal = pyqtSignal(list, int) - mp3playsignal = pyqtSignal(str, int, bool) + mp3playsignal = pyqtSignal(bytes, int, bool) versiontextsignal = pyqtSignal(str) progresssignal = pyqtSignal(str, int) fontbigsmallsignal = pyqtSignal(int) diff --git a/LunaTranslator/LunaTranslator/gui/settingpage_tts.py b/LunaTranslator/LunaTranslator/gui/settingpage_tts.py index 413894f9..3870b1ce 100644 --- a/LunaTranslator/LunaTranslator/gui/settingpage_tts.py +++ b/LunaTranslator/LunaTranslator/gui/settingpage_tts.py @@ -37,6 +37,7 @@ def getttsgrid(self): continue if "args" in globalconfig["reader"][name]: items = autoinitdialog_items(globalconfig["reader"][name]) + items[-1]["callback"] = gobject.baseobject.startreader _3 = getcolorbutton( globalconfig, "", diff --git a/LunaTranslator/LunaTranslator/gui/showword.py b/LunaTranslator/LunaTranslator/gui/showword.py index 90220393..317772b8 100644 --- a/LunaTranslator/LunaTranslator/gui/showword.py +++ b/LunaTranslator/LunaTranslator/gui/showword.py @@ -12,7 +12,7 @@ from PyQt5.QtWidgets import ( QTabWidget, QFileDialog, QTabBar, - QLabel + QLabel, ) from PyQt5.QtGui import QPixmap, QImage from traceback import print_exc @@ -31,7 +31,7 @@ from gui.usefulwidget import ( getlineedit, getsimpleswitch, getcolorbutton, - tabadd_lazy + tabadd_lazy, ) from myutils.wrapper import threader from myutils.ocrutil import imageCut, ocr_run @@ -54,6 +54,7 @@ class ffmpeg_virtual_audio_capturer: ) except: print_exc() + def end(self): try: self.engine.stdin.write(b"q") @@ -94,16 +95,24 @@ class AnkiWindow(QWidget): __ocrsettext = pyqtSignal(str) refreshhtml = pyqtSignal() + def callbacktts(self, edit, data): + fname = "./cache/tts/" + str(uuid.uuid4()) + ".mp3" + os.makedirs("./cache/tts", exist_ok=True) + with open(fname, "wb") as ff: + ff.write(data) + edit.setText(os.path.abspath(fname)) + def langdu(self): if gobject.baseobject.reader: gobject.baseobject.reader.ttscallback( - self.currentword, self.audiopath.setText + self.currentword, functools.partial(self.callbacktts, self.audiopath) ) def langdu2(self): if gobject.baseobject.reader: gobject.baseobject.reader.ttscallback( - self.example.toPlainText(), self.audiopath_sentence.setText + self.example.toPlainText(), + functools.partial(self.callbacktts, self.audiopath_sentence), ) @threader diff --git a/LunaTranslator/LunaTranslator/gui/textbrowser.py b/LunaTranslator/LunaTranslator/gui/textbrowser.py index 0849f4ea..0d42abdb 100644 --- a/LunaTranslator/LunaTranslator/gui/textbrowser.py +++ b/LunaTranslator/LunaTranslator/gui/textbrowser.py @@ -115,8 +115,8 @@ class BorderedLabel(ShadowLabel): self._type = _type def move(self, point: QPoint): - point.setX(point.x() - self.m_fontOutLineWidth) - point.setY(point.y() - self.m_fontOutLineWidth) + point.setX(int(point.x() - self.m_fontOutLineWidth)) + point.setY(int(point.y() - self.m_fontOutLineWidth)) super().move(point) def adjustSize(self): @@ -124,8 +124,8 @@ class BorderedLabel(ShadowLabel): text = self._m_text font_m = QFontMetrics(font) self.resize( - font_m.width(text) + 2 * self.m_fontOutLineWidth, - font_m.height() + 2 * self.m_fontOutLineWidth, + int(font_m.width(text) + 2 * self.m_fontOutLineWidth), + int(font_m.height() + 2 * self.m_fontOutLineWidth), ) def paintEvent(self, event): diff --git a/LunaTranslator/LunaTranslator/myutils/utils.py b/LunaTranslator/LunaTranslator/myutils/utils.py index 89261ffd..29da5d9b 100644 --- a/LunaTranslator/LunaTranslator/myutils/utils.py +++ b/LunaTranslator/LunaTranslator/myutils/utils.py @@ -11,6 +11,9 @@ import time from PyQt5.QtWidgets import ( QApplication, ) +from PyQt5.QtCore import QIODevice, QBuffer +from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent + from traceback import print_exc from myutils.config import ( globalconfig, @@ -235,75 +238,38 @@ def argsort(l): class wavmp3player: + def changepos(self, pos): + if pos != 0 and pos == self.player.duration(): + if self.next: + content, volume = self.next + self.next = None + self.realplay(content, volume) + def __init__(self): - self.i = 0 - self.lastfile = None - self.tasks = None - self.lock = threading.Lock() - self.lock.acquire() - threading.Thread(target=self.dotasks).start() + self.player = QMediaPlayer() + self.player.positionChanged.connect(self.changepos) + self.next = None - def mp3playfunction(self, path, volume, force): - try: - self.tasks = (path, volume, force) - self.lock.release() - except: - pass + def realplay(self, content, volume): + self.player.stop() + self.keepbuffer = [] + buffer = QBuffer() + buffer.open(QIODevice.ReadWrite) + self.player.setMedia(QMediaContent(), buffer) + self.player.setVolume(volume) + buffer.write(content) + self.keepbuffer = [buffer] + self.player.play() - def dotasks(self): - durationms = 0 - try: - while True: - self.lock.acquire() - task = self.tasks - self.tasks = None - if task is None: - continue - path, volume, force = task - - if os.path.exists(path) == False: - continue - durationms = self._playsoundWin(path, volume) - - if durationms and globalconfig["ttsnointerrupt"]: - while durationms > 0: - durationms -= 100 - time.sleep(0.1) - if self.tasks and self.tasks[-1]: - break - # time.sleep(durationms / 1000) - except: - print_exc() - - def _playsoundWin(self, sound, volume): - try: - - windows.mciSendString(("stop lunatranslator_mci_{}".format(self.i))) - windows.mciSendString(("close lunatranslator_mci_{}".format(self.i))) - self.i += 1 - if self.lastfile: - os.remove(self.lastfile) - self.lastfile = sound - windows.mciSendString( - 'open "{}" type mpegvideo alias lunatranslator_mci_{}'.format( - sound, self.i - ) - ) - durationms = int( - windows.mciSendString( - "status lunatranslator_mci_{} length".format(self.i) - ) - ) - windows.mciSendString( - "setaudio lunatranslator_mci_{} volume to {}".format( - self.i, volume * 10 - ) - ) - windows.mciSendString(("play lunatranslator_mci_{}".format(self.i))) - except: - durationms = 0 - - return durationms + def mp3playfunction(self, content, volume, force): + if ( + globalconfig["ttsnointerrupt"] + and self.player.position() < self.player.duration() + and not force + ): + self.next = [content, volume] + else: + self.realplay(content, volume) def selectdebugfile(path): diff --git a/LunaTranslator/LunaTranslator/tts/NeoSpeech.py b/LunaTranslator/LunaTranslator/tts/NeoSpeech.py index 48db9bc6..ef5d8d77 100644 --- a/LunaTranslator/LunaTranslator/tts/NeoSpeech.py +++ b/LunaTranslator/LunaTranslator/tts/NeoSpeech.py @@ -84,4 +84,8 @@ class TTS(TTSbase): windows.WriteFile(self.hPipe, bytes(buf)) fname = windows.ReadFile(self.hPipe, 1024).decode("utf-16-le") if os.path.exists(fname): - return fname + with open("./cache/tts/" + fname + ".wav", "rb") as ff: + data = ff.read() + os.remove("./cache/tts/" + fname + ".wav") + return data + return None diff --git a/LunaTranslator/LunaTranslator/tts/basettsclass.py b/LunaTranslator/LunaTranslator/tts/basettsclass.py index 7ec411d3..125880d1 100644 --- a/LunaTranslator/LunaTranslator/tts/basettsclass.py +++ b/LunaTranslator/LunaTranslator/tts/basettsclass.py @@ -3,6 +3,7 @@ import threading, os, functools from myutils.wrapper import threader from traceback import print_exc + class TTSbase: def init(self): pass @@ -60,11 +61,12 @@ class TTSbase: threading.Thread(target=_).start() def read(self, content, force=False): - def _(force, fname): - volume = self.publicconfig["volume"] - self.mp3playsignal.emit(fname, volume, force) + volume = self.publicconfig["volume"] - self.ttscallback(content, functools.partial(_, force)) + def _(force, volume, data): + self.mp3playsignal.emit(data, volume, force) + + self.ttscallback(content, functools.partial(_, force, volume)) @threader def ttscallback(self, content, callback): @@ -74,14 +76,13 @@ class TTSbase: return if len(self.voicelist) == 0: return - rate = self.publicconfig["rate"] voice = self.privateconfig["voice"] voice_index = self.voicelist.index(voice) try: - fname = self.speak(content, rate, voice, voice_index) - if fname: - callback(os.path.abspath(fname)) + data = self.speak(content, rate, voice, voice_index) + if data and len(data): + callback(data) except: print_exc() return diff --git a/LunaTranslator/LunaTranslator/tts/edgetts.py b/LunaTranslator/LunaTranslator/tts/edgetts.py index be28091f..a506a90a 100644 --- a/LunaTranslator/LunaTranslator/tts/edgetts.py +++ b/LunaTranslator/LunaTranslator/tts/edgetts.py @@ -193,8 +193,4 @@ def transferMsTTSData(rate, content, voice): else: break ws.close() - os.makedirs("./cache/tts/", exist_ok=True) - outputPath = "./cache/tts/" + str(time.time()) + ".mp3" - with open(outputPath, "wb") as audio_out: - audio_out.write(audio_stream) - return outputPath + return audio_stream diff --git a/LunaTranslator/LunaTranslator/tts/gtts.py b/LunaTranslator/LunaTranslator/tts/gtts.py index e9ca465f..55ca0153 100644 --- a/LunaTranslator/LunaTranslator/tts/gtts.py +++ b/LunaTranslator/LunaTranslator/tts/gtts.py @@ -325,6 +325,7 @@ import re _ALL_PUNC_OR_SPACE = re.compile("^[{}]*$".format(re.escape(punc + ws))) + def _minimize(the_string, delim, max_size): if the_string.startswith(delim): the_string = the_string[len(delim) :] @@ -543,11 +544,11 @@ class gTTS: "'fp' is not a file-like object or it does not take bytes: %s" % str(e) ) - def save(self, savefile): - with open(str(savefile), "wb") as f: - self.write_to_fp(f) - f.flush() - log.debug("Saved to %s", savefile) + def save(self): + bs = b"" + for idx, decoded in enumerate(self.stream()): + bs += decoded + return bs class gTTSError(Exception): @@ -605,8 +606,4 @@ class TTS(TTSbase): def speak(self, content, rate, voice, voiceidx): tts = gTTS(content, lang=getlangsrc()) - fname = str(time.time()) - os.makedirs("./cache/tts/", exist_ok=True) - - tts.save("./cache/tts/" + fname + ".mp3") - return "./cache/tts/" + fname + ".mp3" + return tts.save() diff --git a/LunaTranslator/LunaTranslator/tts/huoshantts.py b/LunaTranslator/LunaTranslator/tts/huoshantts.py index f2893705..d675b696 100644 --- a/LunaTranslator/LunaTranslator/tts/huoshantts.py +++ b/LunaTranslator/LunaTranslator/tts/huoshantts.py @@ -45,10 +45,6 @@ class TTS(TTSbase): json=json_data, proxies={"http": None, "https": None}, ) - fname = str(time.time()) b64 = base64.b64decode(response.json()["audio"]["data"]) - os.makedirs("./cache/tts/", exist_ok=True) - with open("./cache/tts/" + fname + ".mp3", "wb") as ff: - ff.write(b64) - return "./cache/tts/" + fname + ".mp3" + return b64 diff --git a/LunaTranslator/LunaTranslator/tts/vitsSimpleAPI.py b/LunaTranslator/LunaTranslator/tts/vitsSimpleAPI.py index 9817a526..4550b07e 100644 --- a/LunaTranslator/LunaTranslator/tts/vitsSimpleAPI.py +++ b/LunaTranslator/LunaTranslator/tts/vitsSimpleAPI.py @@ -30,9 +30,5 @@ class TTS(TTSbase): response = requests.get( f"http://127.0.0.1:{self.config['Port']}/voice/{model}?text={encoded_content}&id={idx}&lang=auto&prompt_lang=auto&format=wav&preset={self.config['preset']}" ).content - fname = str(time.time()) - os.makedirs("./cache/tts/", exist_ok=True) - with open("./cache/tts/" + fname + ".wav", "wb") as ff: - ff.write(response) - return "./cache/tts/" + fname + ".wav" + return response diff --git a/LunaTranslator/LunaTranslator/tts/voiceroid2.py b/LunaTranslator/LunaTranslator/tts/voiceroid2.py index 6e9fbdf3..232210dd 100644 --- a/LunaTranslator/LunaTranslator/tts/voiceroid2.py +++ b/LunaTranslator/LunaTranslator/tts/voiceroid2.py @@ -2,19 +2,18 @@ import time import os import windows from tts.basettsclass import TTSbase - +from ctypes import cast, POINTER, c_char, c_int32 from myutils.subproc import subproc_w, autoproc +import threading class TTS(TTSbase): def init(self): - self.path = "" - self.voice = "" - self.rate = "" + self.status = None self.voicelist = self.getvoicelist() - self.checkpath() + threading.Thread(target=self.checkpath).start() def getvoicelist(self): voicelist = [] @@ -26,7 +25,7 @@ class TTS(TTSbase): if "_" in _: _l = _.split("_") if len(_l) >= 2: - if _l[-1] == "44": + if _l[-1] == "44" or _l[-1] == "22": voicelist.append(_) return voicelist @@ -63,25 +62,19 @@ class TTS(TTSbase): if os.path.exists(self.config["path"]) == False: return False if ( - self.config["path"] != self.path - or self.privateconfig["voice"] != self.voice - or self.publicconfig["rate"] != self.rate - ): - self.path = self.config["path"] - self.rate = self.publicconfig["rate"] - self.voice = self.privateconfig["voice"] - fname = str(time.time()) - os.makedirs("./cache/tts/", exist_ok=True) - savepath = os.path.join(os.getcwd(), "cache/tts", fname + ".wav") - dllpath = os.path.join(self.path, "aitalked.dll") + 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") - self.savepath = savepath t = time.time() t = str(t) pipename = "\\\\.\\Pipe\\voiceroid2_" + t waitsignal = "voiceroid2waitload_" + t + mapname = "voiceroid2filemap" + t def linear_map(x): if x >= 0: @@ -90,22 +83,29 @@ class TTS(TTSbase): 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 "{}" "{}" {} 44100 {} "{}" {} {}'.format( + '"{}" voiceroid2 "{}" "{}" {} {} {} {} {} {}'.format( exepath, self.config["path"], dllpath, self.privateconfig["voice"], - linear_map(self.publicconfig["rate"]), - savepath, + _1, + _2, pipename, waitsignal, + mapname, ), name="voicevoid2", ) ) - windows.WaitForSingleObject( windows.AutoHandle(windows.CreateEvent(False, False, waitsignal)), windows.INFINITE, @@ -122,20 +122,35 @@ class TTS(TTSbase): 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, + 1024 * 1024 * 10, + ) + + self.status = ( + self.config["path"], + self.privateconfig["voice"], + self.publicconfig["rate"], + ) def speak(self, content, rate, voice, voice_idx): self.checkpath() - # def _(): - try: - content.encode("shift-jis") + code1 = content.encode("shift-jis") except: return - code1 = content.encode("shift-jis") - # print(code1) windows.WriteFile(self.hPipe, code1) - fname = windows.ReadFile(self.hPipe, 1024).decode("utf8") - if os.path.exists(fname): - return fname + size = c_int32.from_buffer_copy(windows.ReadFile(self.hPipe, 4)).value + if size == 0: + return None + return cast(self.mem, POINTER(c_char))[:size] diff --git a/LunaTranslator/LunaTranslator/tts/voiceroidplus.py b/LunaTranslator/LunaTranslator/tts/voiceroidplus.py deleted file mode 100644 index fb6f3b37..00000000 --- a/LunaTranslator/LunaTranslator/tts/voiceroidplus.py +++ /dev/null @@ -1,130 +0,0 @@ -import time -import os -import windows -from tts.basettsclass import TTSbase - -from myutils.subproc import subproc_w, autoproc - - -class TTS(TTSbase): - - def init(self): - self.path = "" - self.voice = "" - self.rate = "" - - self.voicelist = self.getvoicelist() - def voiceshowmap(self, voice): - name = voice.split("_")[0] - jpname = { - "yukari": "結月ゆかり", - "akari": "紲星あかり", - "kiritan": "東北きりたん", - "itako": "東北イタコ", - "zunko": "東北ずん子", - "yuzuru": "伊織弓鶴", - "tsuina": "ついなちゃん", - "akane": "琴葉茜", - "aoi": "琴葉葵", - "kou": "水奈瀬コウ", - "sora": "桜乃そら", - "tamiyasu": "民安ともえ", - "ai": "月読アイ", - "shouta": "月読ショウタ", - "seika": "京町セイカ", - "una": "音街ウナ", - "yoshidakun": "鷹の爪吉田", - "galaco": "ギャラ子", - } - vv = jpname[name] - if "west" in voice: - vv += "(関西弁)" - return vv - - def getvoicelist(self): - voicelist = [] - if os.path.exists(self.config["path"]) == False: - return [] - l = os.listdir(os.path.join(self.config["path"], "Voice")) - - for _ in l: - if "_" in _: - _l = _.split("_") - if len(_l) >= 2: - if _l[-1] == "22": - voicelist.append(_) - return voicelist - - def checkpath(self): - if self.config["path"] == "": - return False - if os.path.exists(self.config["path"]) == False: - return False - if ( - self.config["path"] != self.path - or self.privateconfig["voice"] != self.voice - or self.publicconfig["rate"] != self.rate - ): - self.path = self.config["path"] - self.rate = self.publicconfig["rate"] - self.voice = self.privateconfig["voice"] - fname = str(time.time()) - os.makedirs("./cache/tts/", exist_ok=True) - savepath = os.path.join(os.getcwd(), "cache/tts", fname + ".wav") - dllpath = os.path.join(self.path, "aitalked.dll") - - exepath = os.path.join(os.getcwd(), "files/plugins/shareddllproxy32.exe") - self.savepath = savepath - - t = time.time() - t = str(t) - pipename = "\\\\.\\Pipe\\voiceroid2_" + t - waitsignal = "voiceroid2waitload_" + t - # 速率不可调 - self.engine = autoproc( - subproc_w( - '"{}" voiceroid2 "{}" "{}" {} 22050 0 "{}" {} {}'.format( - exepath, - self.config["path"], - dllpath, - self.privateconfig["voice"], - savepath, - pipename, - waitsignal, - ), - 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, - windows.GENERIC_READ | windows.GENERIC_WRITE, - 0, - None, - windows.OPEN_EXISTING, - windows.FILE_ATTRIBUTE_NORMAL, - None, - ) - ) - - def speak(self, content, rate, voice, voice_idx): - self.checkpath() - - - try: - content.encode("shift-jis") - except: - return - code1 = content.encode("shift-jis") - # print(code1) - windows.WriteFile(self.hPipe, code1) - - fname = windows.ReadFile(self.hPipe, 1024).decode("utf8") - if os.path.exists(fname): - return fname diff --git a/LunaTranslator/LunaTranslator/tts/voicevox.py b/LunaTranslator/LunaTranslator/tts/voicevox.py index 202a6424..74a0f17c 100644 --- a/LunaTranslator/LunaTranslator/tts/voicevox.py +++ b/LunaTranslator/LunaTranslator/tts/voicevox.py @@ -100,7 +100,4 @@ class TTS(TTSbase): headers=headers, data=json.dumps(response.json()), ) - os.makedirs("./cache/tts/", exist_ok=True) - with open("./cache/tts/" + fname + ".wav", "wb") as ff: - ff.write(response.content) - return "./cache/tts/" + fname + ".wav" + return response.content \ No newline at end of file diff --git a/LunaTranslator/LunaTranslator/tts/windowstts.py b/LunaTranslator/LunaTranslator/tts/windowstts.py index 9fe5bdf3..75059c86 100644 --- a/LunaTranslator/LunaTranslator/tts/windowstts.py +++ b/LunaTranslator/LunaTranslator/tts/windowstts.py @@ -40,4 +40,7 @@ class TTS(TTSbase): winsharedutils.SAPI_Speak( content, version, voice_idx, rate, 100, "./cache/tts/" + fname + ".wav" ) - return "./cache/tts/" + fname + ".wav" + with open("./cache/tts/" + fname + ".wav", "rb") as ff: + data = ff.read() + os.remove("./cache/tts/" + fname + ".wav") + return data diff --git a/LunaTranslator/LunaTranslator/tts/youdaotts.py b/LunaTranslator/LunaTranslator/tts/youdaotts.py index bf5039b1..02fab944 100644 --- a/LunaTranslator/LunaTranslator/tts/youdaotts.py +++ b/LunaTranslator/LunaTranslator/tts/youdaotts.py @@ -38,9 +38,4 @@ class TTS(TTSbase): headers=headers, proxies={"http": None, "https": None}, ).content - fname = str(time.time()) - os.makedirs("./cache/tts/", exist_ok=True) - with open("./cache/tts/" + fname + ".mp3", "wb") as ff: - ff.write(response) - - return "./cache/tts/" + fname + ".mp3" + return response diff --git a/LunaTranslator/LunaTranslator/windows.py b/LunaTranslator/LunaTranslator/windows.py index ef7ca49d..4dec600a 100644 --- a/LunaTranslator/LunaTranslator/windows.py +++ b/LunaTranslator/LunaTranslator/windows.py @@ -970,3 +970,25 @@ _LoadLibraryW.argtypes = (LPCWSTR,) def loadlibrary(path): _LoadLibraryW(path) + + +SECTION_MAP_WRITE = 0x0002 +SECTION_MAP_READ = 0x0004 +FILE_MAP_WRITE = SECTION_MAP_WRITE +FILE_MAP_READ = SECTION_MAP_READ +_OpenFileMapping = _kernel32.OpenFileMappingW +_OpenFileMapping.argtypes = DWORD, BOOL, LPCWSTR +_OpenFileMapping.restype = HANDLE + + +def OpenFileMapping(acc, inher, name): + return _OpenFileMapping(acc, inher, name) + + +_MapViewOfFile = _kernel32.MapViewOfFile +_MapViewOfFile.argtypes = HANDLE, DWORD, DWORD, DWORD, c_size_t +_MapViewOfFile.restype = c_void_p + + +def MapViewOfFile(hfmap, acc, high, low, size): + return _MapViewOfFile(hfmap, acc, high, low, size) diff --git a/LunaTranslator/files/defaultconfig/config.json b/LunaTranslator/files/defaultconfig/config.json index fc2c1079..2fe8d67b 100644 --- a/LunaTranslator/files/defaultconfig/config.json +++ b/LunaTranslator/files/defaultconfig/config.json @@ -656,22 +656,7 @@ "voiceroid2": { "use": false, "voice": "", - "name": "VoiceRoid2", - "args": { - "path": "" - }, - "argstype": { - "path": { - "type": "file", - "name": "路径", - "dir": true - } - } - }, - "voiceroidplus": { - "use": false, - "voice": "", - "name": "VoiceRoid+", + "name": "VoiceRoid2/VoiceRoid+", "args": { "path": "" }, diff --git a/LunaTranslator/retrieval.py b/LunaTranslator/retrieval.py index 231b3155..0d6cbbaf 100644 --- a/LunaTranslator/retrieval.py +++ b/LunaTranslator/retrieval.py @@ -182,6 +182,21 @@ copycheck( os.path.join(py37Path, "Lib/site-packages/PyQt5/Qt5/bin/Qt5Gui.dll"), os.path.join(runtime, "PyQt5/Qt5/bin"), ) + +### +copycheck( + os.path.join(py37Path, "Lib/site-packages/PyQt5/Qt5/bin/Qt5Multimedia.dll"), + os.path.join(runtime, "PyQt5/Qt5/bin"), +) +copycheck( + os.path.join(py37Path, "Lib/site-packages/PyQt5/Qt5/bin/Qt5Network.dll"), + os.path.join(runtime, "PyQt5/Qt5/bin"), +) +copycheck( + os.path.join(py37Path, "Lib/site-packages/PyQt5/QtNetwork.pyd"), + os.path.join(runtime, "PyQt5"), +) +### copycheck( os.path.join(py37Path, "Lib/site-packages/PyQt5/Qt5/bin/Qt5Widgets.dll"), os.path.join(runtime, "PyQt5/Qt5/bin"), @@ -191,6 +206,10 @@ copycheck( os.path.join(py37Path, "Lib/site-packages/PyQt5/Qt5/plugins/imageformats"), os.path.join(runtime, "PyQt5/Qt5/plugins"), ) +copycheck( + os.path.join(py37Path, "Lib/site-packages/PyQt5/Qt5/plugins/mediaservice"), + os.path.join(runtime, "PyQt5/Qt5/plugins"), +) copycheck( os.path.join( py37Path, "Lib/site-packages/PyQt5/Qt5/plugins/platforms/qoffscreen.dll" diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 843cbc0d..e8268d9f 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -29,7 +29,7 @@ include(generate_product_version) set(VERSION_MAJOR 2) set(VERSION_MINOR 51) -set(VERSION_PATCH 3) +set(VERSION_PATCH 4) add_library(pch pch.cpp) target_precompile_headers(pch PUBLIC pch.h) diff --git a/plugins/shareddllproxy/voiceroid2/voice2.cpp b/plugins/shareddllproxy/voiceroid2/voice2.cpp index 6b932085..92bce904 100644 --- a/plugins/shareddllproxy/voiceroid2/voice2.cpp +++ b/plugins/shareddllproxy/voiceroid2/voice2.cpp @@ -7,42 +7,33 @@ using ebyroid::Ebyroid; int voiceroid2wmain(int argc, wchar_t *wargv[]) { - UINT codepage = GetACP(); char **argv = new char *[argc]; for (int i = 0; i < argc; i++) { - int length = WideCharToMultiByte(codepage, 0, wargv[i], -1, NULL, 0, NULL, NULL); + int length = WideCharToMultiByte(CP_ACP, 0, wargv[i], -1, NULL, 0, NULL, NULL); argv[i] = new char[length]; - WideCharToMultiByte(codepage, 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[7], PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 65535, 65535, NMPWAIT_WAIT_FOREVER, 0); + 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); Ebyroid *ebyroid; - printf("argc %d \n", argc); - for (int i = 0; i < argc; i++) - { - printf("%d %s\n", i, argv[i]); - } ebyroid = Ebyroid::Create((const char *)argv[1], //"C:\\dataH\\Yukari2", (const char *)argv[2], - (const char *)argv[3], //"yukari_emo_44", - 2, + (const char *)argv[3], //"yukari_emo_44", + 2, atof((const char *)argv[5])); // 1); //0.1-2,0.5-4 - - SetEvent(CreateEventA(&allAccess, FALSE, FALSE, argv[8])); - if (ConnectNamedPipe(hPipe, NULL) != NULL) - { - DWORD len = 0; - } + + 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); + memset(mapview, 0, 1024 * 1024 * 10); + SetEvent(CreateEventA(&allAccess, FALSE, FALSE, argv[7])); + ConnectNamedPipe(hPipe, NULL); int freq1 = atoi(argv[4]); - printf("pipe connected"); - int II = 0; while (true) { - II += 1; unsigned char *out; size_t output_size; int16_t *out2; @@ -52,34 +43,43 @@ int voiceroid2wmain(int argc, wchar_t *wargv[]) if (!ReadFile(hPipe, input_j, 4096, &_, NULL)) break; - printf("%s\n", input_j); // 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); - printf("%s\n", out); result = ebyroid->Speech(out, &out2, &output_size); - char newname[1024] = {0}; - sprintf(newname, "%s%d.wav", argv[6], II); - FILE *F = fopen(newname, "wb"); - int fsize = output_size + 44; - fseek(F, 0, SEEK_SET); - fwrite("RIFF", 1, 4, F); - fwrite(&fsize, 4, 1, F); - fwrite("WAVEfmt ", 1, 8, F); - fwrite("\x10\x00\x00\x00\x01\x00\x01\x00", 1, 8, F); - int freq = freq1; - fwrite(&freq, 4, 1, F); - freq = freq * 2; - fwrite(&freq, 4, 1, F); - fwrite("\x02\x00\x10\x00", 1, 4, F); - fwrite("data", 1, 4, F); - int sz = fsize - 44; - fwrite(&sz, 4, 1, F); - printf("%d \n", ftell(F)); - fwrite((char *)out2, 1, output_size, F); - fclose(F); - WriteFile(hPipe, newname, strlen(newname), &_, NULL); + if (fsize > 1024 * 1024 * 10) + { + fsize = 0; + } + else + { + + int ptr = 0; + memcpy(mapview, "RIFF", 4); + ptr += 4; + memcpy(mapview + ptr, &fsize, 4); + ptr += 4; + memcpy(mapview + ptr, "WAVEfmt ", 8); + ptr += 8; + memcpy(mapview + ptr, "\x10\x00\x00\x00\x01\x00\x01\x00", 8); + ptr += 8; + int freq = freq1; + memcpy(mapview + ptr, &freq, 4); + ptr += 4; + freq = freq * 2; + memcpy(mapview + ptr, &freq, 4); + ptr += 4; + memcpy(mapview + ptr, "\x02\x00\x10\x00", 4); + ptr += 4; + memcpy(mapview + ptr, "data", 4); + ptr += 4; + memcpy(mapview + ptr, &output_size, 4); + ptr += 4; + memcpy(mapview + ptr, out2, output_size); + } + WriteFile(hPipe, &fsize, 4, &_, NULL); + free(out); free(out2); }