-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathVoicebankScanner.cs
More file actions
68 lines (54 loc) · 2.17 KB
/
Copy pathVoicebankScanner.cs
File metadata and controls
68 lines (54 loc) · 2.17 KB
1
2
3
4
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
using System;
using System.Collections.Generic;
using System.IO;
using TuneLab.SDK;
namespace DiffSingerForTuneLab;
// 在给定的一组根目录下发现 DiffSinger 物理模型包(返回去重后的根目录绝对路径列表)。
// 包判别:含声学主配置 dsconfig.yaml,且含 character 元数据文件。
// 预测器子目录(dsdur / dspitch / dsvariance)也各自带 dsconfig.yaml,但无 character.*——据此排除;
// 探到包后即不再下钻其子目录。合并(按 model id / voice id)与展示元数据交由 VoiceRegistry。
internal static class VoicebankScanner
{
const int MaxDepth = 6;
public static List<string> Scan(IEnumerable<string> roots, ILogger logger)
{
var result = new List<string>();
var seenPaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var root in roots)
{
if (string.IsNullOrWhiteSpace(root))
continue;
string full;
try { full = Path.GetFullPath(root); }
catch { continue; }
if (!Directory.Exists(full))
continue;
try { Walk(full, 0, result, seenPaths); }
catch (Exception ex) { logger.Warning($"扫描声库根目录失败 {full}: {ex.Message}"); }
}
return result;
}
static void Walk(string dir, int depth, List<string> result, HashSet<string> seenPaths)
{
if (IsVoicebank(dir))
{
if (seenPaths.Add(Path.GetFullPath(dir)))
result.Add(Path.GetFullPath(dir));
return; // 不下钻:子目录是 dsdur / dspitch / dsvariance 等预测器
}
if (depth >= MaxDepth)
return;
string[] subDirs;
try { subDirs = Directory.GetDirectories(dir); }
catch { return; }
foreach (var sub in subDirs)
Walk(sub, depth + 1, result, seenPaths);
}
static bool IsVoicebank(string dir)
{
if (!File.Exists(Path.Combine(dir, "dsconfig.yaml")))
return false;
return File.Exists(Path.Combine(dir, "character.yaml"))
|| File.Exists(Path.Combine(dir, "character.txt"));
}
}