Skip to content

Commit

Permalink
Merge pull request stakira#1006 from oxygen-dioxide/diffsinger-dict
Browse files Browse the repository at this point in the history
DiffSinger: support different dictionaries for Chinese, Japanese and Cantonese
  • Loading branch information
stakira authored Jan 28, 2024
2 parents 56ad46c + 10186b4 commit 6f3b7b6
Show file tree
Hide file tree
Showing 13 changed files with 60 additions and 47 deletions.
17 changes: 11 additions & 6 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
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

0 comments on commit 6f3b7b6

Please sign in to comment.