Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/synthesis/Vocoder.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 101 - (hide annotations) (download) (as text)
Fri Feb 1 01:09:56 2013 UTC (11 years, 2 months ago) by haruneko24
File MIME type: text/x-c++src
File size: 5446 byte(s)


1 haruneko24 50 /*
2 haruneko24 22 *
3     * Vocoder.cpp
4     * (c) HAL@shurabaP 2012-
5     *
6     * This class provides the interface to synthesize wave
7     * by Vocoder system.
8     *
9     * These files are distributed in the hope that it will be useful,
10     * but WITHOUT ANY WARRANTY; without even the implied warranty of
11     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12     *
13     */
14     #include "Vocoder.h"
15    
16 haruneko24 23 #include "SequenceModel.h"
17 haruneko24 26 #include "SynthesizerExpression.h"
18 haruneko24 38 #include "SynthesizerTrack.h"
19     #include "SynthesizerNote.h"
20 haruneko24 50 #include "SynthesizerPhrase.h"
21 haruneko24 36 #include "AbstractCorpus.h"
22 haruneko24 23
23 haruneko24 24 #include "audio/AudioChunk.h"
24    
25 haruneko24 78 #include "../configure.h"
26 haruneko24 101 #include "Utility.h"
27 haruneko24 78
28 haruneko24 22 using namespace stand::synthesis;
29 haruneko24 23 using namespace stand::model;
30 haruneko24 22
31 haruneko24 36 Vocoder::Vocoder(AbstractVocoderEngine *engine, AbstractCorpus *corpus, QObject *parent) :
32 haruneko24 28 AbstractSynthesizer(parent)
33 haruneko24 22 {
34 haruneko24 31 setEngine(engine);
35 haruneko24 36 setCorpus(corpus);
36 haruneko24 22 }
37    
38     Vocoder::~Vocoder()
39     {
40     }
41    
42 haruneko24 50 bool Vocoder::synthesize(stand::io::audio::AudioChunk *dst, SynthesizerPhrase *phrase)
43 haruneko24 23 {
44 haruneko24 36 if(!_engine || !_corpus || !dst || !dst->format().isValid())
45 haruneko24 29 {
46     return false;
47     }
48 haruneko24 36
49 haruneko24 37 double msCurrent = phrase->msBegin();
50 haruneko24 48 dst->setMsLength(phrase->msEnd() - phrase->msBegin());
51 haruneko24 36 dst->clearBufferToZero();
52    
53 haruneko24 38 const QVector<SynthesizerNote *> &notes = phrase->track()->notes();
54    
55     for(int i = 0; i < notes.size(); i++)
56     {
57     if(notes[i]->msBegin() < phrase->msBegin())
58     {
59     continue;
60     }
61 haruneko24 49 if(notes[i]->msBegin() >= phrase->msEnd())
62 haruneko24 38 {
63     break;
64     }
65    
66 haruneko24 56 if(_corpus->contains(AbstractCorpus::Key(notes[i], 0)))
67 haruneko24 38 {
68 haruneko24 39 // ������������������������������
69     SynthesizerNote *thisNote = notes[i];
70     SynthesizerNote *nextNote = (i + 1 < notes.size()) ? notes[i+1] : NULL;
71    
72 haruneko24 56 msCurrent = qMax(msCurrent, thisNote->msBegin() - _corpus->msPreutterance(AbstractCorpus::Key(thisNote, 0.0)));
73 haruneko24 40
74 haruneko24 39 // ���������������������������������������������������������������������
75     if(nextNote)
76     {
77     msCurrent = _synthesizeOneNote(dst, msCurrent, thisNote, nextNote, phrase);
78     }
79     else
80     {
81     msCurrent = _synthesizeOneNote(dst, msCurrent, thisNote, phrase);
82     }
83 haruneko24 38 }
84 haruneko24 39 else
85     {
86     msCurrent = notes[i]->msEnd();
87     }
88 haruneko24 38 }
89 haruneko24 48 dst->setReadiness(true);
90 haruneko24 38
91 haruneko24 39 return true;
92     }
93    
94 haruneko24 50 double Vocoder::_synthesizeOneNote(stand::io::audio::AudioChunk *dst, double msCurrent, SynthesizerNote *current, SynthesizerNote *next, SynthesizerPhrase *phrase)
95 haruneko24 39 {
96     VocoderFrame currentFrame(_engine->info()), nextFrame(_engine->info());
97    
98     QVector<QPair<VocoderFrame *, double> > frames;
99     frames.resize(2);
100     frames[0].first = &currentFrame;
101     frames[1].first = &nextFrame;
102 haruneko24 49
103 haruneko24 56 double currentActualMs = current->msBegin() - _corpus->msPreutterance(AbstractCorpus::Key(current, 0));
104     double nextActualMs = next->msBegin() - _corpus->msPreutterance(AbstractCorpus::Key(next, 0));
105 haruneko24 49 double begin = qMax(currentActualMs, nextActualMs);
106     double length = current->msEnd() - begin;
107 haruneko24 56 if(length <= 0.0)
108     {
109     return _synthesizeOneNote(dst, msCurrent, current, phrase);
110     }
111 haruneko24 49
112 haruneko24 39 while(msCurrent < phrase->msEnd() && msCurrent < current->msEnd())
113 haruneko24 24 {
114 haruneko24 39 double f0 = phrase->track()->f0At(msCurrent);
115 haruneko24 78 if(f0 == 0.0)
116     {
117     f0 = stand::DefaultF0Value;
118     }
119    
120 haruneko24 56 AbstractCorpus::Key currentKey(current, msCurrent - current->msBegin());
121     AbstractCorpus::Key nextKey(next, msCurrent - next->msBegin());
122 haruneko24 31
123 haruneko24 39 // ���������������������������������������
124     frames[0].second = qMax(0.0, qMin(1.0, 1.0 - (msCurrent - begin) / length));
125     frames[1].second = 1.0 - frames[0].second;
126    
127     // ���������������������������������������������������
128     if(frames[0].second == 0.0)
129 haruneko24 37 {
130 haruneko24 40 _corpus->find(&currentFrame, nextKey, _engine);
131 haruneko24 37 }
132 haruneko24 39 else if(frames[0].second == 1.0)
133     {
134 haruneko24 40 _corpus->find(&currentFrame, currentKey, _engine);
135 haruneko24 39 }
136     else
137     {
138 haruneko24 40 _corpus->find(&currentFrame, currentKey, _engine);
139     _corpus->find(&nextFrame, nextKey, _engine);
140 haruneko24 39 _engine->morph(&currentFrame, frames);
141     }
142 haruneko24 36
143 haruneko24 39 _engine->synthesize(dst, &currentFrame, dst->samplesAtMsec(msCurrent));
144 haruneko24 49 msCurrent += 1000.0 / f0;//_engine->samplesForF0(f0);
145 haruneko24 24 }
146 haruneko24 39 return msCurrent;
147     }
148 haruneko24 36
149 haruneko24 50 double Vocoder::_synthesizeOneNote(stand::io::audio::AudioChunk *dst, double msCurrent, SynthesizerNote *current, SynthesizerPhrase *phrase)
150 haruneko24 39 {
151     VocoderFrame currentFrame(_engine->info());
152     while(msCurrent < phrase->msEnd() && msCurrent < current->msEnd())
153     {
154     double f0 = phrase->track()->f0At(msCurrent);
155 haruneko24 101 if(f0 < stand::utility::NoteFrequency(0) || f0 > stand::utility::NoteFrequency(128))
156 haruneko24 78 {
157     f0 = stand::DefaultF0Value;
158     }
159 haruneko24 56 AbstractCorpus::Key key(current, msCurrent - current->msBegin());
160 haruneko24 40 _corpus->find(&currentFrame, key, _engine);
161 haruneko24 39 _engine->synthesize(dst, &currentFrame, dst->samplesAtMsec(msCurrent));
162 haruneko24 49 msCurrent += 1000.0 / f0;//_engine->samplesForF0(f0) / (double)_engine->info().sampleRate() * 1000.0;
163 haruneko24 39 }
164     return msCurrent;
165 haruneko24 23 }
166    
167    

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26