forked from oxygen-dioxide/OpenUtau
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
426 additions
and
236 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Text; | ||
using OpenUtau.SimpleHelpers; | ||
using Serilog; | ||
|
||
namespace OpenUtau.Classic { | ||
|
||
/// <summary> | ||
/// A character. May contains multiple voice banks. | ||
/// </summary> | ||
public class Character { | ||
|
||
private Character() { | ||
} | ||
|
||
public string Name { private set; get; } | ||
public string DisplayName => Loaded ? Name : $"{Name}[Unloaded]"; | ||
public string BasePath { private set; get; } | ||
public string CharacterFile { private set; get; } | ||
public string Author { private set; get; } | ||
public string Website { private set; get; } | ||
public string Language { private set; get; } | ||
public List<Voicebank> Voicebanks { private set; get; } | ||
public bool Loaded { private set; get; } | ||
|
||
public static List<Character> SearchAndLoadCharacters(List<string> searchPaths) { | ||
const string CharacterFileName = "character.txt"; | ||
var characterFiles = new HashSet<string>(); | ||
foreach (var searchPath in searchPaths) { | ||
if (!Directory.Exists(searchPath)) { | ||
continue; | ||
} | ||
var files = Directory.GetFiles(searchPath, CharacterFileName, | ||
SearchOption.AllDirectories); | ||
foreach (var file in files) { | ||
characterFiles.Add(file); | ||
} | ||
} | ||
var result = new List<Character>(); | ||
foreach (var file in characterFiles) { | ||
var character = new Character { | ||
BasePath = Path.GetDirectoryName(file), | ||
CharacterFile = file, | ||
}; | ||
character.LoadVoicebanks(); | ||
result.Add(character); | ||
} | ||
return result; | ||
} | ||
|
||
public void LoadVoicebanks() { | ||
const string OtoFileName = "oto.ini"; | ||
var otoFiles = Directory.GetFiles(BasePath, OtoFileName, SearchOption.AllDirectories); | ||
var voicebanks = new List<Voicebank>(); | ||
foreach (var otoFile in otoFiles) { | ||
try { | ||
var voicebank = new Voicebank.Builder(otoFile) | ||
.SetOtoEncoding(FileEncoding.DetectFileEncoding( | ||
otoFile, Encoding.GetEncoding("shift_jis"))) | ||
.SetPathEncoding(Encoding.Default) | ||
.Build(); | ||
voicebanks.Add(voicebank); | ||
} catch (Exception e) { | ||
Log.Error(e, "Failed to load {0}", otoFile); | ||
} | ||
} | ||
Log.Information("Loaded {0} voicebanks from character {1}", voicebanks.Count, BasePath); | ||
Voicebanks = voicebanks; | ||
Loaded = true; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
using System.Linq; | ||
|
||
namespace OpenUtau.Classic { | ||
|
||
/// <summary> | ||
/// A sound in a voice bank. Corresponds to one line in oto.ini file. | ||
/// </summary> | ||
public class Oto { | ||
public string AudioFile; | ||
public string Alias; | ||
public int Offset; | ||
public int Consonant; | ||
public int Cutoff; | ||
public int Preutter; | ||
public int Overlap; | ||
|
||
public static Oto Parse(string line) { | ||
if (!line.Contains('=')) { | ||
return null; | ||
} | ||
var parts = line.Split('='); | ||
if (parts.Length != 2) { | ||
return null; | ||
} | ||
var audioClip = parts[0].Trim(); | ||
parts = parts[1].Split(','); | ||
if (parts.Length != 6) { | ||
return null; | ||
} | ||
var result = new Oto { | ||
AudioFile = audioClip, | ||
Alias = parts[0].Trim() | ||
}; | ||
int.TryParse(parts[1], out result.Offset); | ||
int.TryParse(parts[2], out result.Consonant); | ||
int.TryParse(parts[3], out result.Cutoff); | ||
int.TryParse(parts[4], out result.Preutter); | ||
int.TryParse(parts[5], out result.Overlap); | ||
return result; | ||
} | ||
|
||
public override string ToString() { | ||
return Alias; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Text; | ||
using Serilog; | ||
|
||
namespace OpenUtau.Classic { | ||
|
||
/// <summary> | ||
/// A sound bank. Corresponds to a single oto.ini file. | ||
/// </summary> | ||
public class Voicebank { | ||
|
||
private Voicebank() { | ||
} | ||
|
||
public string BasePath { private set; get; } | ||
public string OtoFile { private set; get; } | ||
public List<Oto> OtoList { private set; get; } | ||
public Encoding OtoEncoding { private set; get; } | ||
public Encoding PathEncoding { private set; get; } | ||
|
||
public class Builder { | ||
private readonly Voicebank voicebank; | ||
private readonly byte[] otoBytes; | ||
private int audioFilesFound; | ||
|
||
public Builder(string otoFile) { | ||
otoBytes = File.ReadAllBytes(otoFile); | ||
voicebank = new Voicebank() { | ||
OtoFile = otoFile, | ||
BasePath = Path.GetDirectoryName(otoFile), | ||
PathEncoding = Encoding.Default, | ||
}; | ||
} | ||
|
||
public string TestOtoEncoding(Encoding encoding) { | ||
return encoding.GetString(otoBytes); | ||
} | ||
|
||
public Builder SetOtoEncoding(Encoding encoding) { | ||
voicebank.OtoEncoding = encoding; | ||
var lines = new List<string>(); | ||
using (var stream = new StreamReader(new MemoryStream(otoBytes), encoding)) { | ||
while (!stream.EndOfStream) { | ||
lines.Add(stream.ReadLine()); | ||
} | ||
} | ||
var otoList = new List<Oto>(); | ||
foreach (var line in lines) { | ||
var oto = Oto.Parse(line); | ||
if (oto != null) { | ||
otoList.Add(oto); | ||
} | ||
} | ||
voicebank.OtoList = otoList; | ||
return this; | ||
} | ||
|
||
public double TestPathEncoding(Encoding encoding) { | ||
if (voicebank.OtoList == null) { | ||
return 0; | ||
} | ||
if (voicebank.OtoList.Count == 0) { | ||
return 1; | ||
} | ||
audioFilesFound = 0; | ||
foreach (var oto in voicebank.OtoList) { | ||
try { | ||
var file = encoding.GetString(voicebank.OtoEncoding.GetBytes(oto.AudioFile)); | ||
if (File.Exists(Path.Combine(voicebank.BasePath, file))) { | ||
audioFilesFound++; | ||
} | ||
} catch { } | ||
} | ||
return (double)audioFilesFound / voicebank.OtoList.Count; | ||
} | ||
|
||
public Builder SetPathEncoding(Encoding encoding) { | ||
voicebank.PathEncoding = encoding; | ||
return this; | ||
} | ||
|
||
public Voicebank Build() { | ||
var score = TestPathEncoding(voicebank.PathEncoding); | ||
Log.Information("Loaded {0} otos and {1:F2}% audio files from {2}", | ||
voicebank.OtoList.Count, score * 100, voicebank.OtoFile); | ||
return voicebank; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.IO.Compression; | ||
using System.Text; | ||
using Serilog; | ||
|
||
namespace OpenUtau.Classic { | ||
|
||
internal class VoicebankInstaller { | ||
|
||
public static void IndexAllArchive(IEnumerable<string> searchPaths) { | ||
foreach (var path in searchPaths) { | ||
if (Directory.Exists(path)) { | ||
var zips = Directory.GetFiles(path, "*.zip", SearchOption.AllDirectories); | ||
foreach (var zip in zips) { | ||
Log.Information($"{zip}"); | ||
IndexArchive(zip); | ||
} | ||
} | ||
} | ||
} | ||
|
||
public static void IndexArchive(string path) { | ||
using (var stream = new FileStream(path, FileMode.Open)) { | ||
using (var archive = new ZipArchive(stream, ZipArchiveMode.Read, false, Encoding.GetEncoding("shift_jis"))) { | ||
foreach (var entry in archive.Entries) { | ||
if (entry.Name == "character.txt" || entry.Name == "oto.ini") { | ||
Log.Information($"{entry.Name} {entry.FullName}"); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.