Skip to content

Commit

Permalink
Merge branch 'stakira:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
oxygen-dioxide authored Jan 28, 2024
2 parents 0be693c + 94213d7 commit 010d970
Show file tree
Hide file tree
Showing 45 changed files with 1,223 additions and 616 deletions.
32 changes: 12 additions & 20 deletions OpenUtau.Core/Classic/VoicebankLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,28 +88,20 @@ public static void LoadInfo(Voicebank voicebank, string filePath, string basePat
Log.Error(e, $"Failed to load yaml {yamlFile}");
}
}
switch (bankConfig?.SingerType) {
case "utau":
voicebank.SingerType = USingerType.Classic;
break;
case "enunu":
string singerType = bankConfig?.SingerType ?? string.Empty;
if(SingerTypeUtils.SingerTypeFromName.ContainsKey(singerType)){
voicebank.SingerType = SingerTypeUtils.SingerTypeFromName[singerType];
}else{
// Legacy detection code. Do not add more here.
var enuconfigFile = Path.Combine(dir, kEnuconfigYaml);
var dsconfigFile = Path.Combine(dir, kDsconfigYaml);
if (File.Exists(enuconfigFile)) {
voicebank.SingerType = USingerType.Enunu;
break;
case "diffsinger":
} else if (File.Exists(dsconfigFile)) {
voicebank.SingerType = USingerType.DiffSinger;
break;
default:
// Legacy detection code. Do not add more here.
var enuconfigFile = Path.Combine(dir, kEnuconfigYaml);
var dsconfigFile = Path.Combine(dir, kDsconfigYaml);
if (File.Exists(enuconfigFile)) {
voicebank.SingerType = USingerType.Enunu;
} else if (File.Exists(dsconfigFile)) {
voicebank.SingerType = USingerType.DiffSinger;
} else if (voicebank.SingerType != USingerType.Enunu) {
voicebank.SingerType = USingerType.Classic;
}
break;
} else if (voicebank.SingerType != USingerType.Enunu) {
voicebank.SingerType = USingerType.Classic;
}
}
Encoding encoding = Encoding.GetEncoding("shift_jis");
if (!string.IsNullOrEmpty(bankConfig?.TextFileEncoding)) {
Expand Down
33 changes: 26 additions & 7 deletions OpenUtau.Core/DiffSinger/DiffSingerBasePhonemizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public abstract class DiffSingerBasePhonemizer : MachineLearningPhonemizer
DiffSingerSpeakerEmbedManager speakerEmbedManager;

string defaultPause = "SP";
protected virtual string GetDictionaryName()=>"dsdict.yaml";

public override void SetSinger(USinger singer) {
this.singer = singer;
Expand Down Expand Up @@ -66,13 +67,17 @@ public override void SetSinger(USinger singer) {

protected virtual IG2p LoadG2p(string rootPath) {
var g2ps = new List<IG2p>();
var dictionaryNames = new string[] {GetDictionaryName(), "dsdict.yaml"};
// Load dictionary from singer folder.
string file = Path.Combine(rootPath, "dsdict.yaml");
if (File.Exists(file)) {
try {
g2ps.Add(G2pDictionary.NewBuilder().Load(File.ReadAllText(file)).Build());
} catch (Exception e) {
Log.Error(e, $"Failed to load {file}");
foreach(var dictionaryName in dictionaryNames){
string dictionaryPath = Path.Combine(rootPath, dictionaryName);
if (File.Exists(dictionaryPath)) {
try {
g2ps.Add(G2pDictionary.NewBuilder().Load(File.ReadAllText(dictionaryPath)).Build());
} catch (Exception e) {
Log.Error(e, $"Failed to load {dictionaryPath}");
}
break;
}
}
return new G2pFallbacks(g2ps.ToArray());
Expand Down Expand Up @@ -133,11 +138,25 @@ List<phonemesPerNote> ProcessWord(Note[] notes){
};
var dsPhonemes = GetDsPhonemes(notes[0]);
var isVowel = dsPhonemes.Select(s => g2p.IsVowel(s.Symbol)).ToArray();
var isGlide = dsPhonemes.Select(s => g2p.IsGlide(s.Symbol)).ToArray();
var nonExtensionNotes = notes.Where(n=>!IsSyllableVowelExtensionNote(n)).ToArray();
var isStart = new bool[dsPhonemes.Length];
if(!isStart.Any()){
isStart[0] = true;
}
for(int i=0; i<dsPhonemes.Length; i++){
if(isVowel[i]){
if(i>=2 && isGlide[i-1] && !isVowel[i-2]){
isStart[i-1] = true;
}else{
isStart[i] = true;
}
}
}
//distribute phonemes to notes
var noteIndex = 0;
for (int i = 0; i < dsPhonemes.Length; i++) {
if (isVowel[i] && noteIndex < nonExtensionNotes.Length) {
if (isStart[i] && noteIndex < nonExtensionNotes.Length) {
var note = nonExtensionNotes[noteIndex];
wordPhonemes.Add(new phonemesPerNote(note.position, note.tone));
noteIndex++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

using OpenUtau.Api;

namespace OpenUtau.Core.DiffSinger
{
namespace OpenUtau.Core.DiffSinger {
[Phonemizer("DiffSinger Chinese Phonemizer", "DIFFS ZH", language: "ZH")]
public class DiffSingerChinesePhonemizer : DiffSingerBasePhonemizer
{
public class DiffSingerChinesePhonemizer : DiffSingerBasePhonemizer {
protected override string GetDictionaryName()=>"dsdict-zh.yaml";
protected override string[] Romanize(IEnumerable<string> lyrics) {
return BaseChinesePhonemizer.Romanize(lyrics);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,37 +29,35 @@ public Dictionary<string, string> toDict(){
}
}

/// <summary>
/// Base class for DiffSinger phonemizers based on OpenUtau's builtin G2p.
/// </summary>
public abstract class DiffSingerG2pPhonemizer : DiffSingerBasePhonemizer
{
protected virtual string GetDictionaryName()=>"dsdict.yaml";

protected virtual IG2p LoadBaseG2p()=>null;
//vowels and consonants of BaseG2p
protected virtual string[] GetBaseG2pVowels()=>new string[]{};
protected virtual string[] GetBaseG2pConsonants()=>new string[]{};

protected override IG2p LoadG2p(string rootPath) {
var dictionaryName = GetDictionaryName();
//Each phonemizer has a delicated dictionary name, such as dsdict-en.yaml, dsdict-ru.yaml.
//If this dictionary exists, load it.
//If not, load dsdict.yaml.
var dictionaryNames = new string[] {GetDictionaryName(), "dsdict.yaml"};
var g2ps = new List<IG2p>();
// Load dictionary from plugin folder.
string path = Path.Combine(PluginDir, dictionaryName);
if (File.Exists(path)) {
try {
g2ps.Add(G2pDictionary.NewBuilder().Load(File.ReadAllText(path)).Build());
} catch (Exception e) {
Log.Error(e, $"Failed to load {path}");
}
}

// Load dictionary from singer folder.
var replacements = new Dictionary<string,string>();
string file = Path.Combine(rootPath, dictionaryName);
if (File.Exists(file)) {
try {
g2ps.Add(G2pDictionary.NewBuilder().Load(File.ReadAllText(file)).Build());
replacements = G2pReplacementsData.Load(File.ReadAllText(file)).toDict();
} catch (Exception e) {
Log.Error(e, $"Failed to load {file}");
foreach(var dictionaryName in dictionaryNames){
string dictionaryPath = Path.Combine(rootPath, dictionaryName);
if (File.Exists(dictionaryPath)) {
try {
g2ps.Add(G2pDictionary.NewBuilder().Load(File.ReadAllText(dictionaryPath)).Build());
replacements = G2pReplacementsData.Load(File.ReadAllText(dictionaryPath)).toDict();
} catch (Exception e) {
Log.Error(e, $"Failed to load {dictionaryPath}");
}
break;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
using OpenUtau.Api;
using OpenUtau.Core.G2p;

namespace OpenUtau.Core.DiffSinger {
[Phonemizer("DiffSinger Italian Phonemizer", "DIFFS IT", language: "IT")]
public class DiffSingerItalianPhonemizer : DiffSingerG2pPhonemizer {
protected override string GetDictionaryName() => "dsdict-it.yaml";
protected override IG2p LoadBaseG2p() => new ItalianG2p();
protected override string[] GetBaseG2pVowels() => new string[] {
"a", "a1", "e", "e1", "EE", "i", "i1", "o", "o1", "OO", "u", "u1"
};

protected override string[] GetBaseG2pConsonants() => new string[] {
"b", "d", "dz", "dZZ", "f", "g", "JJ", "k", "l", "LL", "m", "n",
"nf", "ng", "p", "r", "rr", "s", "SS", "t", "ts", "tSS", "v", "w", "y", "z"
};
}
}
using OpenUtau.Api;
using OpenUtau.Core.G2p;

namespace OpenUtau.Core.DiffSinger {
[Phonemizer("DiffSinger Italian Phonemizer", "DIFFS IT", language: "IT")]
public class DiffSingerItalianPhonemizer : DiffSingerG2pPhonemizer {
protected override string GetDictionaryName() => "dsdict-it.yaml";
protected override IG2p LoadBaseG2p() => new ItalianG2p();
protected override string[] GetBaseG2pVowels() => new string[] {
"a", "a1", "e", "e1", "EE", "i", "i1", "o", "o1", "OO", "u", "u1"
};

protected override string[] GetBaseG2pConsonants() => new string[] {
"b", "d", "dz", "dZZ", "f", "g", "JJ", "k", "l", "LL", "m", "n",
"nf", "ng", "p", "r", "rr", "s", "SS", "t", "ts", "tSS", "v", "w", "y", "z"
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;

using OpenUtau.Api;

namespace OpenUtau.Core.DiffSinger {
[Phonemizer("DiffSinger Japanese Phonemizer", "DIFFS JA", language: "JA")]
public class DiffSingerJapanesePhonemizer : DiffSingerBasePhonemizer {
protected override string GetDictionaryName()=>"dsdict-ja.yaml";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
namespace OpenUtau.Core.DiffSinger {
[Phonemizer("DiffSinger Jyutping Phonemizer", "DIFFS ZH-YUE", language: "ZH-YUE")]
public class DiffSingerJyutpingPhonemizer : DiffSingerBasePhonemizer {
protected override string GetDictionaryName() => "dsdict-zh-yue.yaml";
protected override string[] Romanize(IEnumerable<string> lyrics) {
return ZhG2p.CantoneseInstance.Convert(lyrics.ToList(), false, true).Split(" ");
}
Expand Down
28 changes: 28 additions & 0 deletions OpenUtau.Core/Ustx/USinger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,21 @@ private static void AddToneRange(string range, SortedSet<int> set) {

[Flags] public enum USingerType { Classic = 0x1, Enunu = 0x2, Vogen = 0x4, DiffSinger=0x5 }

public static class SingerTypeUtils{
public static Dictionary<USingerType?, string> SingerTypeNames = new Dictionary<USingerType?, string>(){
{USingerType.Classic, "utau"},
{USingerType.Enunu, "enunu"},
{USingerType.DiffSinger, "diffsinger"},
};

public static Dictionary<string, USingerType> SingerTypeFromName = new Dictionary<string, USingerType>(){
{"utau", USingerType.Classic},
{"enunu", USingerType.Enunu},
{"diffsinger", USingerType.DiffSinger},
};

}

public class USinger : INotifyPropertyChanged, IEquatable<USinger> {
protected static readonly List<UOto> emptyOtos = new List<UOto>();

Expand Down Expand Up @@ -222,6 +237,19 @@ public bool OtoDirty {
NotifyPropertyChanged(nameof(OtoDirty));
}
}
public bool IsFavourite {
get => Preferences.Default.FavoriteSingers.Contains(Id);
set {
if (value) {
if (!Preferences.Default.FavoriteSingers.Contains(Id)) {
Preferences.Default.FavoriteSingers.Add(Id);
}
} else {
Preferences.Default.FavoriteSingers.Remove(Id);
}
Preferences.Save();
}
}

public event PropertyChangedEventHandler PropertyChanged;

Expand Down
3 changes: 3 additions & 0 deletions OpenUtau.Core/Util/Preferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ public class SerializablePreferences {
public bool PreferCommaSeparator = false;
public bool ResamplerLogging = false;
public List<string> RecentSingers = new List<string>();
public List<string> FavoriteSingers = new List<string>();
public Dictionary<string, string> SingerPhonemizers = new Dictionary<string, string>();
public List<string> RecentPhonemizers = new List<string>();
public bool PreferPortAudio = false;
Expand Down Expand Up @@ -182,6 +183,8 @@ public class SerializablePreferences {
public bool RememberVsqx = true;
public int ImportTempo = 0;
public string PhoneticAssistant = string.Empty;
public string RecentOpenSingerDirectory = string.Empty;
public string RecentOpenProjectDirectory = string.Empty;
}
}
}
24 changes: 24 additions & 0 deletions OpenUtau/Controls/TrackHeader.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,30 @@
<Setter Property="Command" Value="{Binding Command}"/>
<Setter Property="CommandParameter" Value="{Binding CommandParameter}"/>
<Setter Property="ItemsSource" Value="{Binding Items}"/>
<Setter Property="Icon" Value="{Binding Icon}"/>
<Setter Property="ToolTip.Tip" Value="{Binding Location}"/>
</Style>

<Style Selector="ToggleButton">
<Setter Property="Padding" Value="0"/>
<Setter Property="Content" Value=""/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="Width" Value="20"/>
<Setter Property="Height" Value="20"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Foreground" Value="{DynamicResource AccentBrush3}"/>
<Setter Property="Background" Value="Transparent"/>
<Style Selector="^:checked">
<Setter Property="Content" Value=""/>
</Style>
<Style Selector="^:checked /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Foreground" Value="{DynamicResource AccentBrush3}" />
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style Selector="^:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Foreground" Value="{DynamicResource AccentBrush3}" />
<Setter Property="Background" Value="Transparent"/>
</Style>
</Style>
</ContextMenu.Styles>
</ContextMenu>
Expand Down
2 changes: 2 additions & 0 deletions OpenUtau/Controls/TrackHeader.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ void SingerButtonClicked(object sender, RoutedEventArgs args) {
if (SingerManager.Inst.Singers.Count > 0) {
ViewModel?.RefreshSingers();
SingersMenu.Open();
} else {
DocManager.Inst.ExecuteCmd(new ErrorMessageNotification("There is no singer."));
}
args.Handled = true;
}
Expand Down
Loading

0 comments on commit 010d970

Please sign in to comment.