Skip to content

Commit 35ea582

Browse files
committed
LyricTool: update analyzer
1 parent 3858549 commit 35ea582

File tree

7 files changed

+237
-32
lines changed

7 files changed

+237
-32
lines changed

src/plugins/lyrictool/core/lang/ilanguageanalyzer.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,22 @@ namespace LyricTool {
1313
}
1414

1515
ILanguageAnalyzer::ILanguageAnalyzer(const QString &id, QObject *parent)
16-
: ILanguageAnalyzer(*new ILanguageAnalyzerPrivate(), id, parent) {
16+
: ILanguageAnalyzer(*new ILanguageAnalyzerPrivate(), id, parent) {
1717
}
1818

1919
ILanguageAnalyzer::~ILanguageAnalyzer() = default;
2020

2121
void ILanguageAnalyzer::correct(const QList<LyricInfo> &input) const {
2222
for (const auto &note : input) {
23-
if (note.language() == "Unknown") {
23+
if (note.language() == QStringLiteral("Unknown")) {
2424
if (contains(note.lyric()))
2525
note.language() = id();
2626
}
2727
}
2828
}
2929

3030
QString ILanguageAnalyzer::analyze(const QString &input) const {
31-
return contains(input) ? id() : "Unknown";
31+
return contains(input) ? id() : QStringLiteral("Unknown");
3232
}
3333

3434
QList<LyricInfo> ILanguageAnalyzer::split(const QList<LyricInfo> &input) const {
@@ -39,7 +39,7 @@ namespace LyricTool {
3939

4040
QList<LyricInfo> result;
4141
for (const auto &note : input) {
42-
if (note.language() == "Unknown" ) {
42+
if (note.language() == QStringLiteral("Unknown")) {
4343
const auto splitRes = split(note.lyric());
4444
for (const auto &res : splitRes) {
4545
if (res.language() == id() && d->discardResult) {
@@ -56,11 +56,11 @@ namespace LyricTool {
5656

5757
QList<LyricInfo> ILanguageAnalyzer::split(const QString &input) const {
5858
Q_UNUSED(input);
59-
return QList<LyricInfo>();
59+
return {};
6060
}
6161

6262
QString ILanguageAnalyzer::randString() const {
63-
return QString();
63+
return {};
6464
}
6565

6666
bool ILanguageAnalyzer::contains(const QString &input) const {
@@ -78,6 +78,11 @@ namespace LyricTool {
7878
return d->id;
7979
}
8080

81+
QVariantMap ILanguageAnalyzer::g2pConfig() {
82+
Q_D(const ILanguageAnalyzer);
83+
return d->m_g2pConfig;
84+
}
85+
8186
QString ILanguageAnalyzer::displayName() const {
8287
Q_D(const ILanguageAnalyzer);
8388
return d->displayName;
@@ -108,6 +113,16 @@ namespace LyricTool {
108113
d->categroy = category;
109114
}
110115

116+
QString ILanguageAnalyzer::selectedG2p() const {
117+
Q_D(const ILanguageAnalyzer);
118+
return d->m_selectedG2p;
119+
}
120+
121+
void ILanguageAnalyzer::setG2p(const QString &g2pId) {
122+
Q_D(ILanguageAnalyzer);
123+
d->m_selectedG2p = g2pId;
124+
}
125+
111126
bool ILanguageAnalyzer::enabled() const {
112127
Q_D(const ILanguageAnalyzer);
113128
return d->enabled;

src/plugins/lyrictool/core/lang/ilanguageanalyzer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ namespace LyricTool {
3333

3434
public:
3535
QString id() const;
36+
QVariantMap g2pConfig();
3637

3738
QString displayName() const;
3839
void setDisplayName(const QMDisplayString &displayName);
@@ -44,6 +45,9 @@ namespace LyricTool {
4445
QString category() const;
4546
void setCategory(const QString &category);
4647

48+
QString selectedG2p() const;
49+
void setG2p(const QString &g2pId);
50+
4751
bool enabled() const;
4852
void setEnabled(const bool &enable);
4953

src/plugins/lyrictool/core/languagemanager.cpp

Lines changed: 191 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,59 +22,229 @@ namespace LyricTool {
2222
bool LanguageManager::load(QString *errorMessage) {
2323
return false;
2424
}
25+
2526
ILanguageAnalyzer *LanguageManager::language(const QString &id) const {
26-
return nullptr;
27+
Q_D(const LanguageManager);
28+
return d->languages.value(id);
2729
}
30+
2831
QList<ILanguageAnalyzer *> LanguageManager::languages() const {
29-
return {};
32+
Q_D(const LanguageManager);
33+
return d->languages.values_qlist();
3034
}
31-
bool LanguageManager::addLanguage(ILanguageAnalyzer *factory) {
32-
return false;
35+
36+
bool LanguageManager::addLanguage(ILanguageAnalyzer *analyzer) {
37+
Q_D(LanguageManager);
38+
if (!analyzer) {
39+
qWarning() << "LyricTool::LanguageManager::addLanguage(): trying to add null analyzer";
40+
return false;
41+
}
42+
if (d->languages.contains(analyzer->id())) {
43+
qWarning()
44+
<< "LyricTool::LanguageManager::addLanguage(): trying to add duplicated analyzer:"
45+
<< analyzer->id();
46+
return false;
47+
}
48+
analyzer->setParent(this);
49+
d->languages.append(analyzer->id(), analyzer);
50+
return true;
3351
}
34-
bool LanguageManager::removeLanguage(const ILanguageAnalyzer *factory) {
35-
return false;
52+
53+
bool LanguageManager::removeLanguage(const ILanguageAnalyzer *analyzer) {
54+
if (analyzer == nullptr) {
55+
qWarning()
56+
<< "LyricTool::LanguageManager::removeLanguage(): trying to remove null analyzer";
57+
return false;
58+
}
59+
return removeLanguage(analyzer->id());
3660
}
61+
3762
bool LanguageManager::removeLanguage(const QString &id) {
38-
return false;
63+
Q_D(LanguageManager);
64+
const auto it = d->languages.find(id);
65+
if (it == d->languages.end()) {
66+
qWarning() << "LyricTool::LanguageManager::removeLanguage(): analyzer does not exist:"
67+
<< id;
68+
return false;
69+
}
70+
it.value()->setParent(nullptr);
71+
d->languages.erase(it);
72+
return true;
3973
}
74+
4075
void LanguageManager::clearLanguages() {
76+
Q_D(LanguageManager);
77+
d->languages.clear();
4178
}
79+
4280
IG2pConverter *LanguageManager::g2p(const QString &id) const {
43-
return nullptr;
81+
Q_D(const LanguageManager);
82+
return d->g2ps.value(id);
4483
}
84+
4585
QList<IG2pConverter *> LanguageManager::g2ps() const {
46-
return {};
86+
Q_D(const LanguageManager);
87+
return d->g2ps.values_qlist();
4788
}
48-
bool LanguageManager::addG2p(ILanguageAnalyzer *factory) {
49-
return false;
89+
90+
bool LanguageManager::addG2p(IG2pConverter *converter) {
91+
Q_D(LanguageManager);
92+
if (!converter) {
93+
qWarning() << "LyricTool::LanguageManager::addG2p(): trying to add null converter";
94+
return false;
95+
}
96+
if (d->g2ps.contains(converter->id())) {
97+
qWarning()
98+
<< "LyricTool::LanguageManager::addG2p(): trying to add duplicated converter:"
99+
<< converter->id();
100+
return false;
101+
}
102+
converter->setParent(this);
103+
d->g2ps.append(converter->id(), converter);
104+
return true;
50105
}
51-
bool LanguageManager::removeG2p(const ILanguageAnalyzer *factory) {
52-
return false;
106+
107+
bool LanguageManager::removeG2p(const IG2pConverter *converter) {
108+
if (converter == nullptr) {
109+
qWarning()
110+
<< "LyricTool::LanguageManager::removeG2p(): trying to remove null converter";
111+
return false;
112+
}
113+
return removeG2p(converter->id());
53114
}
115+
54116
bool LanguageManager::removeG2p(const QString &id) {
55-
return false;
117+
Q_D(LanguageManager);
118+
auto it = d->g2ps.find(id);
119+
if (it == d->g2ps.end()) {
120+
qWarning() << "LyricTool::LanguageManager::removeG2p(): converter does not exist:"
121+
<< id;
122+
return false;
123+
}
124+
it.value()->setParent(nullptr);
125+
d->g2ps.erase(it);
126+
return true;
56127
}
128+
57129
void LanguageManager::clearG2ps() {
130+
Q_D(LanguageManager);
131+
d->g2ps.clear();
58132
}
133+
59134
QStringList LanguageManager::sortedLanguages() const {
60-
return QStringList();
135+
Q_D(const LanguageManager);
136+
return d->defaultSort;
61137
}
62-
void LanguageManager::setSortedLanguages(const QString &sortedLanguages) {
138+
139+
void LanguageManager::setSortedLanguages(const QStringList &sortedLanguages) {
140+
Q_D(LanguageManager);
141+
d->defaultSort = sortedLanguages;
142+
}
143+
144+
QList<ILanguageAnalyzer *>
145+
LanguageManager::priorityLanguages(const QStringList &priorityList) const {
146+
Q_D(const LanguageManager);
147+
QStringList order = d->defaultSort;
148+
149+
QList<ILanguageAnalyzer *> result;
150+
for (const auto &category : priorityList) {
151+
for (const auto &lang : order) {
152+
const auto analyzer = language(lang);
153+
if (analyzer->category() == category) {
154+
result.append(analyzer);
155+
}
156+
}
157+
}
158+
159+
for (const auto &id : order) {
160+
const auto analyzer = language(id);
161+
if (!result.contains(analyzer)) {
162+
result.append(analyzer);
163+
}
164+
}
165+
return result;
63166
}
167+
64168
QList<LyricInfo> LanguageManager::split(const QString &input) const {
65-
return QList<LyricInfo>();
169+
const auto analyzers = this->priorityLanguages();
170+
LyricInfo lyricInfo;
171+
lyricInfo.setLyric(input);
172+
QList<LyricInfo> result = {lyricInfo};
173+
174+
for (const auto &analyzer : analyzers) {
175+
result = analyzer->split(result);
176+
}
177+
return result;
66178
}
179+
67180
QList<LyricInfo> LanguageManager::correct(const QList<LyricInfo> &input) const {
68-
return QList<LyricInfo>();
181+
QList<LyricInfo> result = input;
182+
const auto analyzers = this->priorityLanguages();
183+
for (const auto &analyzer : analyzers) {
184+
analyzer->correct(result);
185+
}
186+
return result;
69187
}
188+
70189
QList<LyricInfo> LanguageManager::convert(const QList<LyricInfo> &input) const {
71-
return QList<LyricInfo>();
190+
QList<LyricInfo> result = input;
191+
192+
QMap<QString, QList<int>> languageIndexMap;
193+
QMap<QString, QStringList> languageLyricMap;
194+
195+
for (int i = 0; i < input.size(); ++i) {
196+
const LyricInfo &info = input.at(i);
197+
languageIndexMap[info.language()].append(i);
198+
languageLyricMap[info.language()].append(info.lyric());
199+
}
200+
201+
const auto languages = languageIndexMap.keys();
202+
for (const auto &language : languages) {
203+
const auto rawLyrics = languageLyricMap[language];
204+
const auto g2pFactory = this->g2p(this->language(language)->selectedG2p());
205+
const auto g2pConfig = this->language(language)->g2pConfig();
206+
207+
const auto tempRes = g2pFactory->convert(rawLyrics, g2pConfig);
208+
for (int i = 0; i < tempRes.size(); i++) {
209+
const auto index = languageIndexMap[language][i];
210+
result[index].setSyllable(tempRes[i].syllable());
211+
result[index].setError(tempRes[i].error());
212+
result[index].setCandidates(tempRes[i].candidates());
213+
}
214+
}
215+
return result;
72216
}
217+
73218
QString LanguageManager::analysis(const QString &input) const {
74-
return QString();
219+
QString result = QStringLiteral("Unknown");
220+
auto analyzers = this->priorityLanguages();
221+
222+
for (const auto &analyzer : analyzers) {
223+
result = analyzer->analyze(input);
224+
if (result != QStringLiteral("Unknown"))
225+
break;
226+
}
227+
228+
return result;
75229
}
230+
76231
QStringList LanguageManager::analysis(const QStringList &input) const {
77-
return QStringList();
232+
auto analyzers = this->priorityLanguages();
233+
QList<LyricInfo> rawInfo;
234+
for (const auto &lyric : input) {
235+
LyricInfo lyricInfo;
236+
lyricInfo.setLyric(lyric);
237+
rawInfo.append(lyricInfo);
238+
}
239+
240+
for (const auto &analyzer : analyzers) {
241+
analyzer->correct(rawInfo);
242+
}
243+
244+
QStringList result;
245+
for (const auto &info : rawInfo)
246+
result.append(info.language());
247+
return result;
78248
}
79249

80250
LanguageManager::LanguageManager(LanguageManagerPrivate &d, QObject *parent)

src/plugins/lyrictool/core/languagemanager.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,21 @@ namespace LyricTool {
2222

2323
ILanguageAnalyzer *language(const QString &id) const;
2424
QList<ILanguageAnalyzer *> languages() const;
25-
bool addLanguage(ILanguageAnalyzer *factory);
26-
bool removeLanguage(const ILanguageAnalyzer *factory);
25+
bool addLanguage(ILanguageAnalyzer *analyzer);
26+
bool removeLanguage(const ILanguageAnalyzer *analyzer);
2727
bool removeLanguage(const QString &id);
2828
void clearLanguages();
2929

3030
IG2pConverter *g2p(const QString &id) const;
3131
QList<IG2pConverter *> g2ps() const;
32-
bool addG2p(ILanguageAnalyzer *factory);
33-
bool removeG2p(const ILanguageAnalyzer *factory);
32+
bool addG2p(IG2pConverter *converter);
33+
bool removeG2p(const IG2pConverter *converter);
3434
bool removeG2p(const QString &id);
3535
void clearG2ps();
3636

3737
public:
3838
QStringList sortedLanguages() const;
39-
void setSortedLanguages(const QString &sortedLanguages);
39+
void setSortedLanguages(const QStringList &sortedLanguages);
4040

4141
QList<LyricInfo> split(const QString &input) const;
4242
QList<LyricInfo> correct(const QList<LyricInfo> &input) const;
@@ -46,6 +46,8 @@ namespace LyricTool {
4646
QStringList analysis(const QStringList &input) const;
4747

4848
protected:
49+
QList<ILanguageAnalyzer *> priorityLanguages(const QStringList &priorityList = {}) const;
50+
4951
LanguageManager(LanguageManagerPrivate &d, QObject *parent = nullptr);
5052

5153
QScopedPointer<LanguageManagerPrivate> d_ptr;

src/plugins/lyrictool/core/languagemanager_p.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ namespace LyricTool {
1919

2020
QMChronoMap<QString, ILanguageAnalyzer *> languages;
2121
QMChronoMap<QString, IG2pConverter *> g2ps;
22+
23+
QStringList defaultSort = {"Mandarin", "Pinyin", "Cantonese", "Kana", "Romaji", "English",
24+
"Space", "Slur", "Punctuation", "Number", "Linebreak", "Unknown"};
2225
};
2326

2427
}

0 commit comments

Comments
 (0)