• R/O
  • SSH
  • HTTPS

cadencii: コミット


コミットメタ情報

リビジョン1973 (tree)
日時2012-01-26 02:46:52
作者haruneko24

ログメッセージ

[stand2.0/StandConverter] Transcriber移植中(未完)

変更サマリ

差分

--- vConnect/trunk/stand2.0/StandConverter/gui/TranscribeWidget.cpp (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/gui/TranscribeWidget.cpp (nonexistent)
@@ -1,51 +0,0 @@
1-#include "TranscribeWidget.h"
2-#include "ui_TranscribeWidget.h"
3-
4-#include <QStringList>
5-
6-using namespace stand::gui;
7-
8-TranscribeWidget::TranscribeWidget(QWidget *parent, int index) :
9- QWidget(parent),
10- ui(new Ui::TranscribeWidget)
11-{
12- ui->setupUi(this);
13-
14- // Set ColorComboBox
15- QStringList colorNames;
16- colorNames << tr("red") << tr("green") << tr("blue") << tr("cyan") << tr("magenta") << tr("yellow") << tr("white");
17- QPalette pallete = ui->ColorSelector->palette();
18- pallete.setColor(QPalette::Highlight, Qt::transparent);
19-
20- int size = ui->ColorSelector->style()->pixelMetric(QStyle::PM_SmallIconSize);
21- QPixmap pixmap(size, size);
22-
23- for(unsigned int i = 0; i < colorNames.size(); i++)
24- {
25- QString name = colorNames.at(i);
26- ui->ColorSelector->addItem(name, QColor(i));
27- pixmap.fill(QColor(name));
28- ui->ColorSelector->setItemData(i, pixmap, Qt::DecorationRole);
29- }
30- ui->ColorSelector->setCurrentIndex(index % ui->ColorSelector->count());
31-}
32-
33-TranscribeWidget::~TranscribeWidget()
34-{
35- delete ui;
36-}
37-
38-QString TranscribeWidget::dir()
39-{
40- return ui->DirectoryName->text();
41-}
42-
43-int TranscribeWidget::bri()
44-{
45- return ui->BirghtnessSpinBox->value();
46-}
47-
48-int TranscribeWidget::note()
49-{
50- return ui->NoteSpinBox->value();
51-}
--- vConnect/trunk/stand2.0/StandConverter/gui/TranscribeWidget.h (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/gui/TranscribeWidget.h (nonexistent)
@@ -1,34 +0,0 @@
1-#ifndef TRANSCRIBEWIDGET_H
2-#define TRANSCRIBEWIDGET_H
3-
4-#include <QWidget>
5-
6-namespace Ui {
7-class TranscribeWidget;
8-}
9-
10-namespace stand
11-{
12-namespace gui
13-{
14-
15-class TranscribeWidget : public QWidget
16-{
17- Q_OBJECT
18-
19-public:
20- explicit TranscribeWidget(QWidget *parent = 0, int index = 0);
21- ~TranscribeWidget();
22-
23- QString dir();
24- int bri();
25- int note();
26-
27-private:
28- Ui::TranscribeWidget *ui;
29-};
30-
31-}
32-}
33-
34-#endif // TRANSCRIBEWIDGET_H
--- vConnect/trunk/stand2.0/StandConverter/gui/ConverterWindow.cpp (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/gui/ConverterWindow.cpp (revision 1973)
@@ -19,7 +19,7 @@
1919
2020 ConverterWindow::ConverterWindow(QWidget *parent) :
2121 QMainWindow(parent),
22- ui(new Ui::ConverterWindow)
22+ ui(new Ui::ConverterWindow())
2323 {
2424 ui->setupUi(this);
2525 isAnalyzing = false;
@@ -44,7 +44,7 @@
4444 val = (QMessageBox::StandardButton)(QMessageBox::warning(
4545 this,
4646 tr("Confirmation"),
47- tr("Converter is analyzing. Do you want to exit anyway?"),
47+ tr("Converter is still running. Do you want to exit anyway?"),
4848 QMessageBox::Yes,
4949 QMessageBox::No));
5050 }
@@ -239,14 +239,16 @@
239239
240240 void ConverterWindow::converterFinished(bool f)
241241 {
242- isAnalyzing = false;
243- setEditorEnabled(true);
244242 // 変換が失敗したと聞いて.
245243 if(!f)
246244 {
247245 _errorMessage(QObject::tr("Error occured in converting."));
248246 }
247+ currentConverter->disconnect();
248+ currentConverter->wait();
249249 // 処理が終了したので変換器を殺しても大丈夫.
250250 delete currentConverter;
251251 currentConverter = NULL;
252+ isAnalyzing = false;
253+ setEditorEnabled(true);
252254 }
--- vConnect/trunk/stand2.0/StandConverter/gui/TranscriberWidget.cpp (nonexistent)
+++ vConnect/trunk/stand2.0/StandConverter/gui/TranscriberWidget.cpp (revision 1973)
@@ -0,0 +1,69 @@
1+#include "TranscriberWidget.h"
2+#include "ui_TranscriberWidget.h"
3+
4+#include <QStringList>
5+#include <QFileDialog>
6+#include <QDir>
7+#include <QTextCodec>
8+
9+using namespace stand::gui;
10+
11+TranscriberWidget::TranscriberWidget(QWidget *parent, int index) :
12+ QWidget(parent),
13+ ui(new Ui::TranscriberWidget)
14+{
15+ ui->setupUi(this);
16+
17+ // Set ColorComboBox
18+ QStringList colorNames;
19+ colorNames << tr("red") << tr("green") << tr("blue") << tr("cyan") << tr("magenta") << tr("yellow") << tr("white");
20+ QPalette pallete = ui->ColorSelector->palette();
21+ pallete.setColor(QPalette::Highlight, Qt::transparent);
22+
23+ int size = ui->ColorSelector->style()->pixelMetric(QStyle::PM_SmallIconSize);
24+ QPixmap pixmap(size, size);
25+
26+ for(unsigned int i = 0; i < colorNames.size(); i++)
27+ {
28+ QString name = colorNames.at(i);
29+ ui->ColorSelector->addItem(name, QColor(i));
30+ pixmap.fill(QColor(name));
31+ ui->ColorSelector->setItemData(i, pixmap, Qt::DecorationRole);
32+ }
33+ ui->ColorSelector->setCurrentIndex(index % ui->ColorSelector->count());
34+}
35+
36+TranscriberWidget::~TranscriberWidget()
37+{
38+ delete ui;
39+}
40+
41+QString TranscriberWidget::dir()
42+{
43+ return ui->DirectoryName->text();
44+}
45+
46+int TranscriberWidget::bri()
47+{
48+ return ui->BirghtnessSpinBox->value();
49+}
50+
51+int TranscriberWidget::note()
52+{
53+ return ui->NoteSpinBox->value();
54+}
55+
56+void TranscriberWidget::openDirDialog()
57+{
58+ QString dirName = QFileDialog::getExistingDirectory(
59+ this,
60+ tr("Select input directory."),
61+ tr("")
62+ );
63+ ui->DirectoryName->setText(dirName);
64+}
65+
66+QTextCodec *TranscriberWidget::codec()
67+{
68+ return QTextCodec::codecForName(ui->EncodeComboBox->currentText().toLocal8Bit().data());
69+}
--- vConnect/trunk/stand2.0/StandConverter/gui/TranscriberWindow.cpp (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/gui/TranscriberWindow.cpp (revision 1973)
@@ -1,7 +1,13 @@
11 #include "TranscriberWindow.h"
22 #include "ui_TranscriberWindow.h"
33
4+#include "TranscriberWidget.h"
5+#include "../synthesis/Transcriber.h"
6+#include "../synthesis/TranscriberSetting.h"
7+#include "../io/UtauLibrary.h"
8+
49 #include <QMessageBox>
10+#include <QCloseEvent>
511
612 using namespace stand::gui;
713
@@ -17,7 +23,11 @@
1723 ui->SettingTabs->removeTab(0);
1824 delete p;
1925 }
20- ui->SettingTabs->addTab(new TranscribeWidget(this), tr("Base"));
26+ ui->SettingTabs->addTab(new TranscriberWidget(this), tr("Base"));
27+
28+ isAnalyzing = false;
29+ current = NULL;
30+ _setItemEnabled();
2131 }
2232
2333 TranscriberWindow::~TranscriberWindow()
@@ -27,7 +37,28 @@
2737
2838 void TranscriberWindow::closeEvent(QCloseEvent *e)
2939 {
40+ QMessageBox::StandardButton val = QMessageBox::Yes;
3041
42+ // 分析中ならユーザにお伺いを立てる.
43+ if(isAnalyzing)
44+ {
45+ val = (QMessageBox::StandardButton)(QMessageBox::warning(
46+ this,
47+ tr("Confirmation"),
48+ tr("Transcriber is still running. Do you want to exit anyway?"),
49+ QMessageBox::Yes,
50+ QMessageBox::No));
51+ }
52+
53+ // ユーザの希望の処理をする.
54+ if(val == QMessageBox::Yes)
55+ {
56+ e->accept();
57+ }
58+ else
59+ {
60+ e->ignore();
61+ }
3162 }
3263
3364 void TranscriberWindow::addTab()
@@ -36,7 +67,7 @@
3667 QString num;
3768 num.setNum(index);
3869
39- ui->SettingTabs->addTab(new TranscribeWidget(this, index), tr("Opt. ") + num);
70+ ui->SettingTabs->addTab(new TranscriberWidget(this, index), tr("Opt. ") + num);
4071 }
4172
4273 void TranscriberWindow::removeTab()
@@ -59,3 +90,117 @@
5990 ui->SettingTabs->removeTab(index);
6091 delete p;
6192 }
93+
94+void TranscriberWindow::_setItemEnabled()
95+{
96+ ui->AnalyzeButton->setText((isAnalyzing)?tr("Cancel"):tr("Analyze"));
97+
98+ ui->AddButton->setEnabled(!isAnalyzing);
99+ ui->MappingView->setEnabled(!isAnalyzing);
100+ ui->NumThreads->setEnabled(!isAnalyzing);
101+ if(!isAnalyzing)
102+ {
103+ ui->ProgressBar->setValue(0);
104+ }
105+ ui->ProgressBar->setEnabled(isAnalyzing);
106+ ui->RemoveButton->setEnabled(!isAnalyzing);
107+ ui->SettingTabs->setEnabled(!isAnalyzing);
108+}
109+
110+void TranscriberWindow::pushAnalyze()
111+{
112+ if(!isAnalyzing && !current)
113+ {
114+ _beginAnalyze();
115+ }
116+ else
117+ {
118+ _cancelAnalyze();
119+ }
120+}
121+
122+void TranscriberWindow::_beginAnalyze()
123+{
124+ stand::synthesis::TranscriberSetting s;
125+ // ToDo::Create Setting
126+
127+ if(!_createSetting(s))
128+ {
129+ QMessageBox::critical(this, tr("Error"), tr("Some settings are invalid."));
130+ return;
131+ }
132+ current = new stand::synthesis::Transcriber(s, this);
133+ connect(this, SIGNAL(sendCancelToTranscriber()), current, SLOT(cancel()));
134+ connect(current, SIGNAL(finish(bool)), SLOT(transcriptionFinished(bool)));
135+
136+ current->start();
137+ isAnalyzing = true;
138+ _setItemEnabled();
139+}
140+
141+void TranscriberWindow::_cancelAnalyze()
142+{
143+ QMessageBox::StandardButton ret;
144+ ret = (QMessageBox::StandardButton)(QMessageBox::warning(
145+ this,
146+ tr("Confirm"),
147+ tr("Do you really want to cancel transcription?"),
148+ QMessageBox::Yes,
149+ QMessageBox::No));
150+ if(ret != QMessageBox::Yes)
151+ {
152+ return;
153+ }
154+ emit sendCancelToTranscriber();
155+}
156+
157+bool TranscriberWindow::_createSetting(stand::synthesis::TranscriberSetting &s)
158+{
159+ s.numThreads = ui->NumThreads->value();
160+ s.base = new stand::io::UtauLibrary();
161+
162+ TranscriberWidget *w = dynamic_cast<TranscriberWidget *>(ui->SettingTabs->widget(0));
163+ QString filename = w->dir() + QDir::separator() + "oto.ini";
164+ if(!s.base->readFromOtoIni(filename, w->codec()))
165+ {
166+ QMessageBox::critical(this, tr("Error"), tr("Base file path is invalid\n") + filename);
167+ delete s.base;
168+ return false;
169+ }
170+ s.optionals.clear();
171+
172+ for(int i = 0; i < ui->SettingTabs->count() - 1; i++)
173+ {
174+ w = dynamic_cast<TranscriberWidget *>(ui->SettingTabs->widget(i + 1));
175+ QString filename = w->dir() + QDir::separator() + "oto.ini";
176+ stand::io::UtauLibrary *lib = new stand::io::UtauLibrary();
177+ if(lib->readFromOtoIni(filename, w->codec()))
178+ {
179+ s.optionals.push_back(lib);
180+ }
181+ else
182+ {
183+ QMessageBox::critical(this, tr("Error"), tr("Invalid file path\n") + filename);
184+ delete lib;
185+ delete s.base;
186+ for(int i = 0; i < s.optionals.size(); i++)
187+ {
188+ delete s.optionals.at(i);
189+ }
190+ return false;
191+ }
192+ }
193+ // ToDo::ばぶるそーーーーと!!
194+
195+ return true;
196+}
197+
198+void TranscriberWindow::transcriptionFinished(bool)
199+{
200+ current->disconnect();
201+ current->wait();
202+ delete current;
203+ current = NULL;
204+ isAnalyzing = false;
205+ _setItemEnabled();
206+}
--- vConnect/trunk/stand2.0/StandConverter/gui/TranscriberWidget.h (nonexistent)
+++ vConnect/trunk/stand2.0/StandConverter/gui/TranscriberWidget.h (revision 1973)
@@ -0,0 +1,39 @@
1+#ifndef TRANSCRIBERWIDGET_H
2+#define TRANSCRIBERWIDGET_H
3+
4+#include <QWidget>
5+
6+class QTextCodec;
7+
8+namespace Ui {
9+class TranscriberWidget;
10+}
11+
12+namespace stand
13+{
14+namespace gui
15+{
16+
17+class TranscriberWidget : public QWidget
18+{
19+ Q_OBJECT
20+public slots:
21+ void openDirDialog();
22+
23+public:
24+ explicit TranscriberWidget(QWidget *parent = 0, int index = 0ULL);
25+ ~TranscriberWidget();
26+
27+ QString dir();
28+ int bri();
29+ int note();
30+ QTextCodec *codec();
31+
32+private:
33+ Ui::TranscriberWidget *ui;
34+};
35+
36+}
37+}
38+
39+#endif // TRANSCRIBERWIDGET_H
--- vConnect/trunk/stand2.0/StandConverter/gui/TranscriberWindow.h (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/gui/TranscriberWindow.h (revision 1973)
@@ -9,6 +9,11 @@
99
1010 namespace stand
1111 {
12+namespace synthesis
13+{
14+class Transcriber;
15+class TranscriberSetting;
16+}
1217 namespace gui
1318 {
1419
@@ -15,9 +20,14 @@
1520 class TranscriberWindow : public QMainWindow
1621 {
1722 Q_OBJECT
23+signals:
24+ void sendCancelToTranscriber();
1825 public slots:
1926 void addTab();
2027 void removeTab();
28+
29+ void pushAnalyze();
30+ void transcriptionFinished(bool);
2131 public:
2232 explicit TranscriberWindow(QWidget *parent = 0);
2333 ~TranscriberWindow();
@@ -25,7 +35,16 @@
2535 void closeEvent(QCloseEvent *e);
2636
2737 private:
38+ void _beginAnalyze();
39+ void _cancelAnalyze();
40+ void _setItemEnabled();
41+
42+ bool _createSetting(stand::synthesis::TranscriberSetting &s);
43+
2844 Ui::TranscriberWindow *ui;
45+ stand::synthesis::Transcriber *current;
46+
47+ bool isAnalyzing;
2948 };
3049
3150 }
--- vConnect/trunk/stand2.0/StandConverter/io/StandFile.h (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/io/StandFile.h (revision 1973)
@@ -46,26 +46,77 @@
4646 int minBitrate,
4747 int maxBitrate,
4848 int averageBitrate);
49+
50+ static void matching(StandFile *src, StandFile *dst);
51+
52+ void setTimeAxis(double *t, int length);
53+
54+ void setBaseTimeAxis(double *base, int length);
55+
56+ qint32 tLen() const
57+ {
58+ return _tLen;
59+ }
60+
61+ qint32 cLen() const
62+ {
63+ return _cLen;
64+ }
65+
66+ qint32 fftl() const
67+ {
68+ return _fftl;
69+ }
70+
71+ qint32 fs() const
72+ {
73+ return _fs;
74+ }
75+
76+ float **MFCC()
77+ {
78+ return _MFCC;
79+ }
80+ float *f0()
81+ {
82+ return _f0;
83+ }
84+ qint32 baseTimeLength() const
85+ {
86+ return _baseTimeLength;
87+ }
88+ float *baseTimeAxis()
89+ {
90+ return _baseTimeAxis;
91+ }
92+
93+ float framePeriod() const
94+ {
95+ return _framePeriod;
96+ }
97+
98+
4999 private:
50100 void _create(int tLen, int cLen);
51101 void _destroy();
102+ static void _calculateVolumeEnvelope(double *dst, StandFile *src, int length);
52103
53104 // 32bit 実数型で定義したいが…
54- float **MFCC;
55- float *f0;
56- float *t;
57- float framePeriod;
105+ float **_MFCC;
106+ float *_f0;
107+ float *_t;
108+ float _framePeriod;
58109
59110
60- qint32 tLen; //! @brief 時間長
61- qint32 cLen; //! @brief ケプストラム長
111+ qint32 _tLen; //! @brief 時間長
112+ qint32 _cLen; //! @brief ケプストラム長
62113
63- qint32 fftl; //! @brief FFT 長
64- qint32 fs;
114+ qint32 _fftl; //! @brief FFT 長
115+ qint32 _fs;
65116
66117 // 時間伸縮用写像関数.
67- qint32 baseTimeLength;
68- float *baseTimeAxis;
118+ qint32 _baseTimeLength;
119+ float *_baseTimeAxis;
69120 };
70121
71122 }
--- vConnect/trunk/stand2.0/StandConverter/io/StandFile.cpp (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/io/StandFile.cpp (revision 1973)
@@ -1,9 +1,6 @@
11 #include "StandFile.h"
22
3-#include "../math/World.h"
4-#include "../math/MFCCSet.h"
5-#include "../math/FFTSet.h"
6-
3+#include "../math/MathSet.h"
74 #include "WaveFile.h"
85
96 #include "../utility/Utility.h"
@@ -17,12 +14,12 @@
1714
1815 StandFile::StandFile()
1916 {
20- baseTimeAxis = f0 = t = NULL;
21- MFCC = NULL;
22- baseTimeLength = tLen = cLen = 0;
17+ _baseTimeAxis = _f0 = _t = NULL;
18+ _MFCC = NULL;
19+ _baseTimeLength = _tLen = _cLen = 0;
2320 /* ぐぬぬぬ */
24- fftl = 2048;
25- fs = 44100;
21+ _fftl = 2048;
22+ _fs = 44100;
2623 }
2724
2825 StandFile::~StandFile()
@@ -32,21 +29,21 @@
3229
3330 void StandFile::_destroy()
3431 {
35- delete[] f0;
36- delete[] t;
37- if(MFCC)
32+ delete[] _f0;
33+ delete[] _t;
34+ if(_MFCC)
3835 {
39- delete[] MFCC[0];
36+ delete[] _MFCC[0];
4037 }
41- delete[] MFCC;
42- delete[] baseTimeAxis;
38+ delete[] _MFCC;
39+ delete[] _baseTimeAxis;
4340
44- baseTimeAxis = f0 = t = NULL;
45- MFCC = NULL;
46- baseTimeLength = tLen = cLen = 0;
41+ _baseTimeAxis = _f0 = _t = NULL;
42+ _MFCC = NULL;
43+ _baseTimeLength = _tLen = _cLen = 0;
4744 /* ぐぬぬぬ */
48- fftl = 2048;
49- fs = 44100;
45+ _fftl = 2048;
46+ _fs = 44100;
5047
5148 delete vorbis.data;
5249 vorbis.data = NULL;
@@ -55,22 +52,22 @@
5552
5653 void StandFile::_create(int tLen, int cLen)
5754 {
58- if(tLen <= 0 || cLen <= 0 || fftl <= 0)
55+ if(tLen <= 0 || cLen <= 0 || _fftl <= 0)
5956 {
60- qDebug("StandFile::_create(%d, %d, %d); // invalid args.", tLen, cLen, fftl);
57+ qDebug("StandFile::_create(%d, %d, %d); // invalid args.", tLen, cLen, _fftl);
6158 return;
6259 }
6360
64- f0 = new float[tLen];
65- t = new float[tLen];
66- MFCC = new float*[tLen];
67- MFCC[0] = new float[tLen * cLen];
61+ _f0 = new float[tLen];
62+ _t = new float[tLen];
63+ _MFCC = new float*[tLen];
64+ _MFCC[0] = new float[tLen * cLen];
6865 for(int i = 1; i < tLen; i++)
6966 {
70- MFCC[i] = MFCC[0] + i * cLen;
67+ _MFCC[i] = _MFCC[0] + i * cLen;
7168 }
72- this->tLen = tLen;
73- this->cLen = cLen;
69+ this->_tLen = tLen;
70+ this->_cLen = cLen;
7471 }
7572
7673 bool StandFile::read(const char *path)
@@ -83,17 +80,17 @@
8380 }
8481 _destroy();
8582
86- fread(&tLen, sizeof(qint32), 1, fp);
87- fread(&cLen, sizeof(qint32), 1, fp);
88- fread(&framePeriod, sizeof(float), 1, fp);
83+ fread(&_tLen, sizeof(qint32), 1, fp);
84+ fread(&_cLen, sizeof(qint32), 1, fp);
85+ fread(&_framePeriod, sizeof(float), 1, fp);
8986
90- _create(tLen, cLen);
87+ _create(_tLen, _cLen);
9188
92- for(int i = 0; i < tLen; i++) {
93- fread(MFCC[i], sizeof(float), cLen, fp);
89+ for(int i = 0; i < _tLen; i++) {
90+ fread(_MFCC[i], sizeof(float), _cLen, fp);
9491 }
95- fread(f0, sizeof(float), tLen, fp);
96- fread(t , sizeof(float), tLen, fp);
92+ fread(_f0, sizeof(float), _tLen, fp);
93+ fread(_t , sizeof(float), _tLen, fp);
9794
9895 fread(&vorbis.size, sizeof(qint32), 1, fp);
9996 vorbis.data = new char[vorbis.size];
@@ -100,13 +97,13 @@
10097 fread(vorbis.data, vorbis.size, 1, fp);
10198
10299 // 後方互換性と言う名の行き当たりばったり.仕様未だ定まらず.
103- if(fread(&baseTimeLength, sizeof(qint32), 1, fp) == 1 && baseTimeLength > 0)
100+ if(fread(&_baseTimeLength, sizeof(qint32), 1, fp) == 1 && _baseTimeLength > 0)
104101 {
105- baseTimeAxis = new float[baseTimeLength];
102+ _baseTimeAxis = new float[_baseTimeLength];
106103 }
107104 else
108105 {
109- baseTimeLength = 0;
106+ _baseTimeLength = 0;
110107 }
111108
112109 fclose(fp);
@@ -116,7 +113,7 @@
116113
117114 bool StandFile::write(const char *path)
118115 {
119- if(!f0 || !t || !MFCC || !vorbis.data)
116+ if(!_f0 || !_t || !_MFCC || !vorbis.data)
120117 {
121118 qDebug("StandFile::write(\"%s\"); // Empty Data.", path);
122119 return false;
@@ -128,24 +125,24 @@
128125 return false;
129126 }
130127
131- fwrite(&tLen, sizeof(qint32), 1, fp);
132- fwrite(&cLen, sizeof(qint32), 1, fp);
133- fwrite(&framePeriod, sizeof(float), 1, fp);
128+ fwrite(&_tLen, sizeof(qint32), 1, fp);
129+ fwrite(&_cLen, sizeof(qint32), 1, fp);
130+ fwrite(&_framePeriod, sizeof(float), 1, fp);
134131
135- for(int i = 0; i < tLen; i++)
132+ for(int i = 0; i < _tLen; i++)
136133 {
137- fwrite(MFCC[i], sizeof(float), cLen, fp);
134+ fwrite(_MFCC[i], sizeof(float), _cLen, fp);
138135 }
139- fwrite(f0, sizeof(float), tLen, fp);
140- fwrite(t , sizeof(float), tLen, fp);
136+ fwrite(_f0, sizeof(float), _tLen, fp);
137+ fwrite(_t , sizeof(float), _tLen, fp);
141138
142139 fwrite(&vorbis.size, sizeof(qint32), 1, fp);
143140 fwrite(vorbis.data, vorbis.size, 1, fp);
144141
145- if(baseTimeAxis)
142+ if(_baseTimeAxis)
146143 {
147- fwrite(&baseTimeLength, sizeof(qint32), 1, fp);
148- fwrite(baseTimeAxis, sizeof(float), baseTimeLength, fp);
144+ fwrite(&_baseTimeLength, sizeof(qint32), 1, fp);
145+ fwrite(_baseTimeAxis, sizeof(float), _baseTimeLength, fp);
149146 }
150147
151148 fclose(fp);
@@ -163,11 +160,11 @@
163160
164161 _destroy();
165162
166- this->framePeriod = (float)framePeriod;
167- this->tLen = samplesForDio(fs, xLen, framePeriod);
168- this->cLen = cepstrumLength;
169- this->fftl = FFTLengthForStar(fs);
170- this->fs = fs;
163+ this->_framePeriod = (float)framePeriod;
164+ this->_tLen = samplesForDio(fs, xLen, framePeriod);
165+ this->_cLen = cepstrumLength;
166+ this->_fftl = FFTLengthForStar(fs);
167+ this->_fs = fs;
171168
172169 World::WorldSetting s = {
173170 fs,
@@ -174,9 +171,9 @@
174171 framePeriod
175172 };
176173
177- World w(tLen , fftl, &s);
178- MFCCSet mfcc(fftl);
179- _create(tLen, cLen);
174+ World w(_tLen , _fftl, &s);
175+ MFCCSet mfcc(_fftl);
176+ _create(_tLen, _cLen);
180177
181178 /****************************************************/
182179 /* まず WORLD による分析を行う. */
@@ -185,23 +182,23 @@
185182 dio(x, xLen, fs, framePeriod, w.t(), w.f0());
186183 star(x, xLen, fs, w.t(), w.f0(), w.specgram());
187184
188- for(int i = 0; i < tLen; i++)
185+ for(int i = 0; i < _tLen; i++)
189186 {
190- this->f0[i] = (float)w.f0At(i);
191- this->t[i] = (float)w.tAt(i);
187+ this->_f0[i] = (float)w.f0At(i);
188+ this->_t[i] = (float)w.tAt(i);
192189 }
193190
194191 /* melCepstrum の計算 → specgram へ再度展開 */
195192 // 展開する場合は melCepstrum の歪み分を残差に持たせる形になる.
196- for(int i = 0; i < tLen; i++) {
193+ for(int i = 0; i < _tLen; i++) {
197194 // calculate MFCC
198195 double *wspec = w.spectrumAt(i);
199196 fftw_complex *mfcc_complex = mfcc.compute(wspec, fs);
200197
201198 // copy MFCC(double) to float array
202- for(int j = 0; j < cLen; j++)
199+ for(int j = 0; j < _cLen; j++)
203200 {
204- MFCC[i][j] = mfcc_complex[j][0] / fftl;
201+ _MFCC[i][j] = mfcc_complex[j][0] / _fftl;
205202 }
206203
207204 /*double *spectrum = mfcc.extract(MFCC[i], cLen, fs);
@@ -217,37 +214,195 @@
217214 /* 次に残差スペクトルを波形の形に持ち直す. */
218215 /* 保存形式は Ogg Vorbis */
219216 /****************************************************/
220- double *residualWave = new double[fftl * tLen];
217+ double *residualWave = new double[_fftl * _tLen];
221218
222- FFTSet fft(fftl, FFTSet::FFTW_C2R);
219+ FFTSet fft(_fftl, FFTSet::FFTW_C2R);
223220 // 残差波形を計算
224- for(int i = 0; i < tLen; i++)
221+ for(int i = 0; i < _tLen; i++)
225222 {
226223 fftw_complex *in = (fftw_complex *)fft.in();
227224 double *out = (double *)fft.out();
228225
229- World::extractResidual(in, w.residualAt(i), fftl);
226+ World::extractResidual(in, w.residualAt(i), _fftl);
230227
231228 fft.execute();
232229
233- for(int j = 0, k = i * fftl; j < fftl; j++, k++)
230+ for(int j = 0, k = i * _fftl; j < _fftl; j++, k++)
234231 {
235- residualWave[k] = out[j] / fftl;
232+ residualWave[k] = out[j] / _fftl;
236233 }
237234 }
238235
239- encodeToVorbis(residualWave, fftl * tLen, fs, minBitrate, maxBitrate, averageBitrate);
236+ encodeToVorbis(residualWave, _fftl * _tLen, fs, minBitrate, maxBitrate, averageBitrate);
240237
241238 delete[] residualWave;
242239
243- int yLen = tLen * s.framePeriod / 1000.0 * s.fs;
240+ int yLen = _tLen * s.framePeriod / 1000.0 * s.fs;
244241 double *y = new double[yLen];
245- for(int i = 0; i < yLen; i++){ y[i] = 0.0; }
246- stand::math::world::synthesis(w.f0(), w.specgram(), w.residual(), tLen, fftl, s.framePeriod, s.fs, y, yLen);
242+ for(int i = 0; i < yLen; i++)
243+ {
244+ y[i] = 0.0;
245+ }
246+/* stand::math::world::synthesis(w.f0(), w.specgram(), w.residual(), tLen, fftl, s.framePeriod, s.fs, y, yLen);
247247 stand::io::WaveFile wa(y, yLen);
248248
249249 wa.normalize();
250- wa.write("d:\\temp.wav");
250+ wa.write("d:\\temp.wav");*/
251251
252252 return true;
253253 }
254+
255+void StandFile::matching(StandFile *src, StandFile *dst)
256+{
257+ if(!src || !dst)
258+ {
259+ qDebug("StandFile::matching(%h, %h);", src, dst);
260+ return;
261+ }
262+ int src_len, dst_len;
263+ double *src_env, *dst_env;
264+ double *src_to_dst, *dst_to_src, *dst_to_src_stretched;
265+
266+ src_len = src->tLen();
267+ dst_len = dst->tLen();
268+
269+ src_env = new double[src_len];
270+ dst_env = new double[dst_len];
271+ src_to_dst = new double[src_len];
272+ dst_to_src = new double[dst_len];
273+ dst_to_src_stretched = new double[src_len];
274+
275+ // 振幅エンベロープを求めます.
276+ _calculateVolumeEnvelope(src_env, src, src_len);
277+ _calculateVolumeEnvelope(dst_env, dst, dst_len);
278+
279+ for( int i = 0; i < src_len - 1; i++ ){
280+ double tmp = (double)i / (double)src_len * (double)dst_len;
281+ if( tmp >= dst_len - 1 ){
282+ dst_to_src_stretched[i] = dst_env[dst_len-1];
283+ }else{
284+ dst_to_src_stretched[i] = stand::math::interpolateArray(tmp, dst_env);
285+ }
286+ }
287+ dst_to_src_stretched[src_len-1] = dst_env[dst_len-1];
288+
289+ stand::math::smoothMatching(dst_to_src_stretched, src_to_dst, src_env, dst_to_src_stretched, src_len);
290+
291+ double framePeriod = src->framePeriod();
292+ for( int i = 0; i < dst_len - 1; i++ ){
293+ double tmp = (double)i / (double)dst_len * (double)src_len;
294+ if( tmp >= src_len - 1 ){
295+ dst_to_src[i] = dst_to_src_stretched[src_len-1];
296+ }else{
297+ dst_to_src[i] = stand::math::interpolateArray(tmp, dst_to_src_stretched) * dst->framePeriod() / 1000.0 / (double)src_len * (double)dst_len;
298+ }
299+ }
300+ dst_to_src[dst_len-1] = dst_to_src_stretched[src_len-1] / (double)src_len * (double)dst_len;
301+
302+ for( int i = 0; i < src_len; i++ ){
303+ dst_to_src_stretched[i] = src_to_dst[i] * framePeriod / 1000.0;
304+ }
305+ memcpy( src_to_dst, dst_to_src_stretched, sizeof( double ) * src_len );
306+
307+ dst->setTimeAxis(dst_to_src, dst_len);
308+ dst->setBaseTimeAxis(src_to_dst, src_len);
309+
310+ delete[] dst_to_src_stretched;
311+ delete[] src_to_dst;
312+ delete[] dst_to_src;
313+ delete[] src_env;
314+ delete[] dst_env;
315+}
316+
317+void StandFile::_calculateVolumeEnvelope(double *dst, StandFile *src, int length)
318+{
319+ int fftl = src->fftl();
320+
321+ MFCCSet mfcc(fftl);
322+ FFTSet forward(fftl, FFTSet::FFTW_C2C_FORWARD);
323+ FFTSet inverse(fftl, FFTSet::FFTW_C2C_BACKWARD);
324+ FFTSet fromWave(fftl, FFTSet::FFTW_R2C);
325+ FFTSet toWave(fftl, FFTSet::FFTW_C2R);
326+
327+ OggVorbis_File ovf;
328+ src->open( &ovf );
329+ float **pcm_channels;
330+
331+ for( int i = 0; i < length; i++ ){
332+ int c;
333+ float *mel_cep = src->MFCC()[i];
334+ int mel_len = src->cLen();
335+ double sum = 0.0;
336+
337+ // ケプストラムからパワースペクトルを計算.
338+ double *pow_spec = mfcc.extract(mel_cep, mel_len, src->fs());
339+ fftw_complex *spectrum = stand::math::world::minimumPhaseSpectrum(pow_spec, fftl, &forward, &inverse);
340+
341+ // Ogg ストリームから残差波形をデコード.
342+ double *res_wave = (double *)fromWave.in();
343+ for(c = 0; c < fftl;)
344+ {
345+ int bitStream;
346+ long samples = ov_read_float( &ovf, &pcm_channels, fftl - c, &bitStream );
347+ if(samples <= 0)
348+ {
349+ break;
350+ }
351+ for(int j = 0, k = c; j < samples && k < fftl; j++, k++)
352+ {
353+ res_wave[k] = pcm_channels[0][j];
354+ }
355+ c += samples;
356+ }
357+
358+ // 残差スペクトルの計算.
359+ fromWave.execute();
360+ fftw_complex *res_spec = (fftw_complex *)fromWave.out();
361+ fftw_complex *wav_spec = (fftw_complex *)toWave.in();
362+
363+ for(int k = 0; k <= fftl / 2; k++)
364+ {
365+ wav_spec[k][0] = spectrum[k][0] * res_spec[k][0] - spectrum[k][1] * res_spec[k][1];
366+ wav_spec[k][1] = spectrum[k][1] * res_spec[k][0] + spectrum[k][0] * res_spec[k][1];
367+ }
368+
369+ toWave.execute();
370+ double *out = (double *)toWave.out();
371+
372+ for( int j = 0; j < fftl; j++ )
373+ {
374+ sum += out[j] * out[j];
375+ }
376+ dst[i] = sum;
377+ }
378+
379+ src->close(&ovf);
380+}
381+
382+
383+void StandFile::setTimeAxis(double *t, int length)
384+{
385+ if(length != _tLen)
386+ {
387+ return;
388+ }
389+ for(int i = 0; i < length; i++)
390+ {
391+ this->_t[i] = t[i];
392+ }
393+}
394+
395+void StandFile::setBaseTimeAxis(double *base, int length)
396+{
397+ if(length <= 0)
398+ {
399+ return;
400+ }
401+ delete[] _baseTimeAxis;
402+ _baseTimeAxis = new float[length];
403+ _baseTimeLength = length;
404+ for(int i = 0; i < length; i++)
405+ {
406+ this->_baseTimeAxis[i] = base[i];
407+ }
408+}
--- vConnect/trunk/stand2.0/StandConverter/math/MathSet.cpp (nonexistent)
+++ vConnect/trunk/stand2.0/StandConverter/math/MathSet.cpp (revision 1973)
@@ -0,0 +1,8 @@
1+#include "MathSet.h"
2+
3+double stand::math::interpolateArray( double x, const double *p )
4+{
5+ int t = (int)x;
6+ double r = x - (double)t;
7+ return ( p[t] * ( 1.0 - r ) + p[t+1] * r );
8+}
--- vConnect/trunk/stand2.0/StandConverter/math/MathSet.h (nonexistent)
+++ vConnect/trunk/stand2.0/StandConverter/math/MathSet.h (revision 1973)
@@ -0,0 +1,24 @@
1+#ifndef MATHSET_H
2+#define MATHSET_H
3+
4+#include <math.h>
5+
6+#include "FFTSet.h"
7+#include "MFCCSet.h"
8+#include "World.h"
9+#include "SmootMatching.h"
10+
11+namespace stand
12+{
13+namespace math
14+{
15+/// <summary>配列の中間値を線形補間します.</summary>
16+/// <param name="x">配列のインデックス.</param>
17+/// <param name="p">配列</param>
18+/// <returns>配列の中間値を返します.</returns>
19+double interpolateArray(double x, const double *p);
20+
21+}
22+}
23+
24+#endif // MATHSET_H
--- vConnect/trunk/stand2.0/StandConverter/math/SmootMatching.cpp (nonexistent)
+++ vConnect/trunk/stand2.0/StandConverter/math/SmootMatching.cpp (revision 1973)
@@ -0,0 +1,230 @@
1+#include "SmootMatching.h"
2+
3+#include "MathSet.h"
4+
5+#include <stdlib.h>
6+#include <string.h>
7+#include <math.h>
8+#include <float.h>
9+
10+using namespace stand::math;
11+
12+//! @brief 一回微分と二階微分を計算します.
13+static void get_graduation(double* src, double* dst, int length,
14+ double *d1s, double *d2s, double *d1d, double *d2d);
15+
16+//! @brief 対数軸上で最大値ゼロで正規化します.
17+static void log_normalize_infinite( double* dst, int length );
18+
19+//! @brief 写像関数を DP で求める際の枝の重みを計算します.
20+static double get_cost( double* src, double* dst, int i, int j, int n, int m,
21+ double *d1d, double *d2d, double *d1s, double *d2s);
22+
23+/* 許容する傾きの最大値 */
24+const double GRAD = 2.0;
25+/* 変形関数の傾きに対する重み */
26+const double G_WEIGHT = 1.5;
27+
28+void get_graduation( double* src, double* dst, int length,
29+ double *d1s, double *d2s, double *d1d, double *d2d)
30+{
31+ /* 導関数の数値を計算 */
32+ double *temp_spectrum = (double*)malloc(sizeof(double) * length);
33+ memset( temp_spectrum,0,sizeof(double)*length );
34+
35+ for( int i = 1; i < length; i++ )
36+ temp_spectrum[i] = fabs( dst[i] - dst[i-1] );
37+ for( int i = 0; i < length - 1; i++ )
38+ d1d[i] = 0.5 * ( temp_spectrum[i] + temp_spectrum[i+1] );
39+ d1d[length-1] = 0.0;
40+
41+ for( int i = 1; i < length; i++ )
42+ temp_spectrum[i] = fabs( d1d[i] - d1d[i-1] );
43+ for( int i = 0; i < length - 1; i++ )
44+ d2d[i] = 0.5 * ( temp_spectrum[i] + temp_spectrum[i+1] );
45+ d2d[length-1] = 0.0;
46+
47+ for( int i = 1; i < length; i++ )
48+ temp_spectrum[i] = fabs( src[i] - src[i-1] );
49+ for( int i = 0; i < length - 1; i++ )
50+ d1s[i] = 0.5 * ( temp_spectrum[i] + temp_spectrum[i+1] );
51+ d1s[length-1] = 0.0;
52+
53+ for( int i = 1; i < length; i++ )
54+ temp_spectrum[i] = fabs( d1s[i] - d1s[i-1] );
55+ for( int i = 0; i < length - 1; i++ )
56+ d2s[i] = 0.5 * ( temp_spectrum[i] + temp_spectrum[i+1] );
57+ d2s[length-1] = 0.0;
58+
59+ free(temp_spectrum);
60+}
61+
62+void log_normalize_infinite( double* dst, int length )
63+{
64+ /* 正規化の結果は0~1の範囲になる. */
65+ int i;
66+ double min_v = DBL_MAX, max_v = DBL_MIN;
67+ for( i = 0; i < length; i++ ){
68+ if( dst[i] < min_v )
69+ min_v = dst[i];
70+ if( dst[i] > max_v )
71+ max_v = dst[i];
72+ }
73+ for( i = 0; i < length; i++ )
74+ dst[i] = log( dst[i] / min_v ) / log( max_v );
75+}
76+
77+double get_cost( double* src, double* dst, int i, int j, int n, int m,
78+ double *d1d, double *d2d, double *d1s, double *d2s)
79+{
80+ int k;
81+ double temp, rate, sum;
82+
83+ if( n > m * GRAD || m > n * GRAD )
84+ return DBL_MAX;
85+
86+ rate = temp = (double)n / (double)m;
87+ sum = 0.0;
88+
89+ if( rate > 1.0 )
90+ rate = 1.0 / rate;
91+ if( m >= n ){
92+ for( k = 1; k <= m; k++ ){
93+ sum += fabs( interpolateArray( (double)i + (double)k * temp, src ) - dst[j+k] );
94+ sum += fabs( interpolateArray( (double)i + (double)k * temp, d1s ) / temp - d1d[j+k] );
95+ sum += 0.5 * fabs( interpolateArray( (double)i + (double)k * temp, d2s ) / pow( temp, 2.0 ) - d2d[j+k] );
96+ }
97+ temp = m;
98+ temp = sqrt( (double)( m*m + n*n ) ) / temp;
99+ sum *= temp;
100+ }else{
101+ for( k = 1; k <= n; k++ ){
102+ sum += fabs( src[i+k] - interpolateArray( (double)j + (double)k / temp, dst ) );
103+ sum += fabs( d1s[i+k] - interpolateArray( (double)j + (double)k / temp, d1d ) * temp );
104+ sum += 0.5 * fabs( d2s[i+k] - interpolateArray( (double)j + (double)k / temp, d2d ) * pow( temp, 2.0 ) );
105+ }
106+ temp = n;
107+ temp = sqrt( (double)( m*m + n*n ) ) / temp;
108+ sum *= temp;
109+ }
110+ rate = 1.0 + G_WEIGHT * pow( 1.0 - rate, 2.0 );
111+
112+ return sum * rate;
113+}
114+
115+void stand::math::smoothMatching(double* T, double* H, double* src_s, double* dst_s, int length)
116+{
117+ int i, j, k, l, n, m, tx, ty;
118+ double **dpMap;
119+ double tempd, g1, g2;
120+ int **pathX, **pathY;
121+
122+ double* src = (double*)malloc( sizeof(double)*length );
123+ double* dst = (double*)malloc( sizeof(double)*length );
124+ double *d1d = (double*)malloc( sizeof(double)*length );
125+ double *d2d = (double*)malloc( sizeof(double)*length );
126+ double *d1s = (double*)malloc( sizeof(double)*length );
127+ double *d2s = (double*)malloc( sizeof(double)*length );
128+
129+ memcpy( src, src_s, sizeof(double)*length );
130+ memcpy( dst, dst_s, sizeof(double)*length );
131+
132+ /* メモリの確保と値の初期化 */
133+ dpMap = (double **)malloc( sizeof(double *) * length );
134+ pathX = (int **)malloc( sizeof(int *) * length );
135+ pathY = (int **)malloc( sizeof(int *) * length );
136+ for( i = 0; i < length; i++ ){
137+ dpMap[i] = (double *)malloc( sizeof(double) * 1100); //length );
138+ for( j = 0; j < 1100; j++ ) //length; j++ )
139+ dpMap[i][j] = 1000000000.0;
140+ pathX[i] = (int *)malloc( sizeof(int) * 1100); //length );
141+ pathY[i] = (int *)malloc( sizeof(int) * 1100); //length );
142+ memset( pathX[i], -1, sizeof(int) * 1100); //length );
143+ memset( pathY[i], -1, sizeof(int) * 1100); //length );
144+ }
145+ pathX[0][512] = pathY[0][512] = 0;
146+ dpMap[0][512] = fabs( dst[0] - src[0] );
147+
148+
149+ /* 導関数を算出 */
150+ get_graduation( src, dst, length, d1s, d2s, d1d, d2d );
151+
152+ /* 最短経路を求めてマッチング */
153+ for( i = 0; i < length; i++ ){
154+ for( j = 0; j < length; j++ ){
155+ if( abs(i - j) > 48 ) /* 領域を直指定するなんて... */
156+ continue;
157+ /* 現在点における傾き */
158+ tx = pathX[i][j-i+512]; ty = pathY[i][j-i+512];
159+ if( i == tx || j == ty )
160+ g1 = 1.0;
161+ else
162+ g1 = (double)( j - ty ) / (double)( i - tx );
163+ /* 分割はあまり増やしても意味が無いみたい */
164+ for( n = 1; n < 8; n++ ){
165+ if( i + n >= length )
166+ break;
167+ for( m = 1; m < 8; m++ ){
168+ if( j + m >= length )
169+ break;
170+ /* 目標点における傾き */
171+ g2 = (double)m / (double)n;
172+ if( g2 > g1 )
173+ tempd = dpMap[i][j-i+512] + get_cost( src, dst, i, j, n, m, d1d, d2d, d1s, d2s ) * g2 / g1;
174+ else
175+ tempd = dpMap[i][j-i+512] + get_cost( src, dst, i, j, n, m, d1d, d2d, d1s, d2s ) * g1 / g2;
176+ /* 最大値の更新 */
177+ if( i + n < length && j + m < length && dpMap[i+n][j+m-(i+n)+512] > tempd ){
178+ dpMap[i+n][j+m-(i+n)+512] = tempd;
179+ pathX[i+n][j+m-(i+n)+512] = i;
180+ pathY[i+n][j+m-(i+n)+512] = j;
181+ }
182+ }
183+ }
184+ }
185+ }
186+
187+ T[0] = 0.0;
188+ l = j = length - 1;
189+
190+ while( l > 0 && j > 0 ){
191+ tx = pathX[l][j-l+512]; ty = pathY[l][j-l+512];
192+ for( k = l; k > tx; k-- )
193+ T[k] = (double)j - (double)( l - k ) * (double)( j - ty ) / (double)( l - tx );
194+ l = tx; j = ty;
195+ }
196+
197+ H[0] = 0.0;
198+ l = j = length - 1;
199+
200+ while( l > 0 && j > 0 ){
201+ tx = pathX[l][j-l+512]; ty = pathY[l][j-l+512];
202+ for( k = j; k > ty; k-- )
203+ H[k] = (double)j - (double)( j - k ) * (double)( l - tx ) / (double)( j - ty );
204+ l = tx; j = ty;
205+ }
206+
207+/* if(H){
208+ applyStretching( T, dst, length );
209+ for( i = 0; i < length; i++ )
210+ H[i] = src[i] - dst[i];
211+ }
212+*/
213+ /* メモリのお掃除 */
214+ for( i = 0; i < length; i++ ){
215+ free( dpMap[i] );
216+ free( pathX[i] );
217+ free( pathY[i] );
218+ }
219+ free( dpMap );
220+ free( pathX );
221+ free( pathY );
222+ free( src );
223+ free( dst );
224+ free( d1d );
225+ free( d2d );
226+ free( d1s );
227+ free( d2s );
228+
229+}
230+
--- vConnect/trunk/stand2.0/StandConverter/math/MinimumPhaseSpectrum.cpp (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/math/MinimumPhaseSpectrum.cpp (revision 1973)
@@ -6,7 +6,7 @@
66 using namespace stand::math;
77 using namespace stand::math::world;
88
9-void stand::math::world::minimumPhaseSpectrum(double *inputSpec, int fftl, FFTSet *forward, FFTSet *inverse)
9+fftw_complex *stand::math::world::minimumPhaseSpectrum(double *inputSpec, int fftl, FFTSet *forward, FFTSet *inverse)
1010 {
1111 int i;
1212
@@ -46,4 +46,5 @@
4646 dst[i][0] = exp(spectrum[i][0])*cos(spectrum[i][1]);
4747 dst[i][1] = exp(spectrum[i][0])*sin(spectrum[i][1]);
4848 }
49+ return dst;
4950 }
--- vConnect/trunk/stand2.0/StandConverter/math/SmootMatching.h (nonexistent)
+++ vConnect/trunk/stand2.0/StandConverter/math/SmootMatching.h (revision 1973)
@@ -0,0 +1,13 @@
1+#ifndef SMOOTMATCHING_H
2+#define SMOOTMATCHING_H
3+
4+namespace stand
5+{
6+namespace math
7+{
8+void smoothMatching(double* dst_to_src, double* src_to_dst, double* src_s, double* dst_s, int length);
9+void applyStretching(double *T, double* target, int length);
10+}
11+}
12+
13+#endif // SMOOTMATCHING_H
--- vConnect/trunk/stand2.0/StandConverter/math/MFCCSet.cpp (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/math/MFCCSet.cpp (revision 1973)
@@ -1,6 +1,6 @@
11 #include "MFCCSet.h"
22
3-#include <math.h>
3+#include "MathSet.h"
44
55 using namespace stand::math;
66
@@ -107,13 +107,6 @@
107107 }
108108 }
109109
110-double MFCCSet::interpolateArray( double x, const double *p )
111-{
112- int t = (int)x;
113- double r = x - (double)t;
114- return ( p[t] * ( 1.0 - r ) + p[t+1] * r );
115-}
116-
117110 double MFCCSet::getMelScale(double freq){
118111 double ret = 1127.01048 * log(1 + freq / 700);
119112 return ret;
--- vConnect/trunk/stand2.0/StandConverter/math/MinimumPhaseSpectrum.h (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/math/MinimumPhaseSpectrum.h (revision 1973)
@@ -10,7 +10,7 @@
1010 class FFTSet;
1111 namespace world
1212 {
13-void minimumPhaseSpectrum(double *inputSpec, int fftl, FFTSet *forward, stand::math::FFTSet *inverse);
13+fftw_complex *minimumPhaseSpectrum(double *inputSpec, int fftl, FFTSet *forward, stand::math::FFTSet *inverse);
1414 }
1515 }
1616 }
--- vConnect/trunk/stand2.0/StandConverter/math/MFCCSet.h (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/math/MFCCSet.h (revision 1973)
@@ -49,12 +49,6 @@
4949 /// <param name="maxFrequency">最大周波数.</param>
5050 static void stretchFromMelScale(double *spectrum, const double *melSpectrum, int spectrumLength, int maxFrequency);
5151
52- // このクラスか…?うーん.
53- /// <summary>配列の中間値を線形補間します.</summary>
54- /// <param name="x">配列のインデックス.</param>
55- /// <param name="p">配列</param>
56- /// <returns>配列の中間値を返します.</returns>
57- static double interpolateArray( double x, const double *p );
5852 private:
5953
6054 FFTSet *_ffft, *_ifft;
--- vConnect/trunk/stand2.0/StandConverter/math/World.h (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/math/World.h (revision 1973)
@@ -10,6 +10,7 @@
1010 #include "Dio.h"
1111 #include "Star.h"
1212 #include "Platinum.h"
13+#include "MinimumPhaseSpectrum.h"
1314 #include "WorldSynthesis.h"
1415
1516 namespace stand
--- vConnect/trunk/stand2.0/StandConverter/synthesis/UtauPhonemeAnalyzer.h (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/synthesis/UtauPhonemeAnalyzer.h (nonexistent)
@@ -1,54 +0,0 @@
1-#ifndef UTAUPHONEMEANALYZER_H
2-#define UTAUPHONEMEANALYZER_H
3-
4-#include <QThread>
5-#include <QMutex>
6-#include <QWaitCondition>
7-#include "../io/UtauLibrary.h"
8-#include "ConverterSetting.h"
9-
10-namespace stand
11-{
12-namespace io
13-{
14-class WaveFile;
15-}
16-namespace synthesis
17-{
18-
19-class ConverterSetting;
20-class Converter;
21-
22-class UtauPhonemeAnalyzer : public QThread
23-{
24- Q_OBJECT
25-signals:
26-
27-public slots:
28-
29-public:
30- explicit UtauPhonemeAnalyzer(unsigned int index, const ConverterSetting &s, Converter *c, QMutex *m = NULL);
31-
32- void run();
33- void setIndex(unsigned int index);
34- void converterFinished();
35-private:
36- void _writeDebugString();
37- void _analyze();
38-
39- stand::io::UtauPhoneme target;
40- ConverterSetting setting;
41- unsigned int index;
42-
43- QString directory;
44- QMutex *mutex;
45- Converter *converter;
46- QWaitCondition condition;
47-
48- bool _done;
49-};
50-
51-}
52-}
53-
54-#endif // UTAUPHONEMEANALYZER_H
--- vConnect/trunk/stand2.0/StandConverter/synthesis/UtauPhonemeAnalyzer.cpp (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/synthesis/UtauPhonemeAnalyzer.cpp (nonexistent)
@@ -1,171 +0,0 @@
1-#include "UtauPhonemeAnalyzer.h"
2-
3-#include "../io/UtauLibrary.h"
4-#include "../io/WaveFile.h"
5-#include "../io/StandFile.h"
6-#include "../utility/Utility.h"
7-
8-#include "ConverterSetting.h"
9-#include "Converter.h"
10-
11-#include "../math/World.h"
12-#include "../math/MFCCSet.h"
13-#include "../math/FFTSet.h"
14-
15-#include <QFileInfo>
16-
17-using namespace stand::synthesis;
18-
19-// min, max macro
20-#ifndef min
21-#define min(a,b) (((a)<(b))?(a):(b))
22-#endif
23-#ifndef max
24-#define max(a,b) (((a)<(b))?(b):(a))
25-#endif
26-
27-UtauPhonemeAnalyzer::UtauPhonemeAnalyzer(unsigned int index, const ConverterSetting &s, Converter *c, QMutex *m)
28-{
29- setting = s;
30- _done = false;
31- setIndex(index);
32- mutex = m;
33- directory = s.library->directory().absolutePath();
34- converter = c;
35-}
36-
37-void UtauPhonemeAnalyzer::converterFinished()
38-{
39- _done = true;
40-}
41-
42-void UtauPhonemeAnalyzer::setIndex(unsigned int index)
43-{
44- const stand::io::UtauPhoneme *p = setting.library->at(index);
45- if(p)
46- {
47- target = *p;
48- }
49- else
50- {
51- target.filename = "";
52- }
53- this->index = index;
54-}
55-
56-void UtauPhonemeAnalyzer::run()
57-{
58- while(!_done)
59- {
60- bool ret = true;
61- if(target.filename != "")
62- {
63- _writeDebugString();
64- _analyze();
65- }
66- else
67- {
68- qDebug(" Target was null.");
69- ret = false;
70- }
71-
72- if(mutex)
73- {
74- mutex->lock();
75- }
76- converter->analyzerFinished(this, ret);
77- if(mutex)
78- {
79- mutex->unlock();
80- }
81- }
82- qDebug(" Done :UtauPhonemeAnalyzer::run().");
83-}
84-
85-void UtauPhonemeAnalyzer::_writeDebugString()
86-{
87- qDebug("\nUtauPhonemeAnalyzer::run()\n"
88- " Analysis parameters\n"
89- " FileName: %s\n"
90- " Normalize option: %s\n"
91- , target.filename
92- , setting.normalizeUtauLibrary ? "true" : "false"
93- );
94-}
95-
96-void UtauPhonemeAnalyzer::_analyze()
97-{
98- // File duplication check
99- QString outFileName;
100- outFileName.setNum(index + 1);
101- outFileName = setting.outDir.absolutePath() + QDir::separator() + outFileName + ".vvd";
102- QFileInfo info(outFileName);
103- if(info.exists() && setting.overwrite == false)
104- {
105- qDebug(" File already exists; %s", outFileName);
106- return;
107- }
108-
109- // Read WaveFile
110- QString filename = (directory + QDir::separator() + target.filename);
111- filename = QDir::toNativeSeparators(filename);
112- stand::io::WaveFile wave(filename.toLocal8Bit().data());
113- if(wave.empty())
114- {
115- qDebug(" Wave is empty!");
116- return;
117- }
118- qDebug(" UtauPhonemeAnalzer::analyze(wave); length = %d", wave.length());
119-
120- // Cut wave.
121- float leftBlank, rightBlank;
122- if(setting.normalizeUtauLibrary)
123- {
124- leftBlank = target.leftBlank + target.preUtterance - setting.preUtterance;
125- rightBlank = -setting.phonemeLength;
126- }
127- else
128- {
129- leftBlank = target.leftBlank;
130- rightBlank = target.rightBlank;
131- }
132-
133- // 変数準備
134- stand::math::world::World::WorldSetting s;
135- s.framePeriod = setting.framePeriod;
136- s.fs = wave.header()->samplesPerSecond;
137-
138- // 波形を切って正規化
139- int xLen = stand::utility::lengthForUtauSetting(wave.length(), s.fs, leftBlank, rightBlank);
140- double *x = new double[xLen];
141-
142- for(int i = 0; i < xLen; i++)
143- {
144- int index = i + leftBlank / 1000.0 * wave.header()->samplesPerSecond;
145- index = max(0, min(index, wave.length() - 1));
146- x[i] = wave.data()[index];
147- }
148- stand::utility::normalizeByAnchor(x, xLen);
149-
150- // 波形から 1 ファイルを計算.
151- stand::io::StandFile stf;
152- stf.compute(x, xLen, s.fs, s.framePeriod, setting.cepstrumLength, -1, -1, setting.vorbisBitrate * 1024);
153-
154- delete[] x;
155-
156- if(mutex)
157- {
158- mutex->lock();
159- }
160- // 右ブランクを送る.ただし単位はミリ秒.
161- converter->recieveRightBlank(index, (float)xLen / s.fs * 1000.0);
162- if(mutex)
163- {
164- mutex->unlock();
165- }
166-
167- if(!stf.write(QDir::toNativeSeparators(outFileName).toLocal8Bit().data()))
168- {
169- qDebug("UtauPhonemeAnalyzer::analyze(); // failed writing.");
170- }
171-}
--- vConnect/trunk/stand2.0/StandConverter/synthesis/Transcriber.cpp (nonexistent)
+++ vConnect/trunk/stand2.0/StandConverter/synthesis/Transcriber.cpp (revision 1973)
@@ -0,0 +1,83 @@
1+#include "Transcriber.h"
2+#include "TranscriberElement.h"
3+#include "../io/UtauLibrary.h"
4+
5+using namespace stand::synthesis;
6+
7+Transcriber::Transcriber(const TranscriberSetting &s, QObject *parent) :
8+ QThread(parent)
9+{
10+ setting = s;
11+}
12+
13+Transcriber::~Transcriber()
14+{
15+ delete setting.base;
16+ for(int i = 0; i < setting.optionals.size();i ++)
17+ {
18+ delete setting.optionals.at(i);
19+ }
20+ for(int i = 0; i < elements.size(); i++)
21+ {
22+ elements.at(i)->finishTranscription();
23+ elements.at(i)->wait();
24+ elements.at(i)->disconnect();
25+ delete elements.at(i);
26+ }
27+}
28+
29+void Transcriber::run()
30+{
31+ qDebug("Transcriber::run();");
32+
33+ QMutex mutex;
34+ mutex.lock();
35+ elements.clear();
36+ for(int i = 0; i < setting.numThreads && i < setting.base->size(); i++)
37+ {
38+ TranscriberElement *e = new TranscriberElement(i, &setting, &mutex, this);
39+ elements.push_back(e);
40+ e->start();
41+ currentIndex = i;
42+ }
43+ mutex.unlock();
44+
45+ currentIndex = currentFinished = 0;
46+ waitMutex.lock();
47+ condition.wait(&waitMutex);
48+ waitMutex.unlock();
49+
50+ qDebug(" Done::Transcriber::run();");
51+ emit finish(true);
52+}
53+
54+void Transcriber::elementFinished(TranscriberElement *e)
55+{
56+ currentFinished++;
57+ if(currentIndex < setting.base->size())
58+ {
59+ e->setIndex(currentIndex);
60+ currentIndex++;
61+ }
62+ else
63+ {
64+ e->finishTranscription();
65+ }
66+ // SafeGuard (要るかな?)
67+ if(currentFinished == setting.base->size() - 1)
68+ {
69+ for(int i = 0; i < setting.numThreads; i++)
70+ {
71+
72+ }
73+ }
74+}
75+
76+void Transcriber::cancel()
77+{
78+ for(int i = 0; i < elements.size(); i++)
79+ {
80+ elements.at(i)->finishTranscription();
81+ }
82+ condition.wakeAll();
83+}
--- vConnect/trunk/stand2.0/StandConverter/synthesis/ConverterElement.cpp (nonexistent)
+++ vConnect/trunk/stand2.0/StandConverter/synthesis/ConverterElement.cpp (revision 1973)
@@ -0,0 +1,172 @@
1+#include "ConverterElement.h"
2+
3+#include "../io/UtauLibrary.h"
4+#include "../io/WaveFile.h"
5+#include "../io/StandFile.h"
6+#include "../utility/Utility.h"
7+
8+#include "ConverterSetting.h"
9+#include "Converter.h"
10+
11+#include "../math/World.h"
12+#include "../math/MFCCSet.h"
13+#include "../math/FFTSet.h"
14+
15+#include <QFileInfo>
16+
17+using namespace stand::synthesis;
18+
19+// min, max macro
20+#ifndef min
21+#define min(a,b) (((a)<(b))?(a):(b))
22+#endif
23+#ifndef max
24+#define max(a,b) (((a)<(b))?(b):(a))
25+#endif
26+
27+ConverterElement::ConverterElement(unsigned int index, const ConverterSetting &s, Converter *c, QMutex *m)
28+ : QThread(c)
29+{
30+ setting = s;
31+ _done = false;
32+ setIndex(index);
33+ mutex = m;
34+ directory = s.library->directory().absolutePath();
35+ converter = c;
36+}
37+
38+void ConverterElement::converterFinished()
39+{
40+ _done = true;
41+}
42+
43+void ConverterElement::setIndex(unsigned int index)
44+{
45+ const stand::io::UtauPhoneme *p = setting.library->at(index);
46+ if(p)
47+ {
48+ target = *p;
49+ }
50+ else
51+ {
52+ target.filename = "";
53+ }
54+ this->index = index;
55+}
56+
57+void ConverterElement::run()
58+{
59+ while(!_done)
60+ {
61+ bool ret = true;
62+ if(target.filename != "")
63+ {
64+ _writeDebugString();
65+ _analyze();
66+ }
67+ else
68+ {
69+ qDebug(" Target was null.");
70+ ret = false;
71+ }
72+
73+ if(mutex)
74+ {
75+ mutex->lock();
76+ }
77+ converter->analyzerFinished(this, ret);
78+ if(mutex)
79+ {
80+ mutex->unlock();
81+ }
82+ }
83+ qDebug(" Done :ConverterElement::run().");
84+}
85+
86+void ConverterElement::_writeDebugString()
87+{
88+ qDebug("\nConverterElement::run()\n"
89+ " Analysis parameters\n"
90+ " FileName: %s\n"
91+ " Normalize option: %s\n"
92+ , target.filename
93+ , setting.normalizeUtauLibrary ? "true" : "false"
94+ );
95+}
96+
97+void ConverterElement::_analyze()
98+{
99+ // File duplication check
100+ QString outFileName;
101+ outFileName.setNum(index + 1);
102+ outFileName = setting.outDir.absolutePath() + QDir::separator() + outFileName + ".vvd";
103+ QFileInfo info(outFileName);
104+ if(info.exists() && setting.overwrite == false)
105+ {
106+ qDebug(" File already exists; %s", outFileName);
107+ return;
108+ }
109+
110+ // Read WaveFile
111+ QString filename = (directory + QDir::separator() + target.filename);
112+ filename = QDir::toNativeSeparators(filename);
113+ stand::io::WaveFile wave(filename.toLocal8Bit().data());
114+ if(wave.empty())
115+ {
116+ qDebug(" Wave is empty!");
117+ return;
118+ }
119+ qDebug(" UtauPhonemeAnalzer::analyze(wave); length = %d", wave.length());
120+
121+ // Cut wave.
122+ float leftBlank, rightBlank;
123+ if(setting.normalizeUtauLibrary)
124+ {
125+ leftBlank = target.leftBlank + target.preUtterance - setting.preUtterance;
126+ rightBlank = -setting.phonemeLength;
127+ }
128+ else
129+ {
130+ leftBlank = target.leftBlank;
131+ rightBlank = target.rightBlank;
132+ }
133+
134+ // 変数準備
135+ stand::math::world::World::WorldSetting s;
136+ s.framePeriod = setting.framePeriod;
137+ s.fs = wave.header()->samplesPerSecond;
138+
139+ // 波形を切って正規化
140+ int xLen = stand::utility::lengthForUtauSetting(wave.length(), s.fs, leftBlank, rightBlank);
141+ double *x = new double[xLen];
142+
143+ for(int i = 0; i < xLen; i++)
144+ {
145+ int index = i + leftBlank / 1000.0 * wave.header()->samplesPerSecond;
146+ index = max(0, min(index, wave.length() - 1));
147+ x[i] = wave.data()[index];
148+ }
149+ stand::utility::normalizeByAnchor(x, xLen);
150+
151+ // 波形から 1 ファイルを計算.
152+ stand::io::StandFile stf;
153+ stf.compute(x, xLen, s.fs, s.framePeriod, setting.cepstrumLength, -1, -1, setting.vorbisBitrate * 1024);
154+
155+ delete[] x;
156+
157+ if(mutex)
158+ {
159+ mutex->lock();
160+ }
161+ // 右ブランクを送る.ただし単位はミリ秒.
162+ converter->recieveRightBlank(index, (float)xLen / s.fs * 1000.0);
163+ if(mutex)
164+ {
165+ mutex->unlock();
166+ }
167+
168+ if(!stf.write(QDir::toNativeSeparators(outFileName).toLocal8Bit().data()))
169+ {
170+ qDebug("ConverterElement::analyze(); // failed writing.");
171+ }
172+}
--- vConnect/trunk/stand2.0/StandConverter/synthesis/TranscriberSetting.h (nonexistent)
+++ vConnect/trunk/stand2.0/StandConverter/synthesis/TranscriberSetting.h (revision 1973)
@@ -0,0 +1,31 @@
1+#ifndef TRANSCRIBERSETTING_H
2+#define TRANSCRIBERSETTING_H
3+
4+#include <QVector>
5+
6+namespace stand
7+{
8+namespace io
9+{
10+class UtauLibrary;
11+}
12+namespace synthesis
13+{
14+
15+class TranscriberSetting
16+{
17+public:
18+ stand::io::UtauLibrary *base;
19+ QVector<stand::io::UtauLibrary *> optionals;
20+
21+ int note;
22+ int brightness;
23+
24+ unsigned int numThreads;
25+};
26+
27+}
28+}
29+
30+
31+#endif // TRANSCRIBERSETTING_H
--- vConnect/trunk/stand2.0/StandConverter/synthesis/Transcriber.h (nonexistent)
+++ vConnect/trunk/stand2.0/StandConverter/synthesis/Transcriber.h (revision 1973)
@@ -0,0 +1,48 @@
1+#ifndef TRANSCRIBER_H
2+#define TRANSCRIBER_H
3+
4+#include <QThread>
5+#include <QMutex>
6+#include <QWaitCondition>
7+#include <QVector>
8+
9+#include "TranscriberSetting.h"
10+
11+namespace stand
12+{
13+namespace synthesis
14+{
15+
16+class TranscriberElement;
17+
18+class Transcriber : public QThread
19+{
20+ Q_OBJECT
21+signals:
22+ void progressChanged(int val);
23+ void finish(bool flag);
24+
25+public slots:
26+ void cancel();
27+ void elementFinished(stand::synthesis::TranscriberElement *e);
28+
29+public:
30+ explicit Transcriber(const TranscriberSetting &s, QObject *parent = 0);
31+ ~Transcriber();
32+
33+ void run();
34+
35+private:
36+ TranscriberSetting setting;
37+ int currentFinished;
38+ int currentIndex;
39+ QVector<TranscriberElement *> elements;
40+
41+ QMutex waitMutex;
42+ QWaitCondition condition;
43+};
44+
45+}
46+}
47+
48+#endif // TRANSCRIBER_H
--- vConnect/trunk/stand2.0/StandConverter/synthesis/ConverterElement.h (nonexistent)
+++ vConnect/trunk/stand2.0/StandConverter/synthesis/ConverterElement.h (revision 1973)
@@ -0,0 +1,54 @@
1+#ifndef CONVERTERELEMENT_H
2+#define CONVERTERELEMENT_H
3+
4+#include <QThread>
5+#include <QMutex>
6+#include <QWaitCondition>
7+#include "../io/UtauLibrary.h"
8+#include "ConverterSetting.h"
9+
10+namespace stand
11+{
12+namespace io
13+{
14+class WaveFile;
15+}
16+namespace synthesis
17+{
18+
19+class ConverterSetting;
20+class Converter;
21+
22+class ConverterElement : public QThread
23+{
24+ Q_OBJECT
25+signals:
26+
27+public slots:
28+
29+public:
30+ explicit ConverterElement(unsigned int index, const ConverterSetting &s, Converter *c, QMutex *m = NULL);
31+
32+ void run();
33+ void setIndex(unsigned int index);
34+ void converterFinished();
35+private:
36+ void _writeDebugString();
37+ void _analyze();
38+
39+ stand::io::UtauPhoneme target;
40+ ConverterSetting setting;
41+ unsigned int index;
42+
43+ QString directory;
44+ QMutex *mutex;
45+ Converter *converter;
46+ QWaitCondition condition;
47+
48+ bool _done;
49+};
50+
51+}
52+}
53+
54+#endif // CONVERTERELEMENT_H
--- vConnect/trunk/stand2.0/StandConverter/synthesis/Converter.cpp (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/synthesis/Converter.cpp (revision 1973)
@@ -5,7 +5,7 @@
55
66 #include "../utility/Utility.h"
77 #include "../io/UtauLibrary.h"
8-#include "UtauPhonemeAnalyzer.h"
8+#include "ConverterElement.h"
99
1010 using namespace stand::synthesis;
1111
@@ -54,12 +54,12 @@
5454 {
5555 mutex.lock();
5656 currentPosition = 0;
57- analyzers = new UtauPhonemeAnalyzer*[setting.numThreads];
57+ analyzers = new ConverterElement*[setting.numThreads];
5858 for(unsigned int i = 0; i < setting.numThreads; i++)
5959 {
6060 if(i < setting.library->size())
6161 {
62- analyzers[i] = new UtauPhonemeAnalyzer(i, setting, this, &mutex);
62+ analyzers[i] = new ConverterElement(i, setting, this, &mutex);
6363 currentPosition++;
6464 analyzers[i]->start();
6565 }
@@ -71,7 +71,7 @@
7171 mutex.unlock();
7272 }
7373
74-void Converter::analyzerFinished(UtauPhonemeAnalyzer *p, bool f)
74+void Converter::analyzerFinished(ConverterElement *p, bool f)
7575 {
7676 unsigned int i;
7777 currentFinished++;
--- vConnect/trunk/stand2.0/StandConverter/synthesis/TranscriberElement.cpp (nonexistent)
+++ vConnect/trunk/stand2.0/StandConverter/synthesis/TranscriberElement.cpp (revision 1973)
@@ -0,0 +1,86 @@
1+#include "TranscriberElement.h"
2+#include "TranscriberSetting.h"
3+#include "Transcriber.h"
4+#include "../io/StandFile.h"
5+#include "../io/UtauLibrary.h"
6+
7+#include <QVector>
8+#include <QFileInfo>
9+#include <QMutex>
10+
11+using namespace stand::synthesis;
12+
13+TranscriberElement::TranscriberElement(unsigned int index, const TranscriberSetting *s, QMutex *m, Transcriber *t) :
14+ QThread(t)
15+{
16+ this->index = index;
17+ this->setting = s;
18+ this->mutex = m;
19+ this->transcriber = t;
20+
21+ libs.push_back(s->base);
22+ for(int i = 0; i < s->optionals.size(); i++)
23+ {
24+ libs.push_back(s->optionals.at(i));
25+ }
26+ isFinished = false;
27+}
28+
29+void TranscriberElement::setIndex(int index)
30+{
31+ this->index = index;
32+}
33+
34+void TranscriberElement::finishTranscription()
35+{
36+ isFinished = true;
37+}
38+
39+void TranscriberElement::run()
40+{
41+ qDebug("TranscriberElement::run();");
42+
43+ do
44+ {
45+ stand::io::StandFile *prev, *current = NULL;
46+ prev = new stand::io::StandFile();
47+ QString filename = libs.at(0)->directory().absolutePath() + QDir::separator() + libs.at(0)->at(index)->filename;
48+ // 簡単だけど拡張子チェック
49+ if(filename.contains(".vvd") && !prev->read(QDir::toNativeSeparators(filename).toLocal8Bit().data()))
50+ {
51+ qDebug("%s is not vvd file!", filename);
52+ delete prev;
53+ prev = NULL;
54+ }
55+ for(int i = 1; i < libs.size(); i++)
56+ {
57+ const stand::io::UtauPhoneme *phoneme = libs.at(i)->find(libs.at(0)->at(index)->pronounce);
58+ if(phoneme)
59+ {
60+ filename = libs.at(i)->directory().absolutePath() + QDir::separator() + phoneme->filename;
61+ current = new stand::io::StandFile();
62+ // 現在のファイルを読み込む→現在のファイルがよめていて,前回もファイルが読めていた場合だけ分析を行う.
63+ if(filename.contains(".vvd") && current->read(QDir::toNativeSeparators(filename).toLocal8Bit().data()) && prev)
64+ {
65+ // ToDo:: 写像関数の計算と保存
66+ stand::io::StandFile::matching(prev, current);
67+ }
68+ else
69+ {
70+ qDebug("%s is not vvd file!", filename);
71+ delete current;
72+ current = NULL;
73+ }
74+ }
75+ delete prev;
76+ prev = current;
77+ }
78+ delete current;
79+ mutex->lock();
80+ transcriber->elementFinished(this);
81+ mutex->unlock();
82+ }
83+ while(!isFinished);
84+
85+ qDebug(" Done::TranscriberElement::run();");
86+}
--- vConnect/trunk/stand2.0/StandConverter/synthesis/Converter.h (revision 1972)
+++ vConnect/trunk/stand2.0/StandConverter/synthesis/Converter.h (revision 1973)
@@ -15,7 +15,7 @@
1515 namespace synthesis
1616 {
1717
18-class UtauPhonemeAnalyzer;
18+class ConverterElement;
1919
2020 class Converter : public QThread
2121 {
@@ -34,7 +34,7 @@
3434 void run();
3535
3636 void recieveRightBlank(int index, float rightBlank);
37- void analyzerFinished(stand::synthesis::UtauPhonemeAnalyzer *, bool);
37+ void analyzerFinished(stand::synthesis::ConverterElement *, bool);
3838
3939 private:
4040 void _initializeAnalyzers();
@@ -41,7 +41,7 @@
4141 void _writeOtoIni();
4242
4343 float *rightBlanks;
44- UtauPhonemeAnalyzer **analyzers;
44+ ConverterElement **analyzers;
4545 ConverterSetting setting;
4646 bool isCanceled;
4747 volatile unsigned int currentPosition;
--- vConnect/trunk/stand2.0/StandConverter/synthesis/TranscriberSetting.cpp (nonexistent)
+++ vConnect/trunk/stand2.0/StandConverter/synthesis/TranscriberSetting.cpp (revision 1973)
@@ -0,0 +1,4 @@
1+#include "TranscriberSetting.h"
2+
3+using namespace stand::synthesis;
4+
--- vConnect/trunk/stand2.0/StandConverter/synthesis/TranscriberElement.h (nonexistent)
+++ vConnect/trunk/stand2.0/StandConverter/synthesis/TranscriberElement.h (revision 1973)
@@ -0,0 +1,45 @@
1+#ifndef TRANSCRIBERELEMENT_H
2+#define TRANSCRIBERELEMENT_H
3+
4+#include <QThread>
5+#include <QVector>
6+
7+class QMutex;
8+
9+namespace stand
10+{
11+namespace io
12+{
13+class UtauLibrary;
14+}
15+namespace synthesis
16+{
17+
18+class Transcriber;
19+class TranscriberSetting;
20+
21+class TranscriberElement : public QThread
22+{
23+ Q_OBJECT
24+public slots:
25+public:
26+ explicit TranscriberElement(unsigned int index, const TranscriberSetting *s, QMutex *m, Transcriber *t);
27+
28+ void run();
29+ void setIndex(int index);
30+ void finishTranscription();
31+private:
32+ unsigned int index;
33+ const TranscriberSetting *setting;
34+ QMutex *mutex;
35+ Transcriber *transcriber;
36+
37+ QVector<stand::io::UtauLibrary *> libs;
38+
39+ bool isFinished;
40+};
41+
42+}
43+}
44+
45+#endif // TRANSCRIBERELEMENT_H
旧リポジトリブラウザで表示