├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug-report.yml │ └── config.yml └── workflows │ └── release.yml ├── .gitignore ├── LICENSE.txt ├── Logo ├── openutau.svg └── openutau_logotype.svg ├── Misc ├── GIFs │ ├── editor.gif │ ├── editor2.gif │ ├── playback.gif │ ├── undo.gif │ └── vibrato.gif └── sync_strings.py ├── OpenUtau.Core ├── Analysis │ └── Crepe │ │ ├── Crepe.cs │ │ ├── LICENSE.txt │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ └── tiny.onnx ├── Api │ ├── G2pDictionary.cs │ ├── G2pDictionaryData.cs │ ├── G2pFallbacks.cs │ ├── G2pPack.cs │ ├── G2pRemapper.cs │ ├── IG2p.cs │ ├── Phonemizer.cs │ ├── PhonemizerFactory.cs │ ├── PhonemizerRunner.cs │ └── README.md ├── Audio │ ├── AudioDevice.cs │ ├── AudioEngine.cs │ ├── AudioFrame.cs │ ├── AudioStreamInfo.cs │ ├── Bindings │ │ ├── PaBinding.Delegates.cs │ │ ├── PaBinding.Enums.cs │ │ ├── PaBinding.Structs.cs │ │ └── PaBinding.cs │ ├── DummyAudioOutput.cs │ ├── IAudioOutput.cs │ ├── NAudioOutput.cs │ └── PortAudioOutput.cs ├── BaseChinesePhonemizer.cs ├── Classic │ ├── ClassicRenderer.cs │ ├── ClassicSinger.cs │ ├── ClassicSingerLoader.cs │ ├── ExeResampler.cs │ ├── ExeWavtool.cs │ ├── Frq.cs │ ├── IPlugin.cs │ ├── IResampler.cs │ ├── IWavtool.cs │ ├── Ini.cs │ ├── OtoWatcher.cs │ ├── Plugin.cs │ ├── PluginLoader.cs │ ├── PluginRunner.cs │ ├── Presamp.cs │ ├── ResamplerItem.cs │ ├── ResamplerManifest.cs │ ├── SharpWavtool.cs │ ├── ToolsManager.cs │ ├── Ust.cs │ ├── UstNote.cs │ ├── VoiceBank.cs │ ├── VoicebankConfig.cs │ ├── VoicebankErrorChecker.cs │ ├── VoicebankFiles.cs │ ├── VoicebankInstaller.cs │ ├── VoicebankLoader.cs │ ├── WorldlineRenderer.cs │ └── WorldlineResampler.cs ├── Commands │ ├── ExpCommands.cs │ ├── NoteCommands.cs │ ├── Notifications.cs │ ├── PartCommands.cs │ ├── ProjectCommands.cs │ ├── TrackCommands.cs │ └── UCommand.cs ├── DefaultPhonemizer.cs ├── DiffSinger │ ├── DiffSingerConfig.cs │ ├── DiffSingerDependencyInstaller.cs │ ├── DiffSingerMandarinPhonemizer.cs │ ├── DiffSingerRenderer.cs │ ├── DiffSingerRhythmizerPhonemizer.cs │ ├── DiffSingerScript.cs │ ├── DiffSingerSinger.cs │ ├── DiffSingerUtils.cs │ └── DiffSingerVocoder.cs ├── DocManager.cs ├── Editing │ ├── BatchEdit.cs │ ├── LyricBatchEdits.cs │ ├── NoteBatchEdits.cs │ └── README.md ├── Enunu │ ├── EnunuClient.cs │ ├── EnunuConfig.cs │ ├── EnunuEnglishPhonemizer.cs │ ├── EnunuPhonemizer.cs │ ├── EnunuRenderer.cs │ ├── EnunuSinger.cs │ └── EnunuUtils.cs ├── Format │ ├── Formats.cs │ ├── Midi.cs │ ├── MidiWriter.cs │ ├── OpusOggWaveReader.cs │ ├── USTx.cs │ ├── VSQx.cs │ └── Wave.cs ├── G2p │ ├── ArpabetG2p.cs │ ├── Data │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── g2p-arpabet.zip │ │ ├── g2p-es.zip │ │ ├── g2p-fr.zip │ │ ├── g2p-it.zip │ │ ├── g2p-pt.zip │ │ └── g2p-ru.zip │ ├── FrenchG2p.cs │ ├── ItalianG2p.cs │ ├── PortugueseG2p.cs │ ├── RussianG2p.cs │ └── SpanishG2p.cs ├── OpenUtau.Core.csproj ├── PlaybackManager.cs ├── Render │ ├── IRenderer.cs │ ├── RenderCache.cs │ ├── RenderEngine.cs │ ├── RenderPhrase.cs │ ├── Renderers.cs │ └── Worldline.cs ├── SignalChain │ ├── ExportAdapter.cs │ ├── Fader.cs │ ├── ISignalSource.cs │ ├── MasterAdapter.cs │ ├── WaveMix.cs │ └── WaveSource.cs ├── SingerManager.cs ├── ThirdParty │ └── Deque.cs ├── Ustx │ ├── UCurve.cs │ ├── UExpression.cs │ ├── UNote.cs │ ├── UPart.cs │ ├── UPhoneme.cs │ ├── UProject.cs │ ├── USinger.cs │ └── UTrack.cs ├── Util │ ├── Base64.cs │ ├── IniFileClass.cs │ ├── LibraryLoader.cs │ ├── LocalizedSort.cs │ ├── LyricsHelper.cs │ ├── MusicMath.cs │ ├── NotePresets.cs │ ├── OS.cs │ ├── Onnx.cs │ ├── PathManager.cs │ ├── Preferences.cs │ ├── ProcessRunner.cs │ ├── SingletonBase.cs │ ├── SplitLyrics.cs │ ├── TimeAxis.cs │ ├── Yaml.cs │ └── Zip.cs ├── VocalShaper │ ├── Complex.cs │ ├── VSMath.cs │ ├── VSVocoder.cs │ └── World.cs └── Vogen │ ├── Data │ ├── VogenRes.Designer.cs │ ├── VogenRes.resx │ ├── f0.man.onnx │ ├── f0.yue.onnx │ ├── g2p.man.onnx │ ├── g2p.yue.onnx │ ├── po.man.onnx │ ├── po.yue.onnx │ └── yue.csv │ ├── TrieNode.cs │ ├── VogenBasePhonemizer.cs │ ├── VogenMandarinPhonemizer.cs │ ├── VogenRenderer.cs │ ├── VogenSinger.cs │ ├── VogenSingerInstaller.cs │ ├── VogenSingerLoader.cs │ └── VogenYuePhonemizer.cs ├── OpenUtau.Plugin.Builtin ├── ArpasingPhonemizer.cs ├── BrazilianPortugueseCVCPhonemizer.cs ├── ChineseCVVCPhonemizer.cs ├── ChineseCVVPhonemizer.cs ├── Data │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── arpasing.template.yaml │ ├── envccv.template.yaml │ └── xsampa.template.yaml ├── ENDeltaPhonemizer.cs ├── ENtoJAPhonemizer.cs ├── EStoJAPhonemizer.cs ├── EnglishVCCVPhonemizer.cs ├── EnunuOnnx │ ├── EnunuConfig.cs │ ├── EnunuOnnxConfig.cs │ ├── EnunuOnnxEnglishPhonemizer.cs │ ├── EnunuOnnxPhonemizer.cs │ ├── HTS.cs │ ├── HTSLabelFile.cs │ ├── Merlin.cs │ ├── Python.cs │ └── Scaler.cs ├── FrenchCMUSphinxPhonemizer.cs ├── FrenchCVVCPhonemizer.cs ├── FrenchVCCVPhonemizer.cs ├── ItalianCVVCPhonemizer.cs ├── ItalianSyllableBasedPhonemizer.cs ├── JapaneseCVVCPhonemizer.cs ├── JapanesePresampPhonemizer.cs ├── JapaneseVCVPhonemizer.cs ├── KoreanCBNNPhonemizer.cs ├── KoreanCVCCVPhonemizer.cs ├── KoreanCVCPhonemizer.cs ├── KoreanCVVCStandardPronunciationPhonemizer.cs ├── KoreanVCVPhonemizer.cs ├── LatinDiphonePhonemizer.cs ├── OpenUtau.Plugin.Builtin.csproj ├── PolishCVCPhonemizer.cs ├── PresampSamplePhonemizer.cs ├── RussianCVCPhonemizer.cs ├── RussianVCCVPhonemizer.cs ├── SpanishMakkusanPhonemizer.cs ├── SpanishSyllableBasedPhonemizer.cs ├── SpanishVCCVPhonemizer.cs ├── SyllableBasedPhonemizer.cs ├── VietnameseCVVCPhonemizer.cs ├── VietnameseVCVPhonemizer.cs └── VietnameseVINAPhonemizer.cs ├── OpenUtau.Test ├── App │ └── AppTest.cs ├── Classic │ ├── PluginRunnerTest.cs │ ├── UstTest.cs │ ├── VoicebankConfigTest.cs │ └── VoicebankLoaderTest.cs ├── Core │ ├── G2p │ │ └── G2pTest.cs │ ├── SignalChain │ │ └── WaveSourceTest.cs │ ├── USTx │ │ └── UstxYamlTest.cs │ └── Util │ │ ├── MusicMathTest.cs │ │ ├── SplitLyricsTest.cs │ │ └── TimeAxisTest.cs ├── Files │ ├── en_arpa │ │ ├── High │ │ │ └── oto.ini │ │ ├── Low │ │ │ └── oto.ini │ │ ├── Main │ │ │ └── oto.ini │ │ ├── Whisper │ │ │ └── oto.ini │ │ ├── character.txt │ │ └── character.yaml │ ├── en_delta0 │ │ ├── character.txt │ │ ├── oto.ini │ │ └── presamp.ini │ ├── en_delta7 │ │ ├── character.txt │ │ ├── oto.ini │ │ └── presamp.ini │ ├── en_vccv │ │ ├── CC- │ │ │ └── oto.ini │ │ ├── CCV │ │ │ └── oto.ini │ │ ├── CV │ │ │ └── oto.ini │ │ ├── CVC_CV │ │ │ └── oto.ini │ │ ├── CV_CVC │ │ │ └── oto.ini │ │ ├── V │ │ │ └── oto.ini │ │ ├── VC │ │ │ └── oto.ini │ │ ├── VCC │ │ │ └── oto.ini │ │ ├── VV │ │ │ └── oto.ini │ │ ├── _CV │ │ │ └── oto.ini │ │ └── character.txt │ ├── ja_cvvc │ │ ├── A3 │ │ │ └── oto.ini │ │ ├── B4 │ │ │ └── oto.ini │ │ ├── C4 │ │ │ └── oto.ini │ │ ├── F4 │ │ │ └── oto.ini │ │ ├── character.txt │ │ ├── character.yaml │ │ ├── oto.ini │ │ ├── 弱 │ │ │ ├── oto.ini │ │ │ ├── 弱_A3 │ │ │ │ └── oto.ini │ │ │ ├── 弱_B4 │ │ │ │ └── oto.ini │ │ │ ├── 弱_C4 │ │ │ │ └── oto.ini │ │ │ └── 弱_E4 │ │ │ │ └── oto.ini │ │ └── 強 │ │ │ ├── oto.ini │ │ │ ├── 強_B3 │ │ │ └── oto.ini │ │ │ ├── 強_B4 │ │ │ └── oto.ini │ │ │ └── 強_F4 │ │ │ └── oto.ini │ ├── ja_presamp │ │ ├── - a │ │ │ └── oto.ini │ │ ├── C │ │ │ └── oto.ini │ │ ├── a - │ │ │ └── oto.ini │ │ ├── beach A3 │ │ │ └── oto.ini │ │ ├── beach A4 │ │ │ └── oto.ini │ │ ├── beach C5 │ │ │ └── oto.ini │ │ ├── beach D4 │ │ │ └── oto.ini │ │ ├── beach F4 │ │ │ └── oto.ini │ │ ├── beach vv A4 │ │ │ └── oto.ini │ │ ├── beach vv A4C5 │ │ │ └── oto.ini │ │ ├── boat D4 │ │ │ └── oto.ini │ │ ├── character.txt │ │ ├── character.yaml │ │ ├── nebura B3 │ │ │ └── oto.ini │ │ ├── nebura C5 │ │ │ └── oto.ini │ │ ├── nebura E3 │ │ │ └── oto.ini │ │ ├── nebura E4 │ │ │ └── oto.ini │ │ ├── nebura G#3 │ │ │ └── oto.ini │ │ ├── nebura G#4 │ │ │ └── oto.ini │ │ ├── oto.ini │ │ ├── presamp.ini │ │ ├── sand A3 │ │ │ └── oto.ini │ │ ├── sand D4 │ │ │ └── oto.ini │ │ ├── shell A3 │ │ │ └── oto.ini │ │ ├── shell A4 │ │ │ └── oto.ini │ │ ├── shell D4 │ │ │ └── oto.ini │ │ ├── shell F4 │ │ │ └── oto.ini │ │ ├── wave A3 │ │ │ └── oto.ini │ │ ├── wave D4 │ │ │ └── oto.ini │ │ └── wave F4 │ │ │ └── oto.ini │ ├── ja_vcv │ │ ├── C_A3 │ │ │ └── oto.ini │ │ ├── C_C5 │ │ │ └── oto.ini │ │ ├── C_D4 │ │ │ └── oto.ini │ │ ├── C_G4 │ │ │ └── oto.ini │ │ ├── N_A3 │ │ │ └── oto.ini │ │ ├── N_C5 │ │ │ └── oto.ini │ │ ├── N_D4 │ │ │ └── oto.ini │ │ ├── N_G4 │ │ │ └── oto.ini │ │ ├── W_A3 │ │ │ └── oto.ini │ │ ├── W_D4 │ │ │ └── oto.ini │ │ ├── W_G4 │ │ │ └── oto.ini │ │ ├── character.txt │ │ └── character.yaml │ └── sine.wav ├── OpenUtau.Test.csproj ├── Plugins │ ├── EnArpaTest.cs │ ├── EnDeltaTest.cs │ ├── EnToJaTest.cs │ ├── EnVCCVTest.cs │ ├── JaCvvcTest.cs │ ├── JaPresampTest.cs │ ├── JaVcvTest.cs │ ├── PhonemizerTest.cs │ └── PhonemizerTestBase.cs └── Usts │ └── _dummy.ust ├── OpenUtau.sln ├── OpenUtau ├── App.axaml ├── App.axaml.cs ├── Assets │ ├── OpenUtau.icns │ ├── logotype-w.png │ ├── logotype.png │ └── open-utau.ico ├── Colors │ ├── Brushes.axaml │ ├── DarkTheme.axaml │ └── LightTheme.axaml ├── Controls │ ├── ExpSelector.axaml │ ├── ExpSelector.axaml.cs │ ├── ExpressionCanvas.cs │ ├── LyricBox.axaml │ ├── LyricBox.axaml.cs │ ├── NotesCanvas.cs │ ├── PartControl.cs │ ├── PartsCanvas.cs │ ├── PhonemeCanvas.cs │ ├── TextLayoutCache.cs │ ├── TickBackground.cs │ ├── TrackAdder.axaml │ ├── TrackAdder.axaml.cs │ ├── TrackBackground.cs │ ├── TrackHeader.axaml │ ├── TrackHeader.axaml.cs │ ├── TrackHeaderCanvas.cs │ ├── ViewScaler.axaml │ ├── ViewScaler.axaml.cs │ └── WaveformImage.cs ├── FodyWeavers.xml ├── FodyWeavers.xsd ├── Integrations │ └── VLabelerClient.cs ├── OpenUtau.csproj ├── Program.cs ├── Resources │ ├── Resources.Designer.cs │ ├── Resources.resx │ └── Unzipper.exe ├── Strings │ ├── Strings.axaml │ ├── Strings.es-ES.axaml │ ├── Strings.es-MX.axaml │ ├── Strings.fi-FI.axaml │ ├── Strings.fr-FR.axaml │ ├── Strings.id-ID.axaml │ ├── Strings.it-IT.axaml │ ├── Strings.ja-JP.axaml │ ├── Strings.ko-KR.axaml │ ├── Strings.nl-NL.axaml │ ├── Strings.pl-PL.axaml │ ├── Strings.pt-BR.axaml │ ├── Strings.ru-RU.axaml │ ├── Strings.th-TH.axaml │ ├── Strings.vi-VN.axaml │ ├── Strings.zh-CN.axaml │ └── Strings.zh-TW.axaml ├── Styles │ └── Styles.axaml ├── ThemeManager.cs ├── ViewConstants.cs ├── ViewLocator.cs ├── ViewModels │ ├── Converters.cs │ ├── DebugViewModel.cs │ ├── EditSubbanksViewModel.cs │ ├── ExpSelectorViewModel.cs │ ├── ExpressionsViewModel.cs │ ├── LyricBoxViewModel.cs │ ├── LyricsViewModel.cs │ ├── MainWindowViewModel.cs │ ├── MenuItemViewModel.cs │ ├── NoteDefaultsViewModel.cs │ ├── NoteSelectionViewModel.cs │ ├── NotesViewModel.cs │ ├── NotesViewModelHitTest.cs │ ├── PhoneticAssistantViewModel.cs │ ├── PianoRollViewModel.cs │ ├── PlaybackViewModel.cs │ ├── PreferencesViewModel.cs │ ├── SingerSetupViewModel.cs │ ├── SingersViewModel.cs │ ├── TrackHeaderViewModel.cs │ ├── TrackSettingsViewModel.cs │ ├── TracksViewModel.cs │ ├── UpdaterViewModel.cs │ └── ViewModelBase.cs ├── Views │ ├── DebugWindow.axaml │ ├── DebugWindow.axaml.cs │ ├── EditSubbanksDialog.axaml │ ├── EditSubbanksDialog.axaml.cs │ ├── ExpressionsDialog.axaml │ ├── ExpressionsDialog.axaml.cs │ ├── LyricsDialog.axaml │ ├── LyricsDialog.axaml.cs │ ├── MainWindow.axaml │ ├── MainWindow.axaml.cs │ ├── MessageBox.axaml │ ├── MessageBox.axaml.cs │ ├── NoteDefaultsDialog.axaml │ ├── NoteDefaultsDialog.axaml.cs │ ├── NoteEditStates.cs │ ├── PartEditStates.cs │ ├── PhoneticAssistant.axaml │ ├── PhoneticAssistant.axaml.cs │ ├── PianoRollWindow.axaml │ ├── PianoRollWindow.axaml.cs │ ├── PreferencesDialog.axaml │ ├── PreferencesDialog.axaml.cs │ ├── SingerSetupDialog.axaml │ ├── SingerSetupDialog.axaml.cs │ ├── SingersDialog.axaml │ ├── SingersDialog.axaml.cs │ ├── TimeSignatureDialog.axaml │ ├── TimeSignatureDialog.axaml.cs │ ├── TrackSettingsDialog.axaml │ ├── TrackSettingsDialog.axaml.cs │ ├── TypeInDialog.axaml │ ├── TypeInDialog.axaml.cs │ ├── UpdaterDialog.axaml │ └── UpdaterDialog.axaml.cs └── nuget.config ├── README.md ├── README_zh.md ├── Unzipper ├── Program.cs ├── Unzip.cs ├── Unzipper.csproj ├── UnzipperForm.Designer.cs ├── UnzipperForm.cs └── UnzipperForm.resx ├── appveyor.py ├── appveyor.yml ├── py ├── .gitignore ├── README.md └── g2p │ ├── dataset.py │ ├── en_us │ ├── cfg.yaml │ └── phones.txt │ ├── model.py │ ├── requirements.txt │ ├── train.py │ └── trainer.py └── runtimes ├── linux-arm64 └── native │ └── libworldline.so ├── linux-x64 └── native │ ├── libportaudio.so │ └── libworldline.so ├── osx └── native │ ├── libportaudio.dylib │ └── libworldline.dylib ├── win-x64 └── native │ ├── portaudio.dll │ └── worldline.dll └── win-x86 └── native ├── portaudio.dll └── worldline.dll /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | *.cs text diff=csharp eol=crlf 5 | *.cshtml text diff=html 6 | *.csx text diff=csharp 7 | *.sln text eol=crlf 8 | *.csproj text eol=crlf 9 | *.xaml text eol=crlf 10 | *.axaml text eol=crlf 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | name: 🐛 Bug Report 2 | description: Create a report to help us reproduce and fix the bug 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: | 7 | GitHub issues are for reporting bugs and crashes. Vague help requests are not efficiently handled here. 8 | For help request please read [Getting-Started](https://github.com/stakira/OpenUtau/wiki/Getting-Started) and [FAQ](https://github.com/stakira/OpenUtau/wiki/FAQ) and other wiki pages first. 9 | If still not resolved, help requests are better handled in the Discord server or QQ group. 10 | - type: checkboxes 11 | attributes: 12 | label: Acknowledgement 13 | options: 14 | - label: I have read Getting-Started and FAQ 15 | required: true 16 | - type: textarea 17 | attributes: 18 | label: 🐛 Describe the bug 19 | description: > 20 | Please provide a clear and concise description of what the bug is. 21 | validations: 22 | required: true 23 | - type: textarea 24 | attributes: 25 | label: Explains how to reproduce the bug 26 | description: | 27 | Explains how to make the bug happen again. 28 | Explains what's the voicebank used, where to get it. 29 | Share the ust or ustx file if you could. Or you could isolate the issue in a small file. 30 | placeholder: | 31 | Example: 32 | 1. Go to '...' 33 | 2. Click on '...' 34 | 3. See error '...' 35 | 4. Voicebank is '...' 36 | 5. Attach ustx 37 | validations: 38 | required: true 39 | - type: input 40 | attributes: 41 | label: OS & Version 42 | description: > 43 | Example: Windows 7, Windows 10, macOS 10.14, macOS 11.16, Ubuntu 20.04 44 | validations: 45 | required: true 46 | - type: textarea 47 | attributes: 48 | label: Logs 49 | description: | 50 | Find the log corresponding to the bug and attach it here. 51 | Log files are under Logs folder. 52 | When in doubt, delete all log files, reproduce the bug, and attach the new log file. 53 | validations: 54 | required: true 55 | - type: markdown 56 | attributes: 57 | value: > 58 | Thanks for contributing! 59 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Discord Server 4 | url: https://discord.gg/UfpMnqMmEM 5 | about: Ask and answer questions here. 6 | - name: Chinese QQ Group 7 | url: https://qm.qq.com/cgi-bin/qm/qr?k=8EtEpehB1a-nfTNAnngTVqX3o9xoIxmT&jump_from=webapi 8 | about: Ask and answer questions in Chinese here. 9 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 StAkira 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Logo/openutau.svg: -------------------------------------------------------------------------------- 1 | Artboard 1 -------------------------------------------------------------------------------- /Logo/openutau_logotype.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Misc/GIFs/editor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/Misc/GIFs/editor.gif -------------------------------------------------------------------------------- /Misc/GIFs/editor2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/Misc/GIFs/editor2.gif -------------------------------------------------------------------------------- /Misc/GIFs/playback.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/Misc/GIFs/playback.gif -------------------------------------------------------------------------------- /Misc/GIFs/undo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/Misc/GIFs/undo.gif -------------------------------------------------------------------------------- /Misc/GIFs/vibrato.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/Misc/GIFs/vibrato.gif -------------------------------------------------------------------------------- /OpenUtau.Core/Analysis/Crepe/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Jong Wook Kim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /OpenUtau.Core/Analysis/Crepe/tiny.onnx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Core/Analysis/Crepe/tiny.onnx -------------------------------------------------------------------------------- /OpenUtau.Core/Api/G2pDictionaryData.cs: -------------------------------------------------------------------------------- 1 | namespace OpenUtau.Api { 2 | /// 3 | /// Data class used to deserialize yaml dictionary. 4 | /// 5 | public class G2pDictionaryData { 6 | public struct SymbolData { 7 | public string symbol; 8 | public string type; 9 | } 10 | 11 | public struct Entry { 12 | public string grapheme; 13 | public string[] phonemes; 14 | } 15 | 16 | public SymbolData[] symbols; 17 | public Entry[] entries; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /OpenUtau.Core/Api/G2pFallbacks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace OpenUtau.Api { 3 | public class G2pFallbacks : IG2p { 4 | IG2p[] dictionaries; 5 | 6 | public G2pFallbacks(IG2p[] dictionaries) { 7 | this.dictionaries = dictionaries; 8 | } 9 | 10 | public bool IsValidSymbol(string symbol) { 11 | foreach (var dict in dictionaries) { 12 | if (dict.IsValidSymbol(symbol)) { 13 | return true; 14 | } 15 | } 16 | return false; 17 | } 18 | 19 | public bool IsVowel(string symbol) { 20 | foreach (var dict in dictionaries) { 21 | if (dict.IsValidSymbol(symbol)) { 22 | return dict.IsVowel(symbol); 23 | } 24 | } 25 | return false; 26 | } 27 | 28 | public string[] Query(string grapheme) { 29 | foreach (var dict in dictionaries) { 30 | var result = dict.Query(grapheme); 31 | if (result != null) { 32 | return result; 33 | } 34 | } 35 | return null; 36 | } 37 | 38 | public string[] UnpackHint(string hint, char separator = ' ') { 39 | foreach (var dict in dictionaries) { 40 | var result = dict.UnpackHint(hint, separator); 41 | if (result != null) { 42 | return result; 43 | } 44 | } 45 | return null; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /OpenUtau.Core/Api/G2pRemapper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace OpenUtau.Api { 5 | public class G2pRemapper : IG2p { 6 | private IG2p mapped; 7 | private Dictionary phonemeSymbols; // (phoneme, isVowel) 8 | private Dictionary replacements; 9 | 10 | public G2pRemapper(IG2p mapped, 11 | Dictionary phonemeSymbols, 12 | Dictionary replacements) { 13 | this.mapped = mapped; 14 | this.phonemeSymbols = phonemeSymbols; 15 | this.replacements = replacements; 16 | } 17 | 18 | public bool IsValidSymbol(string symbol) { 19 | return phonemeSymbols.ContainsKey(symbol); 20 | } 21 | 22 | public bool IsVowel(string symbol) { 23 | return phonemeSymbols.TryGetValue(symbol, out var isVowel) && isVowel; 24 | } 25 | 26 | public string[] Query(string grapheme) { 27 | var phonemes = mapped.Query(grapheme); 28 | if (phonemes == null) { 29 | return null; 30 | } 31 | phonemes = phonemes.Clone() as string[]; 32 | for (int i = 0; i < phonemes.Length; ++i) { 33 | if (replacements.TryGetValue(phonemes[i], out var replacement)) { 34 | phonemes[i] = replacement; 35 | } 36 | } 37 | return phonemes; 38 | } 39 | 40 | public string[] UnpackHint(string hint, char separator = ' ') { 41 | return hint.Split(separator) 42 | .Where(s => phonemeSymbols.ContainsKey(s)) 43 | .ToArray(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /OpenUtau.Core/Api/IG2p.cs: -------------------------------------------------------------------------------- 1 | namespace OpenUtau.Api { 2 | public interface IG2p { 3 | bool IsValidSymbol(string symbol); 4 | bool IsVowel(string symbol); 5 | 6 | /// 7 | /// Produces a list of phonemes from grapheme. 8 | /// 9 | string[] Query(string grapheme); 10 | 11 | /// 12 | /// Produces a list of phonemes from hint, removing invalid symbols. 13 | /// 14 | string[] UnpackHint(string hint, char separator = ' '); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /OpenUtau.Core/Api/PhonemizerFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | 5 | namespace OpenUtau.Api { 6 | public class PhonemizerFactory { 7 | public Type type; 8 | public string name; 9 | public string tag; 10 | public string author; 11 | public string language; 12 | 13 | public Phonemizer Create() { 14 | var phonemizer = Activator.CreateInstance(type) as Phonemizer; 15 | phonemizer.Name = name; 16 | phonemizer.Tag = tag; 17 | phonemizer.Language = language; 18 | return phonemizer; 19 | } 20 | 21 | public override string ToString() => string.IsNullOrEmpty(author) 22 | ? $"[{tag}] {name}" 23 | : $"[{tag}] {name} (Contributed by {author})"; 24 | 25 | private static Dictionary factories = new Dictionary(); 26 | public static PhonemizerFactory Get(Type type) { 27 | if (!factories.TryGetValue(type, out var factory)) { 28 | var attr = type.GetCustomAttribute(); 29 | if (attr == null || string.IsNullOrEmpty(attr.Name) || string.IsNullOrEmpty(attr.Tag)) { 30 | return null; 31 | } 32 | factory = new PhonemizerFactory() { 33 | type = type, 34 | name = attr.Name, 35 | tag = attr.Tag, 36 | author = attr.Author, 37 | language = attr.Language, 38 | }; 39 | factories[type] = factory; 40 | } 41 | return factory; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /OpenUtau.Core/Api/README.md: -------------------------------------------------------------------------------- 1 | # OpenUtau API 2 | 3 | API for OpenUtau plugin development. They are also used in OpenUtau.Plugin.Builtin project. You can refer to them as example. 4 | 5 | ## Phonemizer 6 | 7 | Experimental. Subject to change. Feedback welcomed. 8 | 9 | API documented in: 10 | - [Phonemizer.cs](Phonemizer.cs) 11 | 12 | Heavily commented example implementations, from simplest to most complex: 13 | - [DefaultPhonemizer.cs](../DefaultPhonemizer.cs) 14 | - [JapaneseVCVPhonemizer.cs](../../OpenUtau.Plugin.Builtin/JapaneseVCVPhonemizer.cs) 15 | - [ChineseCVVPhonemizer.cs](../../OpenUtau.Plugin.Builtin/ChineseCVVPhonemizer.cs) 16 | - [ArpasingPhonemizer.cs](../../OpenUtau.Plugin.Builtin/ArpasingPhonemizer.cs) 17 | 18 | The main method to implement is: 19 | ``` 20 | public abstract Phoneme[] Process(Note[] notes, Note? prevNeighbour, Note? nextNeighbour); 21 | ``` 22 | `notes`: A group of notes. The first note contains the lyric. The rest are extender notes with lyric "+" or "+n" (n is a number). 23 | `prevNeighbour` and `nextNeighbour`: Useful info for creating diphones, if applicable. E.g., creating proper leading diphone in VCV. 24 | `returns`: An array of phonemes, positioned relative to the first note. 25 | For actual document read comments in [Phonemizer.cs](Phonemizer.cs). 26 | 27 | A complete Phonemizer should: 28 | 1. Produce phonemes (or diphones) from the lyric, and previous / next notes if exsit. 29 | 2. Distribute phonemes to positions relative to the first note. 30 | 3. Supports phonetic hinting, e.g., lyric like "read", "read[r iy d]" or "[r iy d]". 31 | 4. Supports extender note aligments if the language is multisyllabic, i.e., "+n" notes. 32 | 33 | Tips: 34 | - To load singer specific resouce, Implement resouce loading in SetSinger() and use singer.Location to look for files. 35 | - If uses expensive resource, load it lazily when the phonemizer is created the first time. Use your best adjudgement to decide its lifetime. 36 | -------------------------------------------------------------------------------- /OpenUtau.Core/Audio/AudioDevice.cs: -------------------------------------------------------------------------------- 1 | using OpenUtau.Audio.Bindings; 2 | 3 | namespace OpenUtau.Audio { 4 | readonly struct AudioDevice { 5 | public int DeviceIndex { get; } 6 | public string Name { get; } 7 | public string HostApi { get; } 8 | public int MaxInputChannels { get; } 9 | public int MaxOutputChannels { get; } 10 | public double DefaultLowInputLatency { get; } 11 | public double DefaultLowOutputLatency { get; } 12 | public double DefaultHighInputLatency { get; } 13 | public double DefaultHighOutputLatency { get; } 14 | public int DefaultSampleRate { get; } 15 | public AudioDevice(PaBinding.PaDeviceInfo device, int deviceIndex) { 16 | var hostApi = PaBinding.GetHostApiInfo(device.hostApi); 17 | DeviceIndex = deviceIndex; 18 | Name = device.name; 19 | HostApi = hostApi.name; 20 | MaxInputChannels = device.maxInputChannels; 21 | MaxOutputChannels = device.maxOutputChannels; 22 | DefaultLowInputLatency = device.defaultLowInputLatency; 23 | DefaultLowOutputLatency = device.defaultLowOutputLatency; 24 | DefaultHighInputLatency = device.defaultHighInputLatency; 25 | DefaultHighOutputLatency = device.defaultHighOutputLatency; 26 | DefaultSampleRate = (int)device.defaultSampleRate; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /OpenUtau.Core/Audio/AudioFrame.cs: -------------------------------------------------------------------------------- 1 | namespace OpenUtau.Audio { 2 | public sealed class AudioFrame { 3 | public AudioFrame(double presentationTime, float[] data) { 4 | PresentationTime = presentationTime; 5 | Data = data; 6 | } 7 | public double PresentationTime { get; } 8 | public float[] Data { get; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /OpenUtau.Core/Audio/AudioStreamInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace OpenUtau.Audio { 4 | public readonly struct AudioStreamInfo { 5 | public AudioStreamInfo(int channels, int sampleRate, TimeSpan duration) { 6 | Channels = channels; 7 | SampleRate = sampleRate; 8 | Duration = duration; 9 | } 10 | public int Channels { get; } 11 | public int SampleRate { get; } 12 | public TimeSpan Duration { get; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /OpenUtau.Core/Audio/Bindings/PaBinding.Enums.cs: -------------------------------------------------------------------------------- 1 | namespace OpenUtau.Audio.Bindings { 2 | internal static partial class PaBinding { 3 | public enum PaSampleFormat : long { 4 | paFloat32 = 0x00000001, 5 | paInt32 = 0x00000002, 6 | paInt24 = 0x00000004, 7 | paInt16 = 0x00000008, 8 | paInt8 = 0x00000010, 9 | paUInt8 = 0x00000020, 10 | paCustomFormat = 0x00010000, 11 | paNonInterleaved = 0x80000000, 12 | } 13 | 14 | public enum PaStreamCallbackFlags : long { 15 | paInputUnderflow = 0x00000001, 16 | paInputOverflow = 0x00000002, 17 | paOutputUnderflow = 0x00000004, 18 | paOutputOverflow = 0x00000008, 19 | paPrimingOutput = 0x00000010 20 | } 21 | 22 | public enum PaStreamCallbackResult { 23 | paContinue = 0, 24 | paComplete = 1, 25 | paAbort = 2 26 | } 27 | 28 | public enum PaStreamFlags : long { 29 | paNoFlag = 0, 30 | paClipOff = 0x00000001, 31 | paDitherOff = 0x00000002, 32 | paPrimeOutputBuffersUsingStreamCallback = 0x00000008, 33 | paPlatformSpecificFlags = 0xFFFF0000 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /OpenUtau.Core/Audio/Bindings/PaBinding.Structs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace OpenUtau.Audio.Bindings { 5 | internal static partial class PaBinding { 6 | [StructLayout(LayoutKind.Sequential)] 7 | public readonly struct PaVersionInfo { 8 | public readonly int versionMajor; 9 | public readonly int versionMinor; 10 | public readonly int versionSubMinor; 11 | 12 | [MarshalAs(UnmanagedType.LPStr)] 13 | public readonly string versionControlRevision; 14 | 15 | [MarshalAs(UnmanagedType.LPStr)] 16 | public readonly string verionText; 17 | } 18 | 19 | [StructLayout(LayoutKind.Sequential)] 20 | public struct PaStreamParameters { 21 | public int device; 22 | public int channelCount; 23 | public PaSampleFormat sampleFormat; 24 | public double suggestedLatency; 25 | public IntPtr hostApiSpecificStreamInfo; 26 | } 27 | 28 | [StructLayout(LayoutKind.Sequential)] 29 | public readonly struct PaDeviceInfo { 30 | public readonly int structVersion; 31 | 32 | [MarshalAs(UnmanagedType.LPUTF8Str)] 33 | public readonly string name; 34 | 35 | public readonly int hostApi; 36 | public readonly int maxInputChannels; 37 | public readonly int maxOutputChannels; 38 | public readonly double defaultLowInputLatency; 39 | public readonly double defaultLowOutputLatency; 40 | public readonly double defaultHighInputLatency; 41 | public readonly double defaultHighOutputLatency; 42 | public readonly double defaultSampleRate; 43 | } 44 | 45 | [StructLayout(LayoutKind.Sequential)] 46 | public readonly struct PaHostApiInfo { 47 | public readonly int structVersion; 48 | 49 | public readonly int type; 50 | 51 | [MarshalAs(UnmanagedType.LPStr)] 52 | public readonly string name; 53 | 54 | public readonly int deviceCount; 55 | public readonly int defaultInputDevice; 56 | public readonly int defaultOutputDevice; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /OpenUtau.Core/Audio/Bindings/PaBinding.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace OpenUtau.Audio.Bindings { 5 | internal static partial class PaBinding { 6 | public static string GetErrorText(int code) => Marshal.PtrToStringAnsi(Pa_GetErrorText(code)); 7 | 8 | public static void MaybeThrow(int code) { 9 | if (code >= 0) { 10 | return; 11 | } 12 | throw new Exception(Marshal.PtrToStringAnsi(Pa_GetErrorText(code))); 13 | } 14 | 15 | public static PaDeviceInfo GetDeviceInfo(int device) => Marshal.PtrToStructure(Pa_GetDeviceInfo(device)); 16 | public static PaHostApiInfo GetHostApiInfo(int hostApi) => Marshal.PtrToStructure(Pa_GetHostApiInfo(hostApi)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /OpenUtau.Core/Audio/DummyAudioOutput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NAudio.Wave; 4 | 5 | namespace OpenUtau.Audio { 6 | public class DummyAudioOutput : IAudioOutput { 7 | public PlaybackState PlaybackState => PlaybackState.Stopped; 8 | public int DeviceNumber => 0; 9 | public List GetOutputDevices() => new List(); 10 | public long GetPosition() => 0; 11 | public void Init(ISampleProvider sampleProvider) { } 12 | public void Pause() { } 13 | public void Play() { } 14 | public void SelectDevice(Guid guid, int deviceNumber) { } 15 | public void Stop() { } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /OpenUtau.Core/Audio/IAudioOutput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NAudio.Wave; 4 | 5 | namespace OpenUtau.Audio { 6 | public class AudioOutputDevice { 7 | public string name; 8 | public string api; 9 | public int deviceNumber; 10 | public Guid guid; 11 | public object data; 12 | 13 | public override string ToString() => $"[{api}] {name}"; 14 | } 15 | 16 | public interface IAudioOutput { 17 | PlaybackState PlaybackState { get; } 18 | int DeviceNumber { get; } 19 | 20 | void SelectDevice(Guid guid, int deviceNumber); 21 | void Init(ISampleProvider sampleProvider); 22 | void Pause(); 23 | void Play(); 24 | void Stop(); 25 | long GetPosition(); 26 | 27 | List GetOutputDevices(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /OpenUtau.Core/BaseChinesePhonemizer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using OpenUtau.Api; 6 | using ToolGood.Words.Pinyin; 7 | 8 | namespace OpenUtau.Core { 9 | public abstract class BaseChinesePhonemizer : Phonemizer { 10 | public static bool IsHanzi(string lyric) { 11 | return lyric.Length == 1 && WordsHelper.IsAllChinese(lyric); 12 | } 13 | 14 | public static Note[] ChangeLyric(Note[] group, string lyric) { 15 | var oldNote = group[0]; 16 | group[0] = new Note { 17 | lyric = lyric, 18 | phoneticHint = oldNote.phoneticHint, 19 | tone = oldNote.tone, 20 | position = oldNote.position, 21 | duration = oldNote.duration, 22 | phonemeAttributes = oldNote.phonemeAttributes, 23 | }; 24 | return group; 25 | } 26 | 27 | public static string[] Romanize(IEnumerable lyrics) { 28 | var lyricsArray = lyrics.ToArray(); 29 | var hanziLyrics = String.Join("", lyricsArray 30 | .Where(IsHanzi)); 31 | var pinyinResult = WordsHelper.GetPinyin(hanziLyrics, " ").ToLower().Split(); 32 | var pinyinIndex = 0; 33 | for(int i=0; i < lyricsArray.Length; i++) { 34 | if (lyricsArray[i].Length == 1 && WordsHelper.IsAllChinese(lyricsArray[i])) { 35 | lyricsArray[i] = pinyinResult[pinyinIndex]; 36 | pinyinIndex++; 37 | } 38 | } 39 | return lyricsArray; 40 | } 41 | 42 | public static void RomanizeNotes(Note[][] groups) { 43 | var ResultLyrics = Romanize(groups.Select(group => group[0].lyric)); 44 | Enumerable.Zip(groups, ResultLyrics, ChangeLyric).Last(); 45 | } 46 | 47 | public override void SetUp(Note[][] groups) { 48 | RomanizeNotes(groups); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /OpenUtau.Core/Classic/ClassicSingerLoader.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using OpenUtau.Core; 4 | using OpenUtau.Core.Ustx; 5 | 6 | namespace OpenUtau.Classic { 7 | public static class ClassicSingerLoader { 8 | static USinger AdjustSingerType(Voicebank v) { 9 | switch (v.SingerType) { 10 | case USingerType.Enunu: 11 | return new Core.Enunu.EnunuSinger(v) as USinger; 12 | case USingerType.DiffSinger: 13 | return new Core.DiffSinger.DiffSingerSinger(v) as USinger; 14 | default: 15 | return new ClassicSinger(v) as USinger; 16 | } 17 | } 18 | public static IEnumerable FindAllSingers() { 19 | List singers = new List(); 20 | foreach (var path in new string[] { 21 | PathManager.Inst.SingersPathOld, 22 | PathManager.Inst.SingersPath, 23 | PathManager.Inst.AdditionalSingersPath, 24 | }) { 25 | var loader = new VoicebankLoader(path); 26 | singers.AddRange(loader.SearchAll() 27 | .Select(AdjustSingerType)); 28 | } 29 | return singers; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /OpenUtau.Core/Classic/IPlugin.cs: -------------------------------------------------------------------------------- 1 | namespace OpenUtau.Classic { 2 | public interface IPlugin { 3 | string Encoding { get; } 4 | void Run(string tempFile); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /OpenUtau.Core/Classic/IResampler.cs: -------------------------------------------------------------------------------- 1 | using OpenUtau.Core.Ustx; 2 | using Serilog; 3 | 4 | namespace OpenUtau.Classic { 5 | public interface IResampler { 6 | string FilePath { get; } 7 | float[] DoResampler(ResamplerItem args, ILogger logger); 8 | string DoResamplerReturnsFile(ResamplerItem args, ILogger logger); 9 | void CheckPermissions(); 10 | ResamplerManifest Manifest { get; } 11 | bool SupportsFlag(string abbr); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /OpenUtau.Core/Classic/IWavtool.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | 4 | namespace OpenUtau.Classic { 5 | public interface IWavtool { 6 | // 7 | // [ [ [ ]]] 8 | float[] Concatenate(List resamplerItems, string tempPath, CancellationTokenSource cancellation); 9 | void CheckPermissions(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /OpenUtau.Core/Classic/OtoWatcher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using OpenUtau.Core; 4 | using Serilog; 5 | 6 | namespace OpenUtau.Classic { 7 | class OtoWatcher : IDisposable { 8 | public bool Paused { get; set; } 9 | 10 | private ClassicSinger singer; 11 | private FileSystemWatcher watcher; 12 | 13 | public OtoWatcher(ClassicSinger singer, string path) { 14 | this.singer = singer; 15 | watcher = new FileSystemWatcher(path); 16 | watcher.Changed += OnFileChanged; 17 | watcher.Created += OnFileChanged; 18 | watcher.Deleted += OnFileChanged; 19 | watcher.Renamed += OnFileChanged; 20 | watcher.Error += OnError; 21 | watcher.Filter = "oto.ini"; 22 | watcher.IncludeSubdirectories = true; 23 | watcher.EnableRaisingEvents = true; 24 | } 25 | 26 | private void OnFileChanged(object sender, FileSystemEventArgs e) { 27 | if (Paused) { 28 | return; 29 | } 30 | Log.Information($"File \"{e.FullPath}\" {e.ChangeType}"); 31 | SingerManager.Inst.ScheduleReload(singer); 32 | } 33 | 34 | private void OnError(object sender, ErrorEventArgs e) { 35 | Log.Error($"Watcher error {e}"); 36 | } 37 | 38 | public void Dispose() { 39 | watcher.Dispose(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /OpenUtau.Core/Classic/Plugin.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using System.IO; 3 | 4 | namespace OpenUtau.Classic { 5 | public class Plugin : IPlugin { 6 | public string Name; 7 | public string Executable; 8 | public bool AllNotes; 9 | public bool UseShell; 10 | private string encoding = "shift_jis"; 11 | 12 | public string Encoding { get => encoding; set => encoding = value; } 13 | 14 | public void Run(string tempFile) { 15 | if (!File.Exists(Executable)) { 16 | throw new FileNotFoundException($"Executable {Executable} not found."); 17 | } 18 | var startInfo = new ProcessStartInfo() { 19 | FileName = Executable, 20 | Arguments = tempFile, 21 | WorkingDirectory = Path.GetDirectoryName(Executable), 22 | UseShellExecute = UseShell, 23 | }; 24 | using (var process = Process.Start(startInfo)) { 25 | process.WaitForExit(); 26 | } 27 | } 28 | 29 | public override string ToString() => Name; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /OpenUtau.Core/Classic/ResamplerManifest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using OpenUtau.Core; 6 | using OpenUtau.Core.Ustx; 7 | 8 | namespace OpenUtau.Classic { 9 | public class ResamplerManifest { 10 | public Dictionary expressions = new Dictionary { }; 11 | public bool expressionFilter = false; 12 | 13 | public ResamplerManifest() { } 14 | 15 | public static ResamplerManifest Load(string path) { 16 | return Yaml.DefaultDeserializer.Deserialize( 17 | File.ReadAllText(path, encoding: Encoding.UTF8) 18 | ); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /OpenUtau.Core/Classic/VoicebankConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Text; 5 | using OpenUtau.Core; 6 | using YamlDotNet.Serialization; 7 | 8 | namespace OpenUtau.Classic { 9 | public enum SymbolSetPreset { unknown, hiragana, arpabet } 10 | 11 | public class SymbolSet { 12 | public SymbolSetPreset Preset { get; set; } 13 | public string Head { get; set; } = "-"; 14 | public string Tail { get; set; } = "R"; 15 | } 16 | 17 | 18 | public class Subbank { 19 | /// 20 | /// Voice color, e.g., "power", "whisper". Leave unspecified for the main bank. 21 | /// 22 | public string Color { get; set; } = string.Empty; 23 | 24 | /// 25 | /// Subbank prefix. Leave unspecified if none. 26 | /// 27 | public string Prefix { get; set; } = string.Empty; 28 | 29 | /// 30 | /// Subbank suffix. Leave unspecified if none. 31 | /// 32 | public string Suffix { get; set; } = string.Empty; 33 | 34 | /// 35 | /// Tone ranges. Each range specified as "C1-C4" or "C4". 36 | /// 37 | public string[] ToneRanges { get; set; } 38 | } 39 | 40 | public class VoicebankConfig { 41 | public string Name; 42 | public string TextFileEncoding; 43 | public string Image; 44 | public string Portrait; 45 | public float PortraitOpacity = 0.67f; 46 | public string Author; 47 | public string Voice; 48 | public string Web; 49 | public string Version; 50 | public string DefaultPhonemizer; 51 | public SymbolSet SymbolSet { get; set; } 52 | public Subbank[] Subbanks { get; set; } 53 | 54 | public void Save(Stream stream) { 55 | using (var writer = new StreamWriter(stream, Encoding.UTF8)) { 56 | Yaml.DefaultSerializer.Serialize(writer, this); 57 | } 58 | } 59 | 60 | public static VoicebankConfig Load(Stream stream) { 61 | using (var reader = new StreamReader(stream, Encoding.UTF8)) { 62 | var bankConfig = Yaml.DefaultDeserializer.Deserialize(reader); 63 | return bankConfig; 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /OpenUtau.Core/Classic/WorldlineResampler.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using NAudio.Wave; 3 | using OpenUtau.Core; 4 | using OpenUtau.Core.Render; 5 | using OpenUtau.Core.SignalChain; 6 | using OpenUtau.Core.Ustx; 7 | using Serilog; 8 | 9 | namespace OpenUtau.Classic { 10 | internal class WorldlineResampler : IResampler { 11 | public const string name = "worldline"; 12 | public string FilePath { get; private set; } 13 | 14 | public WorldlineResampler() { 15 | string ext = OS.IsWindows() ? ".dll" : OS.IsMacOS() ? ".dylib" : ".so"; 16 | FilePath = Path.Join(PathManager.Inst.RootPath, name + ext); 17 | } 18 | 19 | public float[] DoResampler(ResamplerItem item, ILogger logger) { 20 | return Worldline.Resample(item); 21 | } 22 | 23 | public string DoResamplerReturnsFile(ResamplerItem item, ILogger logger) { 24 | var samples = DoResampler(item, logger); 25 | var source = new WaveSource(0, 0, 0, 1); 26 | source.SetSamples(samples); 27 | lock (Renderers.GetCacheLock(item.outputFile)) { 28 | WaveFileWriter.CreateWaveFile16(item.outputFile, new ExportAdapter(source).ToMono(1, 0)); 29 | } 30 | return item.outputFile; 31 | } 32 | 33 | public void CheckPermissions() { } 34 | 35 | //TODO: A list of flags supported by worldline resampler 36 | public ResamplerManifest Manifest { get; } = new ResamplerManifest(); 37 | 38 | public bool SupportsFlag(string abbr) { 39 | return true; 40 | } 41 | 42 | public override string ToString() => name; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /OpenUtau.Core/Commands/UCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace OpenUtau.Core { 6 | public abstract class UCommand { 7 | public virtual bool Silent => false; 8 | public virtual ValidateOptions ValidateOptions => default; 9 | public abstract void Execute(); 10 | public abstract void Unexecute(); 11 | public virtual bool CanMerge(IList commands) => false; 12 | public virtual UCommand Merge(IList commands) => throw new NotImplementedException(); 13 | public abstract override string ToString(); 14 | } 15 | 16 | public class UCommandGroup { 17 | public bool DeferValidate; 18 | public List Commands; 19 | public UCommandGroup(bool deferValidate) { 20 | DeferValidate = deferValidate; 21 | Commands = new List(); 22 | } 23 | public void Merge() { 24 | if (Commands.Count > 0 && Commands.Last().CanMerge(Commands)) { 25 | var merged = Commands.Last().Merge(Commands); 26 | Commands.Clear(); 27 | Commands.Add(merged); 28 | } 29 | } 30 | public override string ToString() { return Commands.Count == 0 ? "No op" : Commands.First().ToString(); } 31 | } 32 | 33 | public interface ICmdSubscriber { 34 | void OnNext(UCommand cmd, bool isUndo); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /OpenUtau.Core/DefaultPhonemizer.cs: -------------------------------------------------------------------------------- 1 | using OpenUtau.Api; 2 | using OpenUtau.Core.Ustx; 3 | using System.Linq; 4 | 5 | namespace OpenUtau.Core { 6 | /// 7 | /// The simplest Phonemizer possible. Simply pass the lyric as phoneme. 8 | /// 9 | [Phonemizer("Default Phonemizer", "DEFAULT")] 10 | public class DefaultPhonemizer : Phonemizer { 11 | private USinger singer; 12 | public override void SetSinger(USinger singer) => this.singer = singer; 13 | public override Result Process(Note[] notes, Note? prev, Note? next, Note? prevNeighbour, Note? nextNeighbour, Note[] prevNeighbours) { 14 | // Note that even when input has multiple notes, only the leading note is used to produce phoneme. 15 | // This is because the 2nd+ notes will always be extender notes, i.e., with lyric "+" or "+". 16 | // For this simple phonemizer, all these notes maps to a single phoneme. 17 | string alias = notes[0].lyric; 18 | var attr0 = notes[0].phonemeAttributes?.FirstOrDefault(attr => attr.index == 0) ?? default; 19 | if (singer.TryGetMappedOto(notes[0].lyric, notes[0].tone + attr0.toneShift, attr0.voiceColor, out var oto)) { 20 | alias = oto.Alias; 21 | } 22 | return new Result { 23 | phonemes = new Phoneme[] { 24 | new Phoneme { 25 | phoneme = alias, 26 | } 27 | } 28 | }; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /OpenUtau.Core/DiffSinger/DiffSingerConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace OpenUtau.Core.DiffSinger { 6 | 7 | [Serializable] 8 | public class RandomPitchShifting { 9 | public float[] range; 10 | } 11 | 12 | [Serializable] 13 | public class AugmentationArgs { 14 | public RandomPitchShifting randomPitchShifting; 15 | } 16 | 17 | [Serializable] 18 | public class DsConfig { 19 | public string phonemes = "phonemes.txt"; 20 | public string acoustic; 21 | public string vocoder; 22 | public List speakers; 23 | public int hiddenSize = 256; 24 | public bool useKeyShiftEmbed = false; 25 | public bool useSpeedEmbed = false; 26 | public AugmentationArgs augmentationArgs; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /OpenUtau.Core/DiffSinger/DiffSingerDependencyInstaller.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Text; 5 | using SharpCompress.Archives; 6 | 7 | namespace OpenUtau.Core.DiffSinger { 8 | //Diffsinger音源依赖项的安装,包括声码器,音素时长模型 9 | [Serializable] 10 | public class DependencyConfig { 11 | public string name = "vocoder"; 12 | } 13 | 14 | public class DiffSingerDependencyInstaller { 15 | public static string FileExt = ".dsvocoder"; 16 | public static void Install(string archivePath) { 17 | DependencyConfig dependencyConfig; 18 | using (var archive = ArchiveFactory.Open(archivePath)) { 19 | DocManager.Inst.ExecuteCmd(new ProgressBarNotification(0, "Installing dependency")); 20 | var configEntry = archive.Entries.First(e => e.Key == "vocoder.yaml"); 21 | if (configEntry == null) { 22 | throw new ArgumentException("missing vocoder.yaml"); 23 | } 24 | using (var stream = configEntry.OpenEntryStream()) { 25 | using var reader = new StreamReader(stream, Encoding.UTF8); 26 | dependencyConfig = Core.Yaml.DefaultDeserializer.Deserialize(reader); 27 | } 28 | string name = dependencyConfig.name; 29 | var basePath = Path.Combine(PathManager.Inst.DependencyPath, name); 30 | foreach (var entry in archive.Entries) { 31 | if (entry.Key.Contains("..")) { 32 | // Prevent zipSlip attack 33 | continue; 34 | } 35 | var filePath = Path.Combine(basePath, entry.Key); 36 | Directory.CreateDirectory(Path.GetDirectoryName(filePath)); 37 | if (!entry.IsDirectory) { 38 | entry.WriteToFile(Path.Combine(basePath, entry.Key)); 39 | } 40 | } 41 | DocManager.Inst.ExecuteCmd(new ProgressBarNotification(0, $"dependency \"{name}\" installaion finished")); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /OpenUtau.Core/DiffSinger/DiffSingerUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using OpenUtau.Core.Render; 3 | 4 | namespace OpenUtau.Core.DiffSinger { 5 | public static class DiffSingerUtils { 6 | public const string VELC = "velc"; 7 | public const string VoiceColorHeader = "cl"; 8 | public const float headMs = 0; 9 | public const float tailMs = 100; 10 | 11 | //参数曲线采样 12 | public static double[] SampleCurve(RenderPhrase phrase, float[] curve, double defaultValue, double frameMs, int length, int headFrames, int tailFrames, Func convert) { 13 | const int interval = 5; 14 | var result = new double[length]; 15 | if (curve == null) { 16 | Array.Fill(result, defaultValue); 17 | return result; 18 | } 19 | 20 | for (int i = 0; i < length - headFrames - tailFrames; i++) { 21 | double posMs = phrase.positionMs - phrase.leadingMs + i * frameMs; 22 | int ticks = phrase.timeAxis.MsPosToTickPos(posMs) - (phrase.position - phrase.leading); 23 | int index = Math.Max(0, (int)((double)ticks / interval)); 24 | if (index < curve.Length) { 25 | result[i + headFrames] = convert(curve[index]); 26 | } 27 | } 28 | //填充头尾 29 | Array.Fill(result, convert(curve[0]), 0, headFrames); 30 | Array.Fill(result, convert(curve[^1]), length - tailFrames, tailFrames); 31 | return result; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /OpenUtau.Core/DiffSinger/DiffSingerVocoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Microsoft.ML.OnnxRuntime; 4 | 5 | namespace OpenUtau.Core.DiffSinger { 6 | public class DsVocoder { 7 | public string Location; 8 | public DsVocoderConfig config; 9 | public IOnnxInferenceSession session; 10 | 11 | //通过名称获取声码器 12 | public DsVocoder(string name) { 13 | byte[] model; 14 | try { 15 | Location = Path.Combine(PathManager.Inst.DependencyPath, name); 16 | config = Core.Yaml.DefaultDeserializer.Deserialize( 17 | File.ReadAllText(Path.Combine(Location, "vocoder.yaml"), 18 | System.Text.Encoding.UTF8)); 19 | 20 | if (config.model.StartsWith("http")) { 21 | session = Onnx.getRemoteInferenceSession(config.model); 22 | } else { 23 | model = File.ReadAllBytes(Path.Combine(Location, config.model)); 24 | session = Onnx.getLocalInferenceSession(model); 25 | } 26 | } 27 | catch (Exception ex) { 28 | throw new Exception($"Error loading vocoder {name}. Please download vocoder from https://github.com/xunmengshe/OpenUtau/wiki/Vocoders"); 29 | } 30 | } 31 | 32 | public float frameMs() { 33 | return 1000f * config.hop_size / config.sample_rate; 34 | } 35 | } 36 | 37 | [Serializable] 38 | public class DsVocoderConfig { 39 | public string name = "vocoder"; 40 | public string model = "model.onnx"; 41 | public int num_mel_bins = 128; 42 | public int hop_size = 512; 43 | public int sample_rate = 44100; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /OpenUtau.Core/Editing/BatchEdit.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using OpenUtau.Core.Ustx; 3 | 4 | namespace OpenUtau.Core.Editing { 5 | public interface BatchEdit { 6 | string Name { get; } 7 | void Run(UProject project, UVoicePart part, List selectedNotes, DocManager docManager); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /OpenUtau.Core/Editing/README.md: -------------------------------------------------------------------------------- 1 | # Batch Edit Macros 2 | 3 | Contributions to editing macros are welcomed. 4 | 5 | An batch edit should: 6 | - Starts with `docManager.StartUndoGroup();` 7 | - Performs modifications by calling `docManager.ExecuteCmd();` with commands. 8 | - Some commands come with a single note variation and a multiple notes variation, e.g., `AddNoteCommand(UVoicePart part, UNote note)` and `AddNoteCommand(UVoicePart part, List notes)`. Use the multiple notes varitaion for batch edits. 9 | - Ends with `docManager.EndUndoGroup();` 10 | - Has a localized name. 11 | -------------------------------------------------------------------------------- /OpenUtau.Core/Enunu/EnunuClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NetMQ; 3 | using NetMQ.Sockets; 4 | using Newtonsoft.Json; 5 | using Serilog; 6 | 7 | namespace OpenUtau.Core.Enunu { 8 | class EnunuClient : Util.SingletonBase { 9 | internal T SendRequest(string[] args) { 10 | using (var client = new RequestSocket()) { 11 | client.Connect("tcp://localhost:15555"); 12 | string request = JsonConvert.SerializeObject(args); 13 | Log.Information($"EnunuProcess sending {request}"); 14 | client.SendFrame(request); 15 | client.TryReceiveFrameString(TimeSpan.FromSeconds(300), out string? message); 16 | Log.Information($"EnunuProcess received {message}"); 17 | return JsonConvert.DeserializeObject(message ?? string.Empty)!; 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /OpenUtau.Core/Enunu/EnunuUtils.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Text; 5 | using OpenUtau.Core.Ustx; 6 | 7 | namespace OpenUtau.Core.Enunu { 8 | public struct EnunuNote { 9 | public string lyric; 10 | public int length; 11 | public int noteNum; 12 | public int noteIndex; 13 | public string timbre; 14 | } 15 | 16 | internal static class EnunuUtils { 17 | static readonly Encoding ShiftJIS = Encoding.GetEncoding("shift_jis"); 18 | 19 | internal static void WriteUst(IList notes, double tempo, USinger singer, string ustPath) { 20 | using (var writer = new StreamWriter(ustPath, false, ShiftJIS)) { 21 | writer.WriteLine("[#SETTING]"); 22 | writer.WriteLine($"Tempo={tempo}"); 23 | writer.WriteLine("Tracks=1"); 24 | writer.WriteLine($"Project={ustPath}"); 25 | writer.WriteLine($"VoiceDir={singer.Location}"); 26 | writer.WriteLine($"CacheDir={PathManager.Inst.CachePath}"); 27 | writer.WriteLine("Mode2=True"); 28 | for (int i = 0; i < notes.Count; ++i) { 29 | writer.WriteLine($"[#{i}]"); 30 | writer.WriteLine($"Lyric={notes[i].lyric}"); 31 | writer.WriteLine($"Length={notes[i].length}"); 32 | writer.WriteLine($"NoteNum={notes[i].noteNum}"); 33 | if (!string.IsNullOrEmpty(notes[i].timbre)) { 34 | writer.WriteLine($"Flags={notes[i].timbre}"); 35 | } 36 | } 37 | writer.WriteLine("[#TRACKEND]"); 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /OpenUtau.Core/G2p/ArpabetG2p.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Microsoft.ML.OnnxRuntime; 5 | using OpenUtau.Api; 6 | 7 | namespace OpenUtau.Core.G2p { 8 | public class ArpabetG2p : G2pPack { 9 | private static readonly string[] graphemes = new string[] { 10 | "", "", "", "", "\'", "-", "a", "b", "c", "d", "e", 11 | "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", 12 | "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", 13 | }; 14 | 15 | private static readonly string[] phonemes = new string[] { 16 | "", "", "", "", "aa", "ae", "ah", "ao", "aw", "ay", "b", "ch", 17 | "d", "dh", "eh", "er", "ey", "f", "g", "hh", "ih", "iy", "jh", 18 | "k", "l", "m", "n", "ng", "ow", "oy", "p", "r", "s", "sh", "t", 19 | "th", "uh", "uw", "v", "w", "y", "z", "zh", 20 | }; 21 | 22 | private static object lockObj = new object(); 23 | private static Dictionary graphemeIndexes; 24 | private static IG2p dict; 25 | private static InferenceSession session; 26 | private static Dictionary predCache = new Dictionary(); 27 | 28 | public ArpabetG2p() { 29 | lock (lockObj) { 30 | if (graphemeIndexes == null) { 31 | graphemeIndexes = graphemes 32 | .Skip(4) 33 | .Select((g, i) => Tuple.Create(g, i)) 34 | .ToDictionary(t => t.Item1, t => t.Item2 + 4); 35 | var tuple = LoadPack( 36 | Data.Resources.g2p_arpabet, 37 | s => s.ToLowerInvariant(), 38 | s => RemoveTailDigits(s.ToLowerInvariant())); 39 | dict = tuple.Item1; 40 | session = tuple.Item2; 41 | } 42 | } 43 | GraphemeIndexes = graphemeIndexes; 44 | Phonemes = phonemes; 45 | Dict = dict; 46 | Session = session; 47 | PredCache = predCache; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /OpenUtau.Core/G2p/Data/g2p-arpabet.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Core/G2p/Data/g2p-arpabet.zip -------------------------------------------------------------------------------- /OpenUtau.Core/G2p/Data/g2p-es.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Core/G2p/Data/g2p-es.zip -------------------------------------------------------------------------------- /OpenUtau.Core/G2p/Data/g2p-fr.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Core/G2p/Data/g2p-fr.zip -------------------------------------------------------------------------------- /OpenUtau.Core/G2p/Data/g2p-it.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Core/G2p/Data/g2p-it.zip -------------------------------------------------------------------------------- /OpenUtau.Core/G2p/Data/g2p-pt.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Core/G2p/Data/g2p-pt.zip -------------------------------------------------------------------------------- /OpenUtau.Core/G2p/Data/g2p-ru.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Core/G2p/Data/g2p-ru.zip -------------------------------------------------------------------------------- /OpenUtau.Core/G2p/FrenchG2p.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Microsoft.ML.OnnxRuntime; 5 | using OpenUtau.Api; 6 | 7 | namespace OpenUtau.Core.G2p { 8 | public class FrenchG2p : G2pPack { 9 | private static readonly string[] graphemes = new string[] { 10 | "", "", "", "", "-", "a", "b", "c", "d", "e", "f", "g", 11 | "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", 12 | "s", "t", "u", "v", "w", "x", "y", "z", "à", "á", "â", "ä", 13 | "æ", "ç", "è", "é", "ê", "ë", "î", "ï", "ñ", "ô", "ö", 14 | "ù", "ú", "û", "ü", "ÿ" 15 | }; 16 | 17 | private static readonly string[] phonemes = new string[] { 18 | "", "", "", "", "aa", "ai", "an", "au", "bb", "ch", "dd", 19 | "ee", "ei", "eu", "ff", "gg", "gn", "ii", "in", "jj", "kk", 20 | "ll", "mm", "nn", "oe", "on", "oo", "ou", "pp", "rr", "ss", 21 | "tt", "un", "uu", "uy", "vv", "ww", "yy", "zz" 22 | }; 23 | 24 | private static object lockObj = new object(); 25 | private static Dictionary graphemeIndexes; 26 | private static IG2p dict; 27 | private static InferenceSession session; 28 | private static Dictionary predCache = new Dictionary(); 29 | 30 | public FrenchG2p() { 31 | lock (lockObj) { 32 | if (graphemeIndexes == null) { 33 | graphemeIndexes = graphemes 34 | .Skip(4) 35 | .Select((g, i) => Tuple.Create(g, i)) 36 | .ToDictionary(t => t.Item1, t => t.Item2 + 4); 37 | var tuple = LoadPack(Data.Resources.g2p_fr); 38 | dict = tuple.Item1; 39 | session = tuple.Item2; 40 | } 41 | } 42 | GraphemeIndexes = graphemeIndexes; 43 | Phonemes = phonemes; 44 | Dict = dict; 45 | Session = session; 46 | PredCache = predCache; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /OpenUtau.Core/G2p/ItalianG2p.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Microsoft.ML.OnnxRuntime; 5 | using OpenUtau.Api; 6 | 7 | namespace OpenUtau.Core.G2p { 8 | public class ItalianG2p : G2pPack { 9 | private static readonly string[] graphemes = new string[] { 10 | "", "", "", "", "\'", "a", "b", "c", "d", "e", 11 | "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", 12 | "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", 13 | "à", "é", "è", "È", "í", "ì", "ò", "ú", "ù", 14 | }; 15 | 16 | private static readonly string[] phonemes = new string[] { 17 | "", "", "", "", "a", "a1", "b", "d", "dz", "dZZ", "e", "e1", "EE", "f", 18 | "g", "i", "i1", "JJ", "k", "l", "LL", "m", "n", "nf", "ng", "o", "o1", 19 | "OO", "p", "r", "rr", "s", "SS", "t", "ts", "tSS", "u", "u1", "v", "w", 20 | "y", "z", 21 | }; 22 | 23 | private static object lockObj = new object(); 24 | private static Dictionary graphemeIndexes; 25 | private static IG2p dict; 26 | private static InferenceSession session; 27 | private static Dictionary predCache = new Dictionary(); 28 | 29 | public ItalianG2p() { 30 | lock (lockObj) { 31 | if (graphemeIndexes == null) { 32 | graphemeIndexes = graphemes 33 | .Skip(4) 34 | .Select((g, i) => Tuple.Create(g, i)) 35 | .ToDictionary(t => t.Item1, t => t.Item2 + 4); 36 | var tuple = LoadPack(Data.Resources.g2p_it); 37 | dict = tuple.Item1; 38 | session = tuple.Item2; 39 | } 40 | } 41 | GraphemeIndexes = graphemeIndexes; 42 | Phonemes = phonemes; 43 | Dict = dict; 44 | Session = session; 45 | PredCache = predCache; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /OpenUtau.Core/G2p/PortugueseG2p.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Microsoft.ML.OnnxRuntime; 5 | using OpenUtau.Api; 6 | 7 | namespace OpenUtau.Core.G2p { 8 | public class PortugueseG2p : G2pPack { 9 | private static readonly string[] graphemes = new string[] { 10 | "", "", "", "", "-", "a", "b", "c", "d", "e", "f", "g", "h", 11 | "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", 12 | "u", "v", "w", "x", "y", "z", "à", "á", "â", "ã", "ç", 13 | "è", "é", "ê", "í", "î", "ó", "ô", "õ", "ú", "û", "ü", 14 | }; 15 | 16 | private static readonly string[] phonemes = new string[] { 17 | "", "", "", "", "E", "J", "L", "O", "R", "S", "X", "Z", 18 | "a", "a~", "b", "d", "dZ", "e", "e~", "f", "g", 19 | "i", "i~", "j", "j~", "k", "l", "m", "n", "o", "o~", 20 | "p", "r", "s", "t", "tS", "u", "u~", "v", "w", "w~", "z", 21 | }; 22 | 23 | private static object lockObj = new object(); 24 | private static Dictionary graphemeIndexes; 25 | private static IG2p dict; 26 | private static InferenceSession session; 27 | private static Dictionary predCache = new Dictionary(); 28 | 29 | public PortugueseG2p() { 30 | lock (lockObj) { 31 | if (graphemeIndexes == null) { 32 | graphemeIndexes = graphemes 33 | .Skip(4) 34 | .Select((g, i) => Tuple.Create(g, i)) 35 | .ToDictionary(t => t.Item1, t => t.Item2 + 4); 36 | var tuple = LoadPack(Data.Resources.g2p_pt); 37 | dict = tuple.Item1; 38 | session = tuple.Item2; 39 | } 40 | } 41 | GraphemeIndexes = graphemeIndexes; 42 | Phonemes = phonemes; 43 | Dict = dict; 44 | Session = session; 45 | PredCache = predCache; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /OpenUtau.Core/G2p/RussianG2p.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Microsoft.ML.OnnxRuntime; 5 | using OpenUtau.Api; 6 | 7 | namespace OpenUtau.Core.G2p { 8 | // Dictionary from https://sourceforge.net/projects/cmusphinx/files/Acoustic%20and%20Language%20Models/Russian/zero_ru_cont_8k_v3.tar.gz 9 | public class RussianG2p : G2pPack { 10 | private static readonly string[] graphemes = new string[] { 11 | "", "", "", "", "-", "а", "б", "в", "г", "д", "е", "ж", "з", 12 | "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", 13 | "ф", "х", "ц", "ч", "ш", "щ", "ъ", "ы", "ь", "э", "ю", "я", "ё" 14 | }; 15 | 16 | private static readonly string[] phonemes = new string[] { 17 | "", "", "", "", "a", "aa", "ay", "b", "bb", "c", "ch", 18 | "d", "dd", "ee", "f", "ff", "g", "gg", "h", "hh", "i", "ii", 19 | "j", "ja", "je", "jo", "ju", "k", "kk", "l", "ll", "m", "mm", 20 | "n", "nn", "oo", "p", "pp", "r", "rr", "s", "sch", "sh", "ss", 21 | "t", "tt", "u", "uj", "uu", "v", "vv", "y", "yy", "z", "zh", "zz" 22 | }; 23 | 24 | private static object lockObj = new object(); 25 | private static Dictionary graphemeIndexes; 26 | private static IG2p dict; 27 | private static InferenceSession session; 28 | private static Dictionary predCache = new Dictionary(); 29 | 30 | public RussianG2p() { 31 | lock (lockObj) { 32 | if (graphemeIndexes == null) { 33 | graphemeIndexes = graphemes 34 | .Skip(4) 35 | .Select((g, i) => Tuple.Create(g, i)) 36 | .ToDictionary(t => t.Item1, t => t.Item2 + 4); 37 | var tuple = LoadPack(Data.Resources.g2p_ru); 38 | dict = tuple.Item1; 39 | session = tuple.Item2; 40 | } 41 | } 42 | GraphemeIndexes = graphemeIndexes; 43 | Phonemes = phonemes; 44 | Dict = dict; 45 | Session = session; 46 | PredCache = predCache; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /OpenUtau.Core/G2p/SpanishG2p.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Microsoft.ML.OnnxRuntime; 5 | using OpenUtau.Api; 6 | 7 | namespace OpenUtau.Core.G2p { 8 | public class SpanishG2p : G2pPack { 9 | private static readonly string[] graphemes = new string[] { 10 | "", "", "", "", "\'", "-", "a", "b", "c", "d", "e", 11 | "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", 12 | "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", 13 | "Á", "É", "Í", "Ó", "Ú", "á", "ã", "é", "ë", "ê", "í", 14 | "ñ", "ó", "ú", "ü" 15 | }; 16 | 17 | private static readonly string[] phonemes = new string[] { 18 | "", "", "", "", "a", "b", "B", "ch", "d", "D", "e", "f", 19 | "g", "G", "gn", "i", "I", "k", "l", "ll", "m", "n", "o", 20 | "p", "r", "rr", "s", "t", "u", "U", "w", "x", "y", "Y", "z" 21 | }; 22 | 23 | private static object lockObj = new object(); 24 | private static Dictionary graphemeIndexes; 25 | private static IG2p dict; 26 | private static InferenceSession session; 27 | private static Dictionary predCache = new Dictionary(); 28 | 29 | public SpanishG2p() { 30 | lock (lockObj) { 31 | if (graphemeIndexes == null) { 32 | graphemeIndexes = graphemes 33 | .Skip(4) 34 | .Select((g, i) => Tuple.Create(g, i)) 35 | .ToDictionary(t => t.Item1, t => t.Item2 + 4); 36 | var tuple = LoadPack( 37 | Data.Resources.g2p_es, 38 | s => s.ToLowerInvariant()); 39 | dict = tuple.Item1; 40 | session = tuple.Item2; 41 | } 42 | } 43 | GraphemeIndexes = graphemeIndexes; 44 | Phonemes = phonemes; 45 | Dict = dict; 46 | Session = session; 47 | PredCache = predCache; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /OpenUtau.Core/Render/IRenderer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using OpenUtau.Core.Ustx; 5 | 6 | namespace OpenUtau.Core.Render { 7 | public class NoResamplerException : Exception { } 8 | public class NoWavtoolException : Exception { } 9 | 10 | /// 11 | /// Render result of a phrase. 12 | /// 13 | public class RenderResult { 14 | public float[] samples; 15 | 16 | /// 17 | /// The length of leading samples. 18 | /// 19 | public double leadingMs; 20 | 21 | /// 22 | /// Start position of non-leading samples. 23 | /// 24 | public double positionMs; 25 | 26 | /// 27 | /// Length estimated before actual render. 28 | /// 29 | public double estimatedLengthMs; 30 | } 31 | 32 | public class RenderPitchResult { 33 | public float[] ticks; 34 | public float[] tones; 35 | } 36 | 37 | /// 38 | /// Interface of phrase-based renderer. 39 | /// 40 | public interface IRenderer { 41 | USingerType SingerType { get; } 42 | bool SupportsRenderPitch { get; } 43 | bool SupportsExpression(UExpressionDescriptor descriptor); 44 | RenderResult Layout(RenderPhrase phrase); 45 | Task Render(RenderPhrase phrase, Progress progress, CancellationTokenSource cancellation, bool isPreRender = false); 46 | RenderPitchResult LoadRenderedPitch(RenderPhrase phrase); 47 | UExpressionDescriptor[] GetSuggestedExpressions(USinger singer, URenderSettings renderSettings); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /OpenUtau.Core/SignalChain/ExportAdapter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NAudio.Wave; 3 | 4 | namespace OpenUtau.Core.SignalChain { 5 | class ExportAdapter : ISampleProvider { 6 | private readonly WaveFormat waveFormat; 7 | private readonly ISignalSource source; 8 | private int position; 9 | 10 | public WaveFormat WaveFormat => waveFormat; 11 | 12 | public ExportAdapter(ISignalSource source) { 13 | waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(44100, 2); 14 | this.source = source; 15 | } 16 | 17 | public int Read(float[] buffer, int offset, int count) { 18 | for (int i = offset; i < offset + count; ++i) { 19 | buffer[i] = 0; 20 | } 21 | if (!source.IsReady(position, count)) { 22 | throw new Exception("All sources must be ready when exporting."); 23 | } else { 24 | int pos = source.Mix(position, buffer, offset, count); 25 | int n = Math.Max(0, pos - position); 26 | position = pos; 27 | return n; 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /OpenUtau.Core/SignalChain/Fader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace OpenUtau.Core.SignalChain { 4 | public class Fader : ISignalSource { 5 | private readonly ISignalSource source; 6 | private float pan = 1; 7 | private float scale = 1; 8 | private float scaleTarget = 1; 9 | private float[] scaleBuffer; 10 | 11 | public Fader(ISignalSource source) { 12 | this.source = source; 13 | } 14 | 15 | public float Scale { 16 | get => scaleTarget; 17 | set => scaleTarget = value; 18 | } 19 | 20 | public float Pan { 21 | get => pan; 22 | set => pan = value; 23 | } 24 | 25 | public void SetScaleToTarget() { 26 | scale = scaleTarget; 27 | } 28 | 29 | public bool IsReady(int position, int count) { 30 | return source.IsReady(position, count); 31 | } 32 | 33 | public int Mix(int position, float[] buffer, int index, int count) { 34 | if (scaleBuffer == null || scaleBuffer.Length < count) { 35 | scaleBuffer = new float[count]; 36 | } 37 | for (int i = 0; i < count; ++i) { 38 | scaleBuffer[i] = 0; 39 | } 40 | (float volumeLeft, float volumeRight) = MusicMath.PanToChannelVolumes(pan); 41 | int ret = source.Mix(position, scaleBuffer, 0, count); 42 | for (int i = 0; i < count; ++i) { 43 | if (scaleTarget > scale) { 44 | scale = Math.Min(scaleTarget, scale + 0.0005f); 45 | } else if (scaleTarget < scale) { 46 | scale = Math.Max(scaleTarget, scale - 0.0005f); 47 | } 48 | buffer[index + i] += scaleBuffer[i] * scale * (i % 2 == 0 ? volumeLeft : volumeRight); 49 | } 50 | return ret; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /OpenUtau.Core/SignalChain/ISignalSource.cs: -------------------------------------------------------------------------------- 1 | namespace OpenUtau.Core.SignalChain { 2 | public interface ISignalSource { 3 | bool IsReady(int position, int count); 4 | /// 5 | /// Add float audio samples to existing buffer values. 6 | /// 7 | /// 8 | /// 9 | /// 10 | /// 11 | /// End position after read. 12 | int Mix(int position, float[] buffer, int index, int count); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /OpenUtau.Core/SignalChain/MasterAdapter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NAudio.Wave; 3 | 4 | namespace OpenUtau.Core.SignalChain { 5 | class MasterAdapter : ISampleProvider { 6 | private readonly WaveFormat waveFormat; 7 | private readonly ISignalSource source; 8 | private int position; 9 | 10 | public WaveFormat WaveFormat => waveFormat; 11 | public int Waited { get; private set; } 12 | public bool IsWaiting { get; private set; } 13 | public MasterAdapter(ISignalSource source) { 14 | waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(44100, 2); 15 | this.source = source; 16 | } 17 | 18 | public int Read(float[] buffer, int offset, int count) { 19 | for (int i = offset; i < offset + count; ++i) { 20 | buffer[i] = 0; 21 | } 22 | if (!source.IsReady(position, count)) { 23 | Waited += count; 24 | IsWaiting = true; 25 | return count; 26 | } else { 27 | int pos = source.Mix(position, buffer, offset, count); 28 | int n = Math.Max(0, pos - position); 29 | position = pos; 30 | IsWaiting = false; 31 | return n; 32 | } 33 | } 34 | 35 | public void SetPosition(int position) { 36 | this.position = position; 37 | Waited = 0; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /OpenUtau.Core/SignalChain/WaveMix.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace OpenUtau.Core.SignalChain { 5 | public class WaveMix : ISignalSource { 6 | private readonly List sources; 7 | 8 | public WaveMix(IEnumerable sources) { 9 | this.sources = sources.ToList(); 10 | } 11 | 12 | public bool IsReady(int position, int count) { 13 | return sources.Count == 0 || sources.All(source => source.IsReady(position, count)); 14 | } 15 | 16 | public int Mix(int position, float[] buffer, int index, int count) { 17 | if (sources.Count == 0) { 18 | return 0; 19 | } 20 | return sources.Max(source => source.Mix(position, buffer, index, count)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /OpenUtau.Core/SignalChain/WaveSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace OpenUtau.Core.SignalChain { 4 | public class WaveSource : ISignalSource { 5 | public readonly double offsetMs; 6 | public readonly double estimatedLengthMs; 7 | public readonly int offset; 8 | public readonly int estimatedLength; 9 | public readonly int channels; 10 | 11 | public double EndMs => offsetMs + estimatedLengthMs; 12 | public bool HasSamples => data != null; 13 | 14 | private readonly object lockObj = new object(); 15 | private float[] data; 16 | 17 | public WaveSource(double offsetMs, double estimatedLengthMs, double skipOverMs, int channels) { 18 | this.offsetMs = offsetMs; 19 | this.estimatedLengthMs = estimatedLengthMs; 20 | this.channels = channels; 21 | offset = (int)((offsetMs - skipOverMs) * 44100 / 1000) * channels; 22 | estimatedLength = (int)(estimatedLengthMs * 44100 / 1000) * channels; 23 | } 24 | 25 | public void SetSamples(float[] samples) { 26 | lock (lockObj) { 27 | data = samples; 28 | } 29 | } 30 | 31 | public bool IsReady(int position, int count) { 32 | int copies = 2 / channels; 33 | return position + count <= offset * copies 34 | || offset * copies + estimatedLength * copies <= position 35 | || data != null; 36 | } 37 | 38 | public int Mix(int position, float[] buffer, int index, int count) { 39 | int copies = 2 / channels; 40 | if (data == null) { 41 | if (position + count <= offset * copies) { 42 | return position + count; 43 | } 44 | return position; 45 | } 46 | int start = Math.Max(position, offset * copies); 47 | int end = Math.Min(position + count, offset * copies + data.Length * copies); 48 | for (int i = start; i < end; ++i) { 49 | buffer[index + i - position] += data[i / copies - offset]; 50 | } 51 | return end; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /OpenUtau.Core/Util/Base64.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | 4 | namespace OpenUtau.Core.Util 5 | { 6 | internal static class Base64 7 | { 8 | public static string Base64EncodeInt12(int[] data) 9 | { 10 | List l = new List(); 11 | foreach (int d in data) 12 | { 13 | l.Add(Base64EncodeInt12(d)); 14 | } 15 | 16 | StringBuilder base64 = new StringBuilder(); 17 | string last = string.Empty; 18 | int dups = 0; 19 | foreach (string b in l) 20 | { 21 | if (last == b) 22 | { 23 | dups++; 24 | } 25 | else if (dups == 0) 26 | { 27 | base64.Append(b); 28 | } 29 | else 30 | { 31 | base64.Append('#'); 32 | base64.Append(dups + 1); 33 | base64.Append('#'); 34 | dups = 0; 35 | base64.Append(b); 36 | } 37 | last = b; 38 | } 39 | if (dups != 0) 40 | { 41 | base64.Append('#'); 42 | base64.Append(dups + 1); 43 | base64.Append('#'); 44 | } 45 | return base64.ToString(); 46 | } 47 | 48 | private const string intToBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 49 | 50 | private static string Base64EncodeInt12(int data) 51 | { 52 | if (data < 0) 53 | { 54 | data += 4096; 55 | } 56 | 57 | char[] base64 = new char[2]; 58 | base64[0] = intToBase64[(data >> 6) & 0x003F]; 59 | base64[1] = intToBase64[data & 0x003F]; 60 | return new string(base64); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /OpenUtau.Core/Util/LocalizedSort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace OpenUtau.Core.Util { 8 | 9 | public class LocalizedComparer : IComparer { 10 | CultureInfo cultureInfo; 11 | public LocalizedComparer(CultureInfo cultureInfo) { 12 | this.cultureInfo = cultureInfo; 13 | } 14 | 15 | public int Compare(string x, string y) { 16 | return cultureInfo.CompareInfo.Compare(x, y); 17 | } 18 | } 19 | public static class LocalizedSort { 20 | public static IEnumerable LocalizedOrderBy(this IEnumerable source, Func selector) { 21 | var sortingOrder = Preferences.Default.SortingOrder; 22 | if(sortingOrder == String.Empty) { 23 | sortingOrder = Preferences.Default.Language; 24 | } 25 | var comparer = new LocalizedComparer(CultureInfo.GetCultureInfo(sortingOrder)); 26 | return source.OrderBy(selector, comparer); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /OpenUtau.Core/Util/SingletonBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace OpenUtau.Core.Util { 4 | public abstract class SingletonBase where T : class { 5 | private static readonly Lazy inst = new Lazy( 6 | () => (T)Activator.CreateInstance(typeof(T), true), 7 | isThreadSafe: true); 8 | public static T Inst => inst.Value; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /OpenUtau.Core/Util/Yaml.cs: -------------------------------------------------------------------------------- 1 | using OpenUtau.Classic; 2 | using OpenUtau.Core.Ustx; 3 | using YamlDotNet.Core; 4 | using YamlDotNet.Core.Events; 5 | using YamlDotNet.Serialization; 6 | using YamlDotNet.Serialization.EventEmitters; 7 | using YamlDotNet.Serialization.NamingConventions; 8 | 9 | namespace OpenUtau.Core { 10 | public static class Yaml { 11 | public static ISerializer DefaultSerializer = new SerializerBuilder() 12 | .WithNamingConvention(UnderscoredNamingConvention.Instance) 13 | .ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitNull) 14 | .WithEventEmitter(next => new FlowEmitter(next)) 15 | .DisableAliases() 16 | .WithQuotingNecessaryStrings() 17 | .Build(); 18 | 19 | public static IDeserializer DefaultDeserializer = new DeserializerBuilder() 20 | .WithNamingConvention(UnderscoredNamingConvention.Instance) 21 | .IgnoreUnmatchedProperties() 22 | .Build(); 23 | } 24 | 25 | public class FlowEmitter : ChainedEventEmitter { 26 | public FlowEmitter(IEventEmitter nextEmitter) : base(nextEmitter) { } 27 | public override void Emit(MappingStartEventInfo eventInfo, IEmitter emitter) { 28 | if (eventInfo.Source.Type == typeof(PitchPoint) || 29 | eventInfo.Source.Type == typeof(UVibrato) || 30 | eventInfo.Source.Type == typeof(UExpression)) { 31 | eventInfo.Style = MappingStyle.Flow; 32 | } 33 | base.Emit(eventInfo, emitter); 34 | } 35 | public override void Emit(SequenceStartEventInfo eventInfo, IEmitter emitter) { 36 | base.Emit(eventInfo, emitter); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /OpenUtau.Core/Util/Zip.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Text; 5 | using SharpCompress.Archives; 6 | 7 | namespace OpenUtau.Core.Util { 8 | public static class Zip { 9 | public static string[] ExtractText(byte[] data, string key) { 10 | using var stream = new MemoryStream(data); 11 | using var archive = ArchiveFactory.Open(stream); 12 | return ExtractText(archive, key); 13 | } 14 | 15 | public static string[] ExtractText(string path, string key) { 16 | using var stream = File.OpenRead(path); 17 | using var archive = ArchiveFactory.Open(stream); 18 | return ExtractText(archive, key); 19 | } 20 | 21 | public static string[] ExtractText(IArchive archive, string key) { 22 | var entry = archive.Entries.FirstOrDefault(e => e.Key == key); 23 | if (entry == null) { 24 | return null; 25 | } 26 | using var stream = entry.OpenEntryStream(); 27 | using var reader = new StreamReader(stream, Encoding.UTF8); 28 | var lines = new List(); 29 | while (!reader.EndOfStream) { 30 | lines.Add(reader.ReadLine()); 31 | } 32 | return lines.ToArray(); 33 | } 34 | 35 | public static byte[] ExtractBytes(byte[] data, string key) { 36 | using var stream = new MemoryStream(data); 37 | using var archive = ArchiveFactory.Open(stream); 38 | return ExtractBytes(archive, key); 39 | } 40 | 41 | public static byte[] ExtractBytes(string path, string key) { 42 | using var stream = File.OpenRead(path); 43 | using var archive = ArchiveFactory.Open(stream); 44 | return ExtractBytes(archive, key); 45 | } 46 | 47 | public static byte[] ExtractBytes(IArchive archive, string key) { 48 | var entry = archive.Entries.FirstOrDefault(e => e.Key == key); 49 | if (entry == null) { 50 | return null; 51 | } 52 | using var entryStream = entry.OpenEntryStream(); 53 | using var memStream = new MemoryStream(); 54 | entryStream.CopyTo(memStream); 55 | return memStream.ToArray(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /OpenUtau.Core/Vogen/Data/f0.man.onnx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Core/Vogen/Data/f0.man.onnx -------------------------------------------------------------------------------- /OpenUtau.Core/Vogen/Data/f0.yue.onnx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Core/Vogen/Data/f0.yue.onnx -------------------------------------------------------------------------------- /OpenUtau.Core/Vogen/Data/g2p.man.onnx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Core/Vogen/Data/g2p.man.onnx -------------------------------------------------------------------------------- /OpenUtau.Core/Vogen/Data/g2p.yue.onnx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Core/Vogen/Data/g2p.yue.onnx -------------------------------------------------------------------------------- /OpenUtau.Core/Vogen/Data/po.man.onnx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Core/Vogen/Data/po.man.onnx -------------------------------------------------------------------------------- /OpenUtau.Core/Vogen/Data/po.yue.onnx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Core/Vogen/Data/po.yue.onnx -------------------------------------------------------------------------------- /OpenUtau.Core/Vogen/TrieNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | 6 | namespace OpenUtau.Core.Vogen { 7 | class TrieNode { 8 | public Dictionary children = new Dictionary(); 9 | public string[]? pinyins = null; 10 | 11 | public static TrieNode LoadDictionary(IEnumerable lines) { 12 | TrieNode root = new TrieNode(); 13 | foreach (var line in lines.Skip(1).Reverse()) { 14 | var parts = line.Trim().Split(','); 15 | if (parts.Length >= 2) { 16 | var etor = StringInfo.GetTextElementEnumerator(parts[0]); 17 | BuildTrie(root, etor, parts[1]); 18 | } 19 | } 20 | return root; 21 | } 22 | 23 | private static void BuildTrie(TrieNode node, TextElementEnumerator etor, string pinyin) { 24 | if (!etor.MoveNext()) { 25 | node.pinyins = pinyin.Split(); 26 | return; 27 | } 28 | string hanzi = etor.GetTextElement(); 29 | if (!node.children.TryGetValue(hanzi, out var child)) { 30 | node.children[hanzi] = child = new TrieNode(); 31 | } 32 | BuildTrie(child, etor, pinyin); 33 | } 34 | 35 | public string[]? Query(Span text) { 36 | string[]? pinyins = null; 37 | int index = 0; 38 | TrieNode node = this; 39 | while (index < text.Length && node.children.TryGetValue(text[index], out var child)) { 40 | if (child.pinyins != null) { 41 | pinyins = child.pinyins; 42 | } 43 | node = child; 44 | index++; 45 | } 46 | return pinyins; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /OpenUtau.Core/Vogen/VogenMandarinPhonemizer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.ML.OnnxRuntime; 2 | using OpenUtau.Api; 3 | using TinyPinyin; 4 | 5 | namespace OpenUtau.Core.Vogen { 6 | [Phonemizer("Vogen Chinese Mandarin Phonemizer", "VOGEN ZH", language: "ZH")] 7 | public class VogenMandarinPhonemizer : VogenBasePhonemizer { 8 | private static InferenceSession? g2p; 9 | private static InferenceSession? prosody; 10 | 11 | public VogenMandarinPhonemizer() { 12 | g2p ??= new InferenceSession(Data.VogenRes.g2p_man); 13 | G2p = g2p; 14 | prosody ??= new InferenceSession(Data.VogenRes.po_man); 15 | Prosody = prosody; 16 | } 17 | protected override string LangPrefix => "man:"; 18 | 19 | protected override string[] Romanize(string[] lyrics) { 20 | return BaseChinesePhonemizer.Romanize(lyrics); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /OpenUtau.Core/Vogen/VogenSinger.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Text; 4 | using OpenUtau.Core.Ustx; 5 | using OpenUtau.Core.Util; 6 | 7 | namespace OpenUtau.Core.Vogen { 8 | class VogenSinger : USinger { 9 | public override string Id => meta.id; 10 | public override string Name => meta.name; 11 | public override USingerType SingerType => USingerType.Vogen; 12 | public override string BasePath => basePath; 13 | public override string Author => meta.builtBy; 14 | public override string Voice => meta.voiceBy; 15 | public override string Location => filePath; 16 | public override string Web => meta.web; 17 | public override string Version => meta.version; 18 | public override string OtherInfo => meta.misc; 19 | public override IList Errors => errors; 20 | public override string Avatar => meta.avatar; 21 | public override byte[] AvatarData => avatarData; 22 | public override string Portrait => meta.portrait; 23 | public override float PortraitOpacity => meta.portraitOpacity; 24 | public override string DefaultPhonemizer => "OpenUtau.Core.Vogen.VogenMandarinPhonemizer"; 25 | public override Encoding TextFileEncoding => Encoding.UTF8; 26 | public override IList Subbanks => subbanks; 27 | 28 | string basePath; 29 | string filePath; 30 | VogenMeta meta; 31 | List errors = new List(); 32 | List subbanks = new List(); 33 | 34 | public byte[] model; 35 | public byte[] avatarData; 36 | 37 | public VogenSinger(string filePath, VogenMeta meta, byte[] model, byte[] avatar) { 38 | basePath = Path.GetDirectoryName(filePath); 39 | this.filePath = filePath; 40 | this.meta = meta; 41 | this.model = model; 42 | this.avatarData = avatar; 43 | found = true; 44 | loaded = true; 45 | } 46 | 47 | public override bool TryGetOto(string phoneme, out UOto oto) { 48 | oto = UOto.OfDummy(phoneme); 49 | return true; 50 | } 51 | 52 | public override byte[] LoadPortrait() { 53 | return string.IsNullOrEmpty(meta.portrait) 54 | ? null 55 | : Zip.ExtractBytes(filePath, meta.portrait); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /OpenUtau.Core/Vogen/VogenSingerInstaller.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Threading.Tasks; 3 | 4 | namespace OpenUtau.Core.Vogen { 5 | public class VogenSingerInstaller { 6 | public const string FileExt = ".vogeon"; 7 | public static void Install(string filePath) { 8 | string fileName = Path.GetFileName(filePath); 9 | string destName = Path.Combine(PathManager.Inst.SingersInstallPath, fileName); 10 | if (File.Exists(destName)) { 11 | DocManager.Inst.ExecuteCmd(new ErrorMessageNotification($"{destName} already exist!")); 12 | return; 13 | } 14 | File.Copy(filePath, destName); 15 | new Task(() => { 16 | DocManager.Inst.ExecuteCmd(new SingersChangedNotification()); 17 | DocManager.Inst.ExecuteCmd(new ProgressBarNotification(0, $"Installed {fileName}")); 18 | }).Start(DocManager.Inst.MainScheduler); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /OpenUtau.Core/Vogen/VogenYuePhonemizer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.ML.OnnxRuntime; 2 | using OpenUtau.Api; 3 | using System; 4 | 5 | namespace OpenUtau.Core.Vogen { 6 | [Phonemizer("Vogen Chinese Yue Phonemizer", "VOGEN ZH-YUE", language: "ZH")] 7 | public class VogenYuePhonemizer : VogenBasePhonemizer { 8 | private static TrieNode? trie; 9 | private static InferenceSession? g2p; 10 | private static InferenceSession? prosody; 11 | 12 | public VogenYuePhonemizer() { 13 | trie ??= TrieNode.LoadDictionary( 14 | Data.VogenRes.yue 15 | .Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.None)); 16 | g2p ??= new InferenceSession(Data.VogenRes.g2p_yue); 17 | G2p = g2p; 18 | prosody ??= new InferenceSession(Data.VogenRes.po_yue); 19 | Prosody = prosody; 20 | } 21 | 22 | protected override string LangPrefix => "yue:"; 23 | 24 | protected override string[] Romanize(string[] lyrics) { 25 | var result = new string[lyrics.Length]; 26 | int index = 0; 27 | while (index < lyrics.Length) { 28 | string[]? romanized = trie!.Query(new Span(lyrics, index, lyrics.Length - index)); 29 | if (romanized == null) { 30 | result[index] = lyrics[index]; 31 | index++; 32 | } else { 33 | Array.Copy(romanized, 0, result, index, romanized.Length); 34 | index += romanized.Length; 35 | } 36 | } 37 | return result; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /OpenUtau.Plugin.Builtin/Data/arpasing.template.yaml: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | symbols: 4 | - {symbol: aa, type: vowel} 5 | - {symbol: ae, type: vowel} 6 | - {symbol: ah, type: vowel} 7 | - {symbol: ao, type: vowel} 8 | - {symbol: aw, type: vowel} 9 | - {symbol: ay, type: vowel} 10 | - {symbol: b, type: stop} 11 | - {symbol: ch, type: affricate} 12 | - {symbol: d, type: stop} 13 | - {symbol: dh, type: fricative} 14 | - {symbol: eh, type: vowel} 15 | - {symbol: er, type: vowel} 16 | - {symbol: ey, type: vowel} 17 | - {symbol: f, type: fricative} 18 | - {symbol: g, type: stop} 19 | - {symbol: hh, type: aspirate} 20 | - {symbol: ih, type: vowel} 21 | - {symbol: iy, type: vowel} 22 | - {symbol: jh, type: affricate} 23 | - {symbol: k, type: stop} 24 | - {symbol: l, type: liquid} 25 | - {symbol: m, type: nasal} 26 | - {symbol: n, type: nasal} 27 | - {symbol: ng, type: nasal} 28 | - {symbol: ow, type: vowel} 29 | - {symbol: oy, type: vowel} 30 | - {symbol: p, type: stop} 31 | - {symbol: r, type: liquid} 32 | - {symbol: s, type: fricative} 33 | - {symbol: sh, type: fricative} 34 | - {symbol: t, type: stop} 35 | - {symbol: th, type: fricative} 36 | - {symbol: uh, type: vowel} 37 | - {symbol: uw, type: vowel} 38 | - {symbol: v, type: fricative} 39 | - {symbol: w, type: semivowel} 40 | - {symbol: y, type: semivowel} 41 | - {symbol: z, type: fricative} 42 | - {symbol: zh, type: fricative} 43 | entries: 44 | - grapheme: openutau 45 | phonemes: [ow, p, eh, n, w, uw, t, ah, w, uw] 46 | -------------------------------------------------------------------------------- /OpenUtau.Plugin.Builtin/Data/envccv.template.yaml: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | symbols: 4 | #CZsampa standard vowels 5 | - {symbol: '@', type: vowel} 6 | - {symbol: a, type: vowel} 7 | - {symbol: i, type: vowel} 8 | - {symbol: u, type: vowel} 9 | - {symbol: e, type: vowel} 10 | - {symbol: o, type: vowel} 11 | - {symbol: A, type: vowel} 12 | - {symbol: I, type: vowel} 13 | - {symbol: E, type: vowel} 14 | - {symbol: O, type: vowel} 15 | - {symbol: 0, type: vowel} 16 | - {symbol: 3, type: vowel} 17 | - {symbol: 6, type: vowel} 18 | - {symbol: 8, type: vowel} 19 | - {symbol: Q, type: vowel} 20 | - {symbol: h, type: aspirate} 21 | - {symbol: j, type: affricate} 22 | #Arpasing 23 | - {symbol: aa, type: vowel} 24 | - {symbol: ae, type: vowel} 25 | - {symbol: ah, type: vowel} 26 | - {symbol: ao, type: vowel} 27 | - {symbol: aw, type: vowel} 28 | - {symbol: ay, type: vowel} 29 | - {symbol: b, type: stop} 30 | - {symbol: ch, type: affricate} 31 | - {symbol: d, type: stop} 32 | - {symbol: dh, type: fricative} 33 | - {symbol: eh, type: vowel} 34 | - {symbol: er, type: vowel} 35 | - {symbol: ey, type: vowel} 36 | - {symbol: f, type: fricative} 37 | - {symbol: g, type: stop} 38 | - {symbol: hh, type: aspirate} 39 | - {symbol: ih, type: vowel} 40 | - {symbol: iy, type: vowel} 41 | - {symbol: jh, type: affricate} 42 | - {symbol: k, type: stop} 43 | - {symbol: l, type: liquid} 44 | - {symbol: m, type: nasal} 45 | - {symbol: n, type: nasal} 46 | - {symbol: ng, type: nasal} 47 | - {symbol: ow, type: vowel} 48 | - {symbol: oy, type: vowel} 49 | - {symbol: p, type: stop} 50 | - {symbol: r, type: liquid} 51 | - {symbol: s, type: fricative} 52 | - {symbol: sh, type: fricative} 53 | - {symbol: t, type: stop} 54 | - {symbol: th, type: fricative} 55 | - {symbol: uh, type: vowel} 56 | - {symbol: uw, type: vowel} 57 | - {symbol: v, type: fricative} 58 | - {symbol: w, type: semivowel} 59 | - {symbol: y, type: semivowel} 60 | - {symbol: z, type: fricative} 61 | - {symbol: zh, type: fricative} 62 | #bonus symbols 63 | - {symbol: '&', type: vowel} 64 | - {symbol: 1, type: vowel} 65 | - {symbol: 9, type: vowel} 66 | - {symbol: x, type: vowel} 67 | - {symbol: dd, type: tap} 68 | 69 | entries: 70 | - grapheme: openutau 71 | phonemes: [ow, p, eh, n, w, uw, t, ah, w, uw] 72 | - grapheme: vccv 73 | phonemes: [v, E, s, E, s, E, v, E] 74 | - grapheme: "VCCV" 75 | phonemes: [v, E, s, E, s, E, v, E] 76 | -------------------------------------------------------------------------------- /OpenUtau.Plugin.Builtin/EnunuOnnx/EnunuConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Text; 4 | using OpenUtau.Core; 5 | 6 | //Instead of using Enunu/EnunuConfig.cs, we created a copy to add EnunuOnnx-specific features 7 | //without potentially breaking the existing Enunu Phonemizers and renderers. 8 | namespace OpenUtau.Plugin.Builtin.EnunuOnnx { 9 | class EnunuConfig { 10 | public string tablePath; 11 | public string questionPath; 12 | public int sampleRate; 13 | public double framePeriod; 14 | public string modelDir; 15 | public string statsDir; 16 | public EnunuDurationConfig duration; 17 | public EnunuTimelagConfig timelag; 18 | 19 | public static EnunuConfig Load(string configPath, Encoding encoding = null) { 20 | encoding = encoding ?? Encoding.UTF8; 21 | var configTxt = File.ReadAllText(configPath,encoding); 22 | RawEnunuConfig config = Yaml.DefaultDeserializer.Deserialize(configTxt); 23 | return config.Convert(); 24 | } 25 | } 26 | 27 | 28 | class EnunuTimelagConfig { 29 | public string checkpoint; 30 | public List allowedRange; 31 | public List allowedRangeRest; 32 | } 33 | class EnunuDurationConfig { 34 | public string checkpoint; 35 | 36 | } 37 | 38 | class RawEnunuConfig { 39 | public string tablePath; 40 | public string questionPath; 41 | public int sampleRate; 42 | public double framePeriod; 43 | public string modelDir; 44 | public string statsDir; 45 | public EnunuDurationConfig duration; 46 | public EnunuTimelagConfig timelag; 47 | 48 | public EnunuConfig Convert() { 49 | EnunuConfig enunuConfig = new EnunuConfig(); 50 | enunuConfig.tablePath = this.tablePath; 51 | enunuConfig.questionPath = this.questionPath; 52 | enunuConfig.sampleRate = this.sampleRate; 53 | enunuConfig.framePeriod = this.framePeriod; 54 | enunuConfig.duration = this.duration; 55 | enunuConfig.modelDir = this.modelDir; 56 | enunuConfig.statsDir = this.statsDir; 57 | enunuConfig.timelag = this.timelag; 58 | return enunuConfig; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /OpenUtau.Plugin.Builtin/EnunuOnnx/EnunuOnnxEnglishPhonemizer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using OpenUtau.Api; 6 | using OpenUtau.Core.G2p; 7 | using Serilog; 8 | 9 | namespace OpenUtau.Plugin.Builtin { 10 | [Phonemizer("Enunu Onnx English Phonemizer", "ENUNU X EN", language:"EN")] 11 | public class EnunuOnnxEnglishPhonemizer : EnunuOnnxPhonemizer { 12 | protected override IG2p LoadG2p(string rootPath) { 13 | var g2ps = new List(); 14 | 15 | // Load dictionary from singer folder. 16 | string file = Path.Combine(rootPath, "enunux.yaml"); 17 | if (File.Exists(file)) { 18 | try { 19 | g2ps.Add(G2pDictionary.NewBuilder().Load(File.ReadAllText(file)).Build()); 20 | } catch (Exception e) { 21 | Log.Error(e, $"Failed to load {file}"); 22 | } 23 | } 24 | g2ps.Add(new ArpabetG2p()); 25 | return new G2pFallbacks(g2ps.ToArray()); 26 | } 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /OpenUtau.Plugin.Builtin/EnunuOnnx/Python.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace OpenUtau.Plugin.Builtin.EnunuOnnx.nnmnkwii.python { 5 | public class AssertionError : Exception { 6 | 7 | public AssertionError() : base() { } 8 | 9 | public AssertionError(string message) : base(message) { 10 | } 11 | 12 | public AssertionError(string message, Exception innerException) 13 | : base(message, innerException) { 14 | } 15 | } 16 | 17 | public static class PythonAssert { 18 | public static void Assert(bool expression) { 19 | if (!expression) { 20 | throw new AssertionError(); 21 | } 22 | } 23 | 24 | public static void Assert(bool expression, string message) { 25 | if (!expression) { 26 | throw new AssertionError(message); 27 | } 28 | } 29 | } 30 | 31 | //python string methods that C# doesn't have 32 | public static class PythonString { 33 | //python "".split() without parameter 34 | public static string[] split(string str) { 35 | return Regex.Split(str, @" +"); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /OpenUtau.Plugin.Builtin/FrenchCMUSphinxPhonemizer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using OpenUtau.Api; 5 | using OpenUtau.Core.G2p; 6 | using Serilog; 7 | 8 | namespace OpenUtau.Plugin.Builtin { 9 | /// 10 | /// A French diphone phonemizer that uses CMUSphinx dictionary. 11 | /// 12 | [Phonemizer("French CMUSphinx Phonemizer", "FR SPHINX", language:"FR")] 13 | public class FrenchCMUSphinxPhonemizer : LatinDiphonePhonemizer { 14 | public FrenchCMUSphinxPhonemizer() { 15 | try { 16 | Initialize(); 17 | } catch (Exception e) { 18 | Log.Error(e, "Failed to initialize."); 19 | } 20 | } 21 | 22 | protected override IG2p LoadG2p() { 23 | var g2ps = new List(); 24 | 25 | // Load dictionary from plugin folder. 26 | string path = Path.Combine(PluginDir, "french.yaml"); 27 | if (File.Exists(path)) { 28 | try { 29 | g2ps.Add(G2pDictionary.NewBuilder().Load(File.ReadAllText(path)).Build()); 30 | } catch (Exception e) { 31 | Log.Error(e, $"Failed to load {path}"); 32 | } 33 | } 34 | 35 | // Load dictionary from singer folder. 36 | if (singer != null && singer.Found && singer.Loaded) { 37 | string file = Path.Combine(singer.Location, "french.yaml"); 38 | if (File.Exists(file)) { 39 | try { 40 | g2ps.Add(G2pDictionary.NewBuilder().Load(File.ReadAllText(file)).Build()); 41 | } catch (Exception e) { 42 | Log.Error(e, $"Failed to load {file}"); 43 | } 44 | } 45 | } 46 | 47 | // Load base g2p. 48 | g2ps.Add(new FrenchG2p()); 49 | 50 | return new G2pFallbacks(g2ps.ToArray()); 51 | } 52 | 53 | protected override Dictionary LoadVowelFallbacks() { 54 | return new Dictionary(); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /OpenUtau.Plugin.Builtin/OpenUtau.Plugin.Builtin.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.1 5 | none 6 | embedded 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | True 17 | True 18 | Resources.resx 19 | 20 | 21 | 22 | 23 | 24 | ResXFileCodeGenerator 25 | Resources.Designer.cs 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /OpenUtau.Test/App/AppTest.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace OpenUtau.App { 4 | public class AppTest { 5 | [Fact] 6 | public void BuildTest() { 7 | Assert.False(typeof(OpenUtau.App.App).IsAbstract); 8 | Assert.False(typeof(OpenUtau.App.Program).IsAbstract); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /OpenUtau.Test/Classic/VoicebankLoaderTest.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace OpenUtau.Classic { 7 | public class VoicebankLoaderTest { 8 | readonly ITestOutputHelper output; 9 | 10 | public VoicebankLoaderTest(ITestOutputHelper output) { 11 | this.output = output; 12 | } 13 | 14 | [Fact] 15 | public void OtoSetRoundTrip() { 16 | string text = @"a.wav=,,,,, 17 | a.wav=- a, 18 | a.wav=a R,500,,, 19 | !@#$!@#$ 20 | aoieu.wav=- a,,,,,,,,, 21 | 22 | aoieu.wav=a o,, 23 | aoieu.wav=o i,,, 24 | aoieu.wav=i e,,100,150,,, 25 | aoieu.wav=e u,20, 26 | aoieu.wav=u R,5,,33,44,, 27 | ".Replace("\r\n", "\n"); 28 | string expected = @"a.wav=,,,,, 29 | a.wav=- a,,,,, 30 | a.wav=a R,500,,,, 31 | !@#$!@#$ 32 | aoieu.wav=- a,,,,, 33 | 34 | aoieu.wav=a o,,,,, 35 | aoieu.wav=o i,,,,, 36 | aoieu.wav=i e,,100,150,, 37 | aoieu.wav=e u,20,,,, 38 | aoieu.wav=u R,5,,33,44, 39 | ".Replace("\r\n", "\n"); 40 | 41 | using (MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(text))) { 42 | var otoSet = VoicebankLoader.ParseOtoSet(stream, "oto.ini", Encoding.ASCII); 43 | using (MemoryStream stream2 = new MemoryStream()) { 44 | VoicebankLoader.WriteOtoSet(otoSet, stream2, Encoding.ASCII); 45 | string actual = Encoding.ASCII.GetString(stream2.ToArray()); 46 | Assert.Equal(expected, actual); 47 | } 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /OpenUtau.Test/Core/G2p/G2pTest.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Xunit.Abstractions; 3 | 4 | namespace OpenUtau.Core.G2p { 5 | public class G2pTest { 6 | readonly ITestOutputHelper output; 7 | 8 | public G2pTest(ITestOutputHelper output) { 9 | this.output = output; 10 | } 11 | 12 | [Fact] 13 | public void ArpabetG2pTest() { 14 | var g2p = new ArpabetG2p(); 15 | Assert.Null(g2p.Query("")); 16 | Assert.Null(g2p.Query(",")); 17 | Assert.Null(g2p.Query("-")); 18 | Assert.Equal("v ow k ah l", string.Join(' ', g2p.Query("vocal"))); 19 | Assert.Equal("v ow k ah l", string.Join(' ', g2p.Query("%v,oca l"))); 20 | Assert.Equal("v uw ow", string.Join(' ', g2p.Query("voooo"))); 21 | Assert.Equal("m iy", string.Join(' ', g2p.Query("meeee"))); 22 | } 23 | 24 | [Fact] 25 | public void RussianG2pTest() { 26 | var g2p = new RussianG2p(); 27 | Assert.Null(g2p.Query("")); 28 | Assert.Null(g2p.Query(",")); 29 | Assert.Null(g2p.Query("-")); 30 | Assert.Equal("nn i vv je zh d ay", string.Join(' ', g2p.Query("невежда"))); 31 | Assert.Equal("nn i vv je zh d ay", string.Join(' ', g2p.Query("?нев,.еж да "))); 32 | Assert.Equal("nn i nn i nn i nn i", string.Join(' ', g2p.Query("нененене"))); 33 | Assert.Equal("d ay d ay d a d aa", string.Join(' ', g2p.Query("дададада"))); 34 | } 35 | 36 | [Fact] 37 | public void PortugueseG2pTest() { 38 | var g2p = new PortugueseG2p(); 39 | Assert.Null(g2p.Query("")); 40 | Assert.Null(g2p.Query(",")); 41 | Assert.Null(g2p.Query("-")); 42 | Assert.Equal("i~ v e R n e s", string.Join(' ', g2p.Query("inverness"))); 43 | Assert.Equal("i~ v e R n e s", string.Join(' ', g2p.Query("inve rn,.ess"))); 44 | Assert.Equal("p i r i m i tS i", string.Join(' ', g2p.Query("pírímítí"))); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /OpenUtau.Test/Core/Util/MusicMathTest.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Xunit.Abstractions; 3 | 4 | namespace OpenUtau.Core.Util { 5 | public class MusicMathTest { 6 | readonly ITestOutputHelper output; 7 | 8 | public MusicMathTest(ITestOutputHelper output) { 9 | this.output = output; 10 | } 11 | 12 | [Fact] 13 | public void ToneNameTest() { 14 | for (int i = 24; i < 108; ++i) { 15 | string name = MusicMath.GetToneName(i); 16 | int tone = MusicMath.NameToTone(name); 17 | output.WriteLine($"{i} -> {name} -> {tone}"); 18 | Assert.Equal(i, tone); 19 | } 20 | Assert.Equal("C1", MusicMath.GetToneName(24)); 21 | Assert.Equal("B7", MusicMath.GetToneName(107)); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /OpenUtau.Test/Core/Util/SplitLyricsTest.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Xunit.Abstractions; 3 | 4 | namespace OpenUtau.Core.Util { 5 | public class SplitLyricsTest { 6 | readonly ITestOutputHelper output; 7 | public SplitLyricsTest(ITestOutputHelper output) { 8 | this.output = output; 9 | } 10 | 11 | [Fact] 12 | public void SplitTest() { 13 | var result = SplitLyrics.Split("a word中文русский가각갂ひらがな \"がな\" \"\" \"two words\""); 14 | Assert.Collection(result, 15 | s => Assert.Equal("a", s), 16 | s => Assert.Equal("word", s), 17 | s => Assert.Equal("中", s), 18 | s => Assert.Equal("文", s), 19 | s => Assert.Equal("русский", s), 20 | s => Assert.Equal("가", s), 21 | s => Assert.Equal("각", s), 22 | s => Assert.Equal("갂", s), 23 | s => Assert.Equal("ひ", s), 24 | s => Assert.Equal("ら", s), 25 | s => Assert.Equal("が", s), 26 | s => Assert.Equal("な", s), 27 | s => Assert.Equal("がな", s), 28 | s => Assert.Equal("", s), 29 | s => Assert.Equal("two words", s)); 30 | } 31 | 32 | [Fact] 33 | public void JoinTest() { 34 | string[] lyrics = new[] { "a", "word", "中", "文", "русский", "가", "각", "갂", "ひ", "ら", "が", "な", "がな", "", "two words" }; 35 | Assert.Equal( 36 | "a word 中 文 русский 가 각 갂 ひ ら が な \"がな\" \"\" \"two words\"", 37 | SplitLyrics.Join(lyrics)); 38 | } 39 | 40 | [Fact] 41 | public void RoundTripTest() { 42 | string[] lyrics = new[] { "a", "word", "中", "文", "中文", " ", " ", "-", "12 3# $%^", "中русский", "русский", "ひ", "ら", "が", "な", "がな", "two words", "가", "각", "갂", "갃간" }; 43 | Assert.Equal(lyrics, SplitLyrics.Split(SplitLyrics.Join(lyrics))); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /OpenUtau.Test/Files/en_arpa/character.txt: -------------------------------------------------------------------------------- 1 | name=en_arpa 2 | -------------------------------------------------------------------------------- /OpenUtau.Test/Files/en_arpa/character.yaml: -------------------------------------------------------------------------------- 1 | portrait_opacity: 0.67000001668930054 2 | subbanks: 3 | - color: '' 4 | prefix: '' 5 | suffix: '' 6 | tone_ranges: 7 | - C1-A#2 8 | - D4-D5 9 | - F6-B7 10 | - color: '' 11 | prefix: '' 12 | suffix: _1 13 | tone_ranges: 14 | - D#5-E6 15 | - color: '' 16 | prefix: '' 17 | suffix: _3 18 | tone_ranges: 19 | - B2-C#4 20 | - color: Whisper 21 | prefix: '' 22 | suffix: _W 23 | tone_ranges: 24 | - C1-B7 25 | -------------------------------------------------------------------------------- /OpenUtau.Test/Files/en_delta0/character.txt: -------------------------------------------------------------------------------- 1 | name=en_delta0 -------------------------------------------------------------------------------- /OpenUtau.Test/Files/en_delta7/character.txt: -------------------------------------------------------------------------------- 1 | name=en_delta7 -------------------------------------------------------------------------------- /OpenUtau.Test/Files/en_delta7/presamp.ini: -------------------------------------------------------------------------------- 1 | [VOWEL] 2 | {={={=100 3 | @=@=@=100 4 | 3=3=3=100 5 | a=a=a=100 6 | A=A=A=100 7 | E=E=E=100 8 | i=i=i=100 9 | I=I=I=100 10 | o=o=o=100 11 | O=O=O=100 12 | u=u=u=100 13 | U=U=U=100 14 | V=V=V=100 15 | [CONSONANT] 16 | b=b,b3,b@,bA,bE,bI,bO,bU,bV,ba,bd,bi,bju,bl,bo,br,bu,bz,b{=0 17 | d=d,d3,d@,dA,dE,dI,dO,dU,dV,da,di,dju,do,dr,du,dw,dz,d{,dn=0 18 | D=D,D3,D@,DA,DE,DI,DO,DU,DV,Da,Di,Dju,Do,Du,D{,Dd,Dm=0 19 | dZ=dZ,dZ3,dZ@,dZA,dZE,dZI,dZO,dZU,dZV,dZa,dZd,dZi,dZju,dZo,dZu,dZ{=0 20 | f=f,f3,f@,fA,fE,fI,fO,fT,fU,fV,fa,fi,fju,fl,fo,fr,fs,ft,fu,f{,fTs,fts=0 21 | g=g,g3,g@,gA,gE,gI,gO,gU,gV,ga,gi,gju,gl,go,gr,gu,gw,gz,g{,gd,glz=0 22 | h=h,h3,h@,hA,hE,hI,hO,hU,hV,ha,hi,hju,ho,hu,h{=0 23 | j=j,j3,j@,jA,jE,jI,jO,jU,jV,ja,ji,jju,jo,ju,j{=0 24 | k=k,k3,k@,kA,kE,kI,kO,kU,kV,ka,ki,kju,kl,ko,kr,ks,kt,ku,kw,k{,kst=0 25 | l=l,l3,l@,lA,lE,lI,lO,lU,lV,la,li,lju,lo,ls,lu,lz,l{,lb,lbz,ld,ldz,lf,lfs,lft,lfT,lk,lks,lkt,lm,lmd,lmz,lp,lpt,lS,lt,lT,ltSt,lv,lvd,lvz=0 26 | m=m,m3,m@,mA,mE,mI,mO,mU,mV,ma,md,mi,mju,mo,mu,mz,m{,mdZ,mf,mfs,mp,mps,mpt,ms,mtS,mtSt,mtSz=0 27 | n=n,n3,n@,nA,nE,nI,nO,nU,nV,na,ni,nju,no,nt,nu,nz,n{,nd,ndz,ndZd,nk,nks,ns,nT,nts=0 28 | N=N,N3,N@,NA,NE,NI,NO,NU,NV,Na,Ni,Nju,No,Nu,N{,Nd,Nz=0 29 | p=p,p3,p@,pA,pE,pI,pO,pU,pV,pa,pi,pju,pl,po,pr,ps,pt,pu,p{,pls,pT,pTs=0 30 | r=r,r3,r@,rA,rE,rI,rO,rU,rV,ra,ri,rju,ro,ru,r{,rbd,rbz,rdz,rdZd,rfs,rft,rgz,rks,rkt,rmd,rmz,rnt,rnz,rTs,rtSt,rvt,rzd=0 31 | s=s,s3,s@,sA,sE,sI,sO,sU,sV,sa,si,sju,sk,skl,skr,skw,sl,sm,sn,so,sp,spr,st,str,stw,su,sw,s{,sks,skt,sps,sts=0 32 | S=S,S3,S@,SA,SE,SI,SO,SU,SV,Sa,Si,Sju,So,Sr,Su,S{,St=0 33 | t=t,t3,t@,tA,tE,tI,tO,tU,tV,ta,ti,tju,to,tr,ts,tu,tw,t{,tl,tm,tn=0 34 | T=T,T3,T@,TA,TE,TI,TO,TU,TV,Ta,Ti,Tju,To,Tr,Ts,Tu,Tw,T{=0 35 | tS=tS,tS3,tS@,tSA,tSE,tSI,tSO,tSU,tSV,tSa,tSi,tSju,tSo,tSt,tSu,tSz,tS{=0 36 | v=v,v3,v@,vA,vE,vI,vO,vU,vV,va,vd,vi,vju,vo,vt,vu,vz,v{,vd,vl=0 37 | w=w,w3,w@,wA,wE,wI,wO,wU,wV,wa,wi,wju,wo,wu,w{=0 38 | z=z,z3,z@,zA,zE,zI,zO,zU,zV,za,zd,zi,zju,zo,zu,z{,zl,zlz,zm,zmz,zn,znt=0 39 | Z=Z,Z3,Z@,ZA,ZE,ZI,ZO,ZU,ZV,Za,Zi,Zju,Zo,Zu,Z{=0 40 | [PRIORITY] 41 | tS,dZ 42 | [REPLACE] 43 | a=a 44 | [ALIAS] 45 | C=%c% 46 | VC=%v%%vcpad%%c%,%c%%vcpad%%c% 47 | VCVPAD= 48 | VCPAD= 49 | ENDING1=%v% - 50 | ENDING2=- 51 | BEGINING_CV=-%VCVPAD%%CV% 52 | LONG_V=%V%ー 53 | VCV=%v%%VCVPAD%%CV% 54 | CROSS_CV=*%VCVPAD%%CV% 55 | CV=%CV%,%c%%V% 56 | [NUM] 57 | 58 | [SPLIT] 59 | 1 60 | [MUSTVC] 61 | 1 62 | [CFLAGS] 63 | P0 64 | [ENDFLAG] 65 | 3 -------------------------------------------------------------------------------- /OpenUtau.Test/Files/en_vccv/character.txt: -------------------------------------------------------------------------------- 1 | name=en_vccv -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/A3/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_cvvc/A3/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/B4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_cvvc/B4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/C4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_cvvc/C4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/F4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_cvvc/F4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/character.txt: -------------------------------------------------------------------------------- 1 | name=ja_cvvc 2 | -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/character.yaml: -------------------------------------------------------------------------------- 1 | text_file_encoding: shift_jis 2 | portrait_opacity: 0.67000001668930054 3 | subbanks: 4 | - color: '' 5 | prefix: '' 6 | suffix: _B4 7 | tone_ranges: 8 | - A#4-B7 9 | - color: '' 10 | prefix: '' 11 | suffix: _F4 12 | tone_ranges: 13 | - E4-A4 14 | - color: '' 15 | prefix: '' 16 | suffix: _C4 17 | tone_ranges: 18 | - B3-D#4 19 | - color: '' 20 | prefix: '' 21 | suffix: _A3 22 | tone_ranges: 23 | - C1-A#3 24 | - color: 弱 25 | prefix: '' 26 | suffix: _弱B4 27 | tone_ranges: 28 | - A#4-B7 29 | - color: 弱 30 | prefix: '' 31 | suffix: _弱E4 32 | tone_ranges: 33 | - E4-A4 34 | - color: 弱 35 | prefix: '' 36 | suffix: _弱C4 37 | tone_ranges: 38 | - C4-D#4 39 | - color: 弱 40 | prefix: '' 41 | suffix: _弱A3 42 | tone_ranges: 43 | - C1-B3 44 | - color: 強 45 | prefix: '' 46 | suffix: _強B4 47 | tone_ranges: 48 | - A#4-B7 49 | - color: 強 50 | prefix: '' 51 | suffix: _強F4 52 | tone_ranges: 53 | - E4-A4 54 | - color: 強 55 | prefix: '' 56 | suffix: _強B3 57 | tone_ranges: 58 | - C1-D#4 59 | -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_cvvc/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/弱/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_cvvc/弱/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/弱/弱_A3/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_cvvc/弱/弱_A3/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/弱/弱_B4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_cvvc/弱/弱_B4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/弱/弱_C4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_cvvc/弱/弱_C4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/弱/弱_E4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_cvvc/弱/弱_E4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/強/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_cvvc/強/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/強/強_B3/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_cvvc/強/強_B3/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/強/強_B4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_cvvc/強/強_B4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_cvvc/強/強_F4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_cvvc/強/強_F4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/- a/oto.ini: -------------------------------------------------------------------------------- 1 | 01 -a.wav=bre,122,602,-780,70,160 2 | 02 -a.wav=bre2,157,565,-705,60,140 3 | 03 -a.wav=bre3,250,620,-662,60,140 4 | 04 -a.wav=bre4,195,440,-580,55,132 5 | 05 -a.wav=bre5,152,420,-445,45,115 6 | 06 -a.wav=bre6,77,207,-305,35,85 7 | 07 -a.wav=bre7,152,200,-272,37,82 8 | 08 -a.wav=bre8,322,687,-742,47,97 9 | -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/C/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/C/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/a -/oto.ini: -------------------------------------------------------------------------------- 1 | 01 a-.wav=bre-,180,242,-312,10,60 2 | 02 a-.wav=bre-2,285,287,-352,20,90 3 | 03 a-.wav=bre-3,232,352,-387,15,80 4 | 04 a-.wav=bre-4,382,265,-310,20,85 5 | 05 a-.wav=bre-5,375,230,-262,25,95 6 | 06 a-.wav=bre-6,265,190,-237,17,67 7 | 07 a-.wav=bre-7,335,205,-250,10,70 8 | 08 a-.wav=bre-8,342,282,-322,12,77 9 | 09 a-.wav=bre-9,322,97,-200,17,60 10 | 10 a-.wav=bre-10,272,342,-357,20,85 11 | 11 a-.wav=bre-11,305,240,-297,22,87 12 | 12 a-.wav=bre-12,247,267,-315,15,85 13 | 13 a-.wav=bre-13,232,182,-252,20,77 14 | -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/beach A3/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/beach A3/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/beach A4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/beach A4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/beach C5/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/beach C5/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/beach D4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/beach D4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/beach F4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/beach F4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/beach vv A4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/beach vv A4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/beach vv A4C5/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/beach vv A4C5/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/boat D4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/boat D4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/character.txt: -------------------------------------------------------------------------------- 1 | name=ja_presamp -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/character.yaml: -------------------------------------------------------------------------------- 1 | subbanks: 2 | - color: '' 3 | prefix: '' 4 | suffix: _A4 5 | tone_ranges: 6 | - G#4-B7 7 | - color: '' 8 | prefix: '' 9 | suffix: _F4 10 | tone_ranges: 11 | - E4-G4 12 | - color: '' 13 | prefix: '' 14 | suffix: _D4 15 | tone_ranges: 16 | - C4-D#4 17 | - color: '' 18 | prefix: '' 19 | suffix: _A3 20 | tone_ranges: 21 | - C1-B3 22 | - color: 波 23 | prefix: '' 24 | suffix: 波_F4 25 | tone_ranges: 26 | - E4-B7 27 | - color: 波 28 | prefix: '' 29 | suffix: 波_D4 30 | tone_ranges: 31 | - C4-D#4 32 | - color: 波 33 | prefix: '' 34 | suffix: 波_A3 35 | tone_ranges: 36 | - C1-B3 37 | - color: 砂 38 | prefix: '' 39 | suffix: 砂_D4 40 | tone_ranges: 41 | - C4-B7 42 | - color: 砂 43 | prefix: '' 44 | suffix: 砂_A3 45 | tone_ranges: 46 | - C1-B3 47 | - color: 船 48 | prefix: '' 49 | suffix: 船_D4 50 | tone_ranges: 51 | - C1-B7 52 | - color: 貝 53 | prefix: '' 54 | suffix: 貝_A4 55 | tone_ranges: 56 | - G#4-B7 57 | - color: 貝 58 | prefix: '' 59 | suffix: 貝_F4 60 | tone_ranges: 61 | - E4-G4 62 | - color: 貝 63 | prefix: '' 64 | suffix: 貝_D4 65 | tone_ranges: 66 | - C4-D#4 67 | - color: 貝 68 | prefix: '' 69 | suffix: 貝_A3 70 | tone_ranges: 71 | - C1-B3 72 | - color: 星 73 | prefix: '' 74 | suffix: 星_C5 75 | tone_ranges: 76 | - B4-B7 77 | - color: 星 78 | prefix: '' 79 | suffix: 星_G#4 80 | tone_ranges: 81 | - G4-A#4 82 | - color: 星 83 | prefix: '' 84 | suffix: 星_E4 85 | tone_ranges: 86 | - D4-F#4 87 | - color: 星 88 | prefix: '' 89 | suffix: 星_B3 90 | tone_ranges: 91 | - A#3-C#4 92 | - color: 星 93 | prefix: '' 94 | suffix: 星_G#3 95 | tone_ranges: 96 | - G3-A3 97 | - color: 星 98 | prefix: '' 99 | suffix: 星_E3 100 | tone_ranges: 101 | - C1-F#3 102 | -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/nebura B3/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/nebura B3/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/nebura C5/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/nebura C5/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/nebura E3/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/nebura E3/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/nebura E4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/nebura E4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/nebura G#3/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/nebura G#3/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/nebura G#4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/nebura G#4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/sand A3/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/sand A3/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/sand D4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/sand D4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/shell A3/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/shell A3/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/shell A4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/shell A4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/shell D4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/shell D4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/shell F4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/shell F4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/wave A3/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/wave A3/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/wave D4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/wave D4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_presamp/wave F4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_presamp/wave F4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_vcv/C_A3/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_vcv/C_A3/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_vcv/C_C5/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_vcv/C_C5/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_vcv/C_D4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_vcv/C_D4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_vcv/C_G4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_vcv/C_G4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_vcv/N_A3/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_vcv/N_A3/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_vcv/N_C5/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_vcv/N_C5/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_vcv/N_D4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_vcv/N_D4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_vcv/N_G4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_vcv/N_G4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_vcv/W_A3/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_vcv/W_A3/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_vcv/W_D4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_vcv/W_D4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_vcv/W_G4/oto.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/ja_vcv/W_G4/oto.ini -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_vcv/character.txt: -------------------------------------------------------------------------------- 1 | name=ja_vcv 2 | -------------------------------------------------------------------------------- /OpenUtau.Test/Files/ja_vcv/character.yaml: -------------------------------------------------------------------------------- 1 | text_file_encoding: shift_jis 2 | portrait_opacity: 0.67000001668930054 3 | subbanks: 4 | - color: '' 5 | prefix: '' 6 | suffix: C5 7 | tone_ranges: 8 | - C5-B7 9 | - color: '' 10 | prefix: '' 11 | suffix: G4 12 | tone_ranges: 13 | - G4-B4 14 | - color: '' 15 | prefix: '' 16 | suffix: D4 17 | tone_ranges: 18 | - D4-F#4 19 | - color: '' 20 | prefix: '' 21 | suffix: A3 22 | tone_ranges: 23 | - C1-C#4 24 | - color: Clear 25 | prefix: '' 26 | suffix: CC5 27 | tone_ranges: 28 | - C5-B7 29 | - color: Clear 30 | prefix: '' 31 | suffix: CG4 32 | tone_ranges: 33 | - G4-B4 34 | - color: Clear 35 | prefix: '' 36 | suffix: CD4 37 | tone_ranges: 38 | - D4-F#4 39 | - color: Clear 40 | prefix: '' 41 | suffix: CA3 42 | tone_ranges: 43 | - C1-C#4 44 | - color: Whisper 45 | prefix: '' 46 | suffix: WG4 47 | tone_ranges: 48 | - G4-B7 49 | - color: Whisper 50 | prefix: '' 51 | suffix: WD4 52 | tone_ranges: 53 | - D4-F#4 54 | - color: Whisper 55 | prefix: '' 56 | suffix: WA3 57 | tone_ranges: 58 | - C1-C#4 59 | -------------------------------------------------------------------------------- /OpenUtau.Test/Files/sine.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau.Test/Files/sine.wav -------------------------------------------------------------------------------- /OpenUtau.Test/OpenUtau.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0-windows 4 | 5 | 6 | net6.0 7 | 8 | 9 | none 10 | false 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | runtime; build; native; contentfiles; analyzers; buildtransitive 21 | all 22 | 23 | 24 | runtime; build; native; contentfiles; analyzers; buildtransitive 25 | all 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /OpenUtau.Test/Plugins/EnArpaTest.cs: -------------------------------------------------------------------------------- 1 | using OpenUtau.Api; 2 | using OpenUtau.Plugin.Builtin; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace OpenUtau.Plugins { 7 | public class EnArpaTest : PhonemizerTestBase { 8 | public EnArpaTest(ITestOutputHelper output) : base(output) { } 9 | 10 | protected override Phonemizer CreatePhonemizer() { 11 | return new ArpasingPhonemizer(); 12 | } 13 | 14 | [Theory] 15 | [InlineData("en_arpa", 16 | new string[] { "good", "morning" }, 17 | new string[] { "C4", "C4" }, 18 | new string[] { "", "" }, 19 | new string[] { "- g_3", "g uh_3", "uh d_3", "d m_3", "m ao_3", "ao r_3", "r n_3", "n ih_3", "ih ng_3", "ng -_3" })] 20 | [InlineData("en_arpa", 21 | new string[] { "good", "morning", "-" }, 22 | new string[] { "A3", "F4", "C4" }, 23 | new string[] { "", "", "" }, 24 | new string[] { "- g_3", "g uh_3", "uh d_3", "d m_3", "m ao", "ao r", "r n", "n ih", "ih ng", "ng -_3" })] 25 | [InlineData("en_arpa", 26 | new string[] { "moon", "+", "+", "+", "star", "+" }, 27 | new string[] { "F4", "C4", "F4", "F4", "C4", "F4" }, 28 | new string[] { "Whisper", "", "", "", "", "" }, 29 | new string[] { "- m_W", "m uw", "uw n", "n s", "s t_3", "t aa_3", "aa r", "r -" })] 30 | public void PhonemizeTest(string singerName, string[] lyrics, string[] tones, string[] colors, string[] aliases) { 31 | RunPhonemizeTest(singerName, lyrics, tones, colors, aliases); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /OpenUtau.Test/Plugins/EnDeltaTest.cs: -------------------------------------------------------------------------------- 1 | using OpenUtau.Api; 2 | using OpenUtau.Plugin.Builtin; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace OpenUtau.Plugins { 7 | public class EnDeltaTest : PhonemizerTestBase { 8 | public EnDeltaTest(ITestOutputHelper output) : base(output) { } 9 | protected override Phonemizer CreatePhonemizer() { 10 | return new ENDeltaPhonemizer(); 11 | } 12 | 13 | [Theory] 14 | [InlineData("en_delta0", 15 | new string[] { "my", "test" }, 16 | new string[] { "C4", "C4" }, 17 | new string[] { "", "", }, 18 | new string[] { "- maI", "aI t", "tE", "E st-" })] 19 | public void BasicPhonemizingTest(string singerName, string[] lyrics, string[] tones, string[] colors, string[] aliases) { 20 | RunPhonemizeTest(singerName, lyrics, tones, colors, aliases); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /OpenUtau.Test/Plugins/EnToJaTest.cs: -------------------------------------------------------------------------------- 1 | using OpenUtau.Api; 2 | using OpenUtau.Plugin.Builtin; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace OpenUtau.Plugins { 7 | public class EnToJaTest : PhonemizerTestBase { 8 | public EnToJaTest(ITestOutputHelper output) : base(output) { } 9 | protected override Phonemizer CreatePhonemizer() { 10 | return new ENtoJAPhonemizer(); 11 | } 12 | 13 | [Theory] 14 | [InlineData("ja_cvvc", 15 | new string[] { "test", "words" }, 16 | new string[] { "C3", "C3" }, 17 | new string[] { "", "", }, 18 | new string[] { "て_A3", "e s_A3", "と_A3", "うぉ_A3", "o d_A3", "ず_A3" })] 19 | public void BasicPhonemizingTest(string singerName, string[] lyrics, string[] tones, string[] colors, string[] aliases) { 20 | RunPhonemizeTest(singerName, lyrics, tones, colors, aliases); 21 | } 22 | 23 | [Theory] 24 | [InlineData("ja_cvvc", 25 | new string[] { "test", "words" }, 26 | new string[] { "C3", "C4" }, 27 | new string[] { "", "", }, 28 | new string[] { "て_A3", "e s_A3", "と_A3", "うぉ_C4", "o d_C4", "ず_C4" })] 29 | public void MultipitchTest(string singerName, string[] lyrics, string[] tones, string[] colors, string[] aliases) { 30 | RunPhonemizeTest(singerName, lyrics, tones, colors, aliases); 31 | } 32 | 33 | [Theory] 34 | [InlineData("ja_cvvc", 35 | new string[] { "test", "words" }, 36 | new string[] { "C4", "C4" }, 37 | new string[] { "", "強", }, 38 | new string[] { "て_C4", "e s_強B3", "と_C4", "うぉ_C4", "o d_C4", "ず_C4" })] 39 | // Colors are per-phoneme 40 | public void VoiceColorTest(string singerName, string[] lyrics, string[] tones, string[] colors, string[] aliases) { 41 | RunPhonemizeTest(singerName, lyrics, tones, colors, aliases); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /OpenUtau.Test/Plugins/EnVCCVTest.cs: -------------------------------------------------------------------------------- 1 | using OpenUtau.Api; 2 | using OpenUtau.Plugin.Builtin; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace OpenUtau.Plugins { 7 | public class EnVCCVTest : PhonemizerTestBase { 8 | public EnVCCVTest(ITestOutputHelper output) : base(output) { } 9 | protected override Phonemizer CreatePhonemizer() { 10 | return new EnglishVCCVPhonemizer(); 11 | } 12 | 13 | [Theory] 14 | [InlineData("en_vccv", 15 | new string[] { "test", "words" }, 16 | new string[] { "C4", "C4" }, 17 | new string[] { "", "", }, 18 | new string[] { "-te", "e st", "tw", "w3", "3 d", "dz-" })] 19 | public void BasicPhonemizingTest(string singerName, string[] lyrics, string[] tones, string[] colors, string[] aliases) { 20 | RunPhonemizeTest(singerName, lyrics, tones, colors, aliases); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /OpenUtau.Test/Plugins/JaCvvcTest.cs: -------------------------------------------------------------------------------- 1 | using OpenUtau.Api; 2 | using OpenUtau.Plugin.Builtin; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace OpenUtau.Plugins { 7 | public class JaCvvcTest : PhonemizerTestBase { 8 | public JaCvvcTest(ITestOutputHelper output) : base(output) { } 9 | 10 | protected override Phonemizer CreatePhonemizer() { 11 | return new JapaneseCVVCPhonemizer(); 12 | } 13 | 14 | [Theory] 15 | [InlineData("ja_cvvc", 16 | new string[] { "あ", "+", "あ", "-" }, 17 | new string[] { "C4", "C4", "C4", "C4" }, 18 | new string[] { "", "", "弱", "" }, 19 | new string[] { "- あ_C4", "a あ_弱C4", "-" })] 20 | [InlineData("ja_cvvc", 21 | new string[] { "お", "にょ", "ひょ", "みょ", "びょ", "ぴょ", "りょ" }, 22 | new string[] { "A3", "C4", "D4", "E4", "F4", "G3", "F3" }, 23 | new string[] { "", "弱", "", "", "強", "", "" }, 24 | new string[] { "- お_A3", "o ny_A3", "にょ_弱C4", "o hy_弱C4", "ひょ_C4", "o my_C4", "みょ_F4", "o by_F4", "びょ_強F4", "o py_強F4", "ぴょ_A3", "o ry_A3", "りょ_A3" })] 25 | [InlineData("ja_cvvc", 26 | new string[] { "ラ", "リ", "ル", "ら" }, 27 | new string[] { "C4", "C4", "C4", "C4" }, 28 | new string[] { "", "", "", "" }, 29 | new string[] { "ラ_C4", "a ly_C4", "リ_C4", "i l_C4", "ル_C4", "u r_C4", "ら_C4" })] 30 | public void PhonemizeTest(string singerName, string[] lyrics, string[] tones, string[] colors, string[] aliases) { 31 | RunPhonemizeTest(singerName, lyrics, tones, colors, aliases); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /OpenUtau.Test/Plugins/JaPresampTest.cs: -------------------------------------------------------------------------------- 1 | using OpenUtau.Api; 2 | using OpenUtau.Plugin.Builtin; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace OpenUtau.Plugins { 7 | public class JaPresampTest : PhonemizerTestBase { 8 | public JaPresampTest(ITestOutputHelper output) : base(output) { } 9 | 10 | protected override Phonemizer CreatePhonemizer() { 11 | return new JapanesePresampPhonemizer(); 12 | } 13 | 14 | [Theory] 15 | [InlineData("ja_presamp", 16 | new string[] { "あ", "+", "あ", "-" }, 17 | new string[] { "C4", "C4", "C4", "C4" }, 18 | new string[] { "", "", "波", "" }, 19 | new string[] { "- あ_D4", "a あ波_D4", "a -_D4" })] 20 | [InlineData("ja_presamp", 21 | new string[] { "お", "にょ", "ひょ", "みょ", "びょ", "ぴょ", "りょ", "R" }, 22 | new string[] { "A3", "C4", "D4", "E4", "F4", "G4", "A4", "A4" }, 23 | new string[] { "", "", "波", "星", "星", "貝", "貝", "貝" }, 24 | new string[] { "- お_A3", "o にょ_D4", "o C_D4", "ひょ波_D4", "o みょ星_E4", "o びょ星_E4", "o p'星_E4", "ぴょ貝_F4", "o 4'貝_F4", "りょ貝_A4", "o R貝_A4" })] 25 | [InlineData("ja_presamp", 26 | new string[] { "- ず", "u t", "と", "お・", "o R" }, 27 | new string[] { "A3", "A3", "C4", "D4", "D4" }, 28 | new string[] { "", "", "", "", "" }, 29 | new string[] { "- ず_A3", "u t_A3", "と_D4", "o ・_D4", "・ お_D4", "o R_D4" })] 30 | [InlineData("ja_presamp", 31 | new string[] { "ri", "p", "re", "i", "s" }, // [PRIORITY] p,s 32 | new string[] { "C4", "C4", "C4", "C4", "C4" }, 33 | new string[] { "", "", "", "", "" }, 34 | new string[] { "- り_D4", "i p_D4", "p", "れ_D4", "e い_D4", "i s_D4", "s" })] 35 | public void PhonemizeTest(string singerName, string[] lyrics, string[] tones, string[] colors, string[] aliases) { 36 | RunPhonemizeTest(singerName, lyrics, tones, colors, aliases); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /OpenUtau.Test/Plugins/JaVcvTest.cs: -------------------------------------------------------------------------------- 1 | using OpenUtau.Api; 2 | using OpenUtau.Plugin.Builtin; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace OpenUtau.Plugins { 7 | public class JaVcvTest : PhonemizerTestBase { 8 | public JaVcvTest(ITestOutputHelper output) : base(output) { } 9 | 10 | protected override Phonemizer CreatePhonemizer() { 11 | return new JapaneseVCVPhonemizer(); 12 | } 13 | 14 | [Theory] 15 | [InlineData("ja_vcv", 16 | new string[] { "あ", "+", "あ", "-" }, 17 | new string[] { "C4", "C4", "C4", "C4" }, 18 | new string[] { "", "", "Clear", "" }, 19 | new string[] { "- あA3", "a あCA3", "-" })] 20 | [InlineData("ja_vcv", 21 | new string[] { "お", "にょ", "ひょ", "みょ", "びょ", "ぴょ", "りょ" }, 22 | new string[] { "A3", "C4", "D4", "E4", "F4", "G3", "F3" }, 23 | new string[] { "", "Clear", "", "", "Whisper", "", "" }, 24 | new string[] { "- おA3", "o にょCA3", "o ひょD4", "o みょD4", "o びょWD4", "o ぴょA3", "o りょA3" })] 25 | [InlineData("ja_vcv", 26 | new string[] { "- ず", "u と", "o R" }, 27 | new string[] { "A3", "C4", "D4" }, 28 | new string[] { "", "", "" }, 29 | new string[] { "- ずA3", "u とA3", "o RD4" })] 30 | public void PhonemizeTest(string singerName, string[] lyrics, string[] tones, string[] colors, string[] aliases) { 31 | RunPhonemizeTest(singerName, lyrics, tones, colors, aliases); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /OpenUtau.Test/Usts/_dummy.ust: -------------------------------------------------------------------------------- 1 | [#SETTING] 2 | Tempo=84.00 3 | Tracks=1 4 | ProjectName=Main 5 | VoiceDir=%VOICE%�g�����c�E�L������Ver1.0 6 | OutFile= 7 | CacheDir= 8 | Tool1= 9 | Tool2= 10 | Mode2=True 11 | Flags=Y0H0F-10 12 | [#0000] 13 | Length=15 14 | Lyric=R 15 | NoteNum=60 16 | PreUtterance= -------------------------------------------------------------------------------- /OpenUtau/App.axaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /OpenUtau/Assets/OpenUtau.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau/Assets/OpenUtau.icns -------------------------------------------------------------------------------- /OpenUtau/Assets/logotype-w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau/Assets/logotype-w.png -------------------------------------------------------------------------------- /OpenUtau/Assets/logotype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau/Assets/logotype.png -------------------------------------------------------------------------------- /OpenUtau/Assets/open-utau.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau/Assets/open-utau.ico -------------------------------------------------------------------------------- /OpenUtau/Colors/DarkTheme.axaml: -------------------------------------------------------------------------------- 1 | 4 | true 5 | 6 | #303030 7 | 8 | #303030 9 | #505050 10 | #707070 11 | #404040 12 | 13 | #E0E0E0 14 | #FCFCFC 15 | #FFFFFF 16 | #A0A0A0 17 | 18 | #707070 19 | #B0B0B0 20 | 21 | #808080 22 | #A0A0A0 23 | #4EA6EA 24 | #FF679D 25 | #E62E6E 26 | 27 | #707070 28 | #D0D0D0 29 | #D0D0D0 30 | #404040 31 | 32 | 33 | #CC2A63 34 | #FF347C 35 | #FFFFFF 36 | 37 | #CCA5B0 38 | #FFCEDC 39 | #FF347C 40 | 41 | Transparent 42 | Transparent 43 | #FFFFFF 44 | 45 | -------------------------------------------------------------------------------- /OpenUtau/Colors/LightTheme.axaml: -------------------------------------------------------------------------------- 1 | 4 | false 5 | 6 | #FFFFFF 7 | 8 | #FFFFFF 9 | #F0F0F0 10 | #E0E0E0 11 | #D0D0D0 12 | 13 | #000000 14 | #000000 15 | #202020 16 | #808080 17 | 18 | #707070 19 | #B0B0B0 20 | 21 | #ADA1B3 22 | #948A99 23 | #4EA6EA 24 | #FF679D 25 | #E62E6E 26 | 27 | #AFA3B5 28 | #AFA3B5 29 | #C0C0C0 30 | #F0F0F0 31 | 32 | 33 | Transparent 34 | Transparent 35 | #FF347c 36 | 37 | #FFDDE6 38 | #FFCEDC 39 | #FF347C 40 | 41 | #FF71A3 42 | #FF347C 43 | #FFFFFF 44 | 45 | -------------------------------------------------------------------------------- /OpenUtau/Controls/ExpSelector.axaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia; 2 | using Avalonia.Controls; 3 | using Avalonia.Input; 4 | using Avalonia.Markup.Xaml; 5 | using OpenUtau.App.ViewModels; 6 | 7 | namespace OpenUtau.App.Controls { 8 | public partial class ExpSelector : UserControl { 9 | public static readonly DirectProperty IndexProperty = 10 | AvaloniaProperty.RegisterDirect( 11 | nameof(Index), 12 | o => o.Index, 13 | (o, v) => o.Index = v); 14 | 15 | public int Index { 16 | get => index; 17 | set => SetAndRaise(IndexProperty, ref index, value); 18 | } 19 | 20 | private int index; 21 | 22 | public ExpSelector() { 23 | InitializeComponent(); 24 | DataContext = new ExpSelectorViewModel(); 25 | ((ExpSelectorViewModel)DataContext!).Index = Index; 26 | } 27 | 28 | protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { 29 | base.OnPropertyChanged(change); 30 | if (change.Property == IndexProperty) { 31 | ((ExpSelectorViewModel)DataContext!).Index = Index; 32 | } 33 | } 34 | 35 | private void InitializeComponent() { 36 | AvaloniaXamlLoader.Load(this); 37 | } 38 | 39 | private void TextBlockPointerPressed(object sender, PointerPressedEventArgs e) { 40 | ((ExpSelectorViewModel)DataContext!).OnSelected(); 41 | } 42 | 43 | public void SelectExp() { 44 | ((ExpSelectorViewModel)DataContext!).OnSelected(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /OpenUtau/Controls/TextLayoutCache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Avalonia.Media; 4 | using Avalonia.Media.TextFormatting; 5 | 6 | namespace OpenUtau.App.Controls { 7 | static class TextLayoutCache { 8 | private static readonly Dictionary, TextLayout> cache 9 | = new Dictionary, TextLayout>(); 10 | 11 | public static void Clear() { 12 | cache.Clear(); 13 | } 14 | 15 | public static TextLayout Get(string text, IBrush brush, double fontSize, bool bold = false) { 16 | var key = Tuple.Create(text, brush, fontSize, bold); 17 | if (!cache.TryGetValue(key, out var textLayout)) { 18 | var fontWeight = bold ? FontWeight.Bold : FontWeight.Normal; 19 | textLayout = new TextLayout( 20 | text, 21 | new Typeface(FontFamily.Default, weight: fontWeight), 22 | fontSize, 23 | brush, 24 | TextAlignment.Left, 25 | TextWrapping.NoWrap); 26 | cache.Add(key, textLayout); 27 | } 28 | return textLayout; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /OpenUtau/Controls/TrackAdder.axaml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /OpenUtau/Controls/ViewScaler.axaml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 11 | 14 | 17 | 20 | 23 | 26 | 27 | 31 | 32 | -------------------------------------------------------------------------------- /OpenUtau/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /OpenUtau/FodyWeavers.xsd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. 12 | 13 | 14 | 15 | 16 | A comma-separated list of error codes that can be safely ignored in assembly verification. 17 | 18 | 19 | 20 | 21 | 'false' to turn off automatic generation of the XML Schema file. 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /OpenUtau/Resources/Unzipper.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishaudio/OpenUtau/72e8339f25331e5aa09dff18dd44550efbb71579/OpenUtau/Resources/Unzipper.exe -------------------------------------------------------------------------------- /OpenUtau/ViewLocator.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | using Avalonia.Controls.Templates; 3 | using OpenUtau.App.ViewModels; 4 | using System; 5 | 6 | namespace OpenUtau.App 7 | { 8 | public class ViewLocator : IDataTemplate 9 | { 10 | public bool SupportsRecycling => false; 11 | 12 | public IControl Build(object data) 13 | { 14 | var name = data.GetType().FullName!.Replace("ViewModel", "View"); 15 | var type = Type.GetType(name); 16 | 17 | if (type != null) 18 | { 19 | return (Control)Activator.CreateInstance(type)!; 20 | } 21 | else 22 | { 23 | return new TextBlock { Text = "Not Found: " + name }; 24 | } 25 | } 26 | 27 | public bool Match(object data) 28 | { 29 | return data is ViewModelBase; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /OpenUtau/ViewModels/Converters.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Text; 4 | using Avalonia.Data.Converters; 5 | 6 | namespace OpenUtau.App.ViewModels { 7 | public class CultureNameConverter : IValueConverter { 8 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { 9 | if (value is CultureInfo cultureInfo) { 10 | return cultureInfo.NativeName; 11 | } 12 | return string.Empty; 13 | } 14 | 15 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException(); 16 | } 17 | 18 | public class EncodingNameConverter : IValueConverter { 19 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { 20 | return ((Encoding)value).EncodingName; 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { 24 | throw new NotImplementedException(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /OpenUtau/ViewModels/MenuItemViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Windows.Input; 3 | 4 | namespace OpenUtau.App.ViewModels { 5 | public class MenuItemViewModel { 6 | public string? Header { get; set; } 7 | public ICommand? Command { get; set; } 8 | public object? CommandParameter { get; set; } 9 | public IList? Items { get; set; } 10 | public int Height { get; set; } = 24; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /OpenUtau/ViewModels/PhoneticAssistantViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reactive.Linq; 4 | using OpenUtau.Core.G2p; 5 | using ReactiveUI; 6 | using ReactiveUI.Fody.Helpers; 7 | 8 | namespace OpenUtau.App.ViewModels { 9 | public class PhoneticAssistantViewModel : ViewModelBase { 10 | public class G2pOption { 11 | public string name; 12 | public Type klass; 13 | public G2pOption(Type klass) { 14 | name = klass.Name; 15 | this.klass = klass; 16 | } 17 | public override string ToString() => name; 18 | } 19 | public List G2ps => g2ps; 20 | 21 | [Reactive] public G2pOption? G2p { get; set; } 22 | [Reactive] public string Grapheme { get; set; } 23 | [Reactive] public string Phonemes { get; set; } 24 | 25 | private readonly List g2ps = new List() { 26 | new G2pOption(typeof(ArpabetG2p)), 27 | new G2pOption(typeof(FrenchG2p)), 28 | new G2pOption(typeof(ItalianG2p)), 29 | new G2pOption(typeof(PortugueseG2p)), 30 | new G2pOption(typeof(RussianG2p)), 31 | }; 32 | 33 | private Api.G2pPack? g2p; 34 | 35 | public PhoneticAssistantViewModel() { 36 | Grapheme = string.Empty; 37 | Phonemes = string.Empty; 38 | this.WhenAnyValue(x => x.G2p) 39 | .Subscribe(option => { 40 | g2p = null; 41 | if (option != null) { 42 | g2p = Activator.CreateInstance(option.klass) as Api.G2pPack; 43 | Refresh(); 44 | } 45 | }); 46 | this.WhenAnyValue(x => x.Grapheme) 47 | .Subscribe(_ => Refresh()); 48 | } 49 | 50 | private void Refresh() { 51 | if (g2p == null) { 52 | Phonemes = string.Empty; 53 | return; 54 | } 55 | string[] phonemes = g2p.Query(Grapheme); 56 | if (phonemes == null) { 57 | Phonemes = string.Empty; 58 | return; 59 | } 60 | Phonemes = string.Join(' ', phonemes); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /OpenUtau/ViewModels/ViewModelBase.cs: -------------------------------------------------------------------------------- 1 | using ReactiveUI; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace OpenUtau.App.ViewModels 7 | { 8 | public class ViewModelBase : ReactiveObject 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /OpenUtau/Views/DebugWindow.axaml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |