corpusManager.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * corpusManager.cpp
  3. * Copyright (C) 2010- HAL,
  4. * Copyright (C) 2011-2012 kbinani.
  5. *
  6. * This files is a part of v.Connect.
  7. * corpusManager is a class that controls corpus based on UTAU.
  8. * This class convert UTAU WAVE corpus into WORLD specgrams.
  9. *
  10. * These files are distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. */
  14. #include <tuple>
  15. #include "Configuration.h"
  16. #include "corpusManager.h"
  17. #include "vConnectPhoneme.h"
  18. #include "utau/UtauDB.h"
  19. #include "vsq/Sequence.h"
  20. using namespace vconnect;
  21. corpusManager::corpusManager()
  22. {
  23. mUtauDB = NULL;
  24. mBrightness = 64;
  25. mFrequency = 440.0;
  26. }
  27. void corpusManager::analyze( vector<tuple<string, int>> &phonemes )
  28. {
  29. int size = phonemes.size();
  30. for( int i = 0; i < size; i++ ){
  31. string lyric = std::get<0>(phonemes[i]);
  32. int note_number = std::get<1>(phonemes[i]);
  33. getPhoneme(lyric, note_number);
  34. cout << "corpusManager::analyze; lyric=" << lyric << endl;
  35. }
  36. for( int i = 0; i < mAppendCorpus.size(); i++ ){
  37. if( mAppendCorpus[i] ){
  38. mAppendCorpus[i]->analyze(phonemes);
  39. }
  40. }
  41. mIsAppend = mEnableExtention = mEnableBrightness = mEnableFrequency = false;
  42. }
  43. corpusManager::~corpusManager()
  44. {
  45. Map<string, phoneme *>::iterator i;
  46. for( i = objectMap.begin(); i != objectMap.end(); i++ ){
  47. if( i->second ){
  48. if( i->second->p ){
  49. delete i->second->p;
  50. i->second->p = NULL;
  51. }
  52. delete i->second;
  53. i->second = NULL;
  54. }
  55. }
  56. for( int j = 0; j < mAppendCorpus.size(); j++){
  57. delete mAppendCorpus[j];
  58. }
  59. // うーん…
  60. if(mIsAppend){
  61. delete mUtauDB;
  62. }
  63. }
  64. corpusManager::phoneme *corpusManager::getPhoneme(string const& lyric, int note_number)
  65. {
  66. phoneme *ret = NULL;
  67. Map<string, phoneme *>::iterator i;
  68. string alphabet, vtd_path;
  69. #ifdef STND_MULTI_THREAD
  70. if( hMutex ){
  71. hMutex->lock();
  72. }
  73. #endif
  74. // まず vConnectPhoneme の有無をチェック.
  75. i = objectMap.find( lyric );
  76. if( i != objectMap.end() ){ // 希望のデータが存在するのでそれを返す.
  77. #ifdef STND_MULTI_THREAD
  78. if( hMutex ){
  79. hMutex->unlock();
  80. }
  81. if( i->second->isProcessing ){ // あるにはあるけど分析中なので待機.
  82. if( i->second->waitHandle ){
  83. i->second->waitHandle->lock();
  84. // ロックが取得できたってことは分析終了なので即解放
  85. i->second->waitHandle->unlock();
  86. delete i->second->waitHandle;
  87. }
  88. i->second->waitHandle = NULL;
  89. }
  90. #endif
  91. if( i->second->isValid ){
  92. // 有効性を見る.
  93. ret = i->second;
  94. }else{
  95. ret = NULL;
  96. }
  97. }else{ // 希望するデータが存在しないので作成する.
  98. UtauParameter parameters;
  99. phoneme *target = new phoneme; // ハッシュには先に突っ込んでしまう.
  100. objectMap.insert( make_pair( lyric, target ) );
  101. #ifdef STND_MULTI_THREAD
  102. target->isProcessing = true;
  103. target->waitHandle = new Mutex();// CreateEvent(NULL,TRUE,FALSE,NULL);
  104. target->waitHandle->lock();
  105. if( hMutex ){
  106. hMutex->unlock();
  107. }
  108. #endif
  109. // UTAU の原音設定が無ければ読み込みを行わない.
  110. if (mUtauDB->getParams(parameters, lyric, note_number)) {
  111. target->p = new vConnectPhoneme;
  112. string path = mDBPath + parameters.fileName;
  113. bool bResult = false;
  114. if( parameters.isWave ){
  115. double framePeriod = Configuration::getMilliSecondsPerFrame();
  116. bResult = target->p->readRawWave( mDBPath, &parameters, framePeriod );
  117. }else{
  118. bResult = target->p->readPhoneme( path.c_str() );
  119. }
  120. if( bResult ){
  121. target->isValid = true;
  122. target->fixedLength = parameters.msFixedLength;
  123. ret = target;
  124. target->brightness = mBrightness;
  125. target->frequency = mFrequency;
  126. target->enableBrightness = mEnableBrightness;
  127. target->enableFrequency = mEnableFrequency;
  128. }
  129. }
  130. target->isProcessing = false;
  131. #ifdef STND_MULTI_THREAD
  132. if( target->waitHandle ){
  133. target->waitHandle->unlock();
  134. }
  135. #endif
  136. }
  137. return ret;
  138. }
  139. corpusManager::phoneme *corpusManager::getPhoneme(string const& lyric, int note_number, list<phoneme*> &phonemeList)
  140. {
  141. phoneme *p = NULL;
  142. // 有効な音素なら追加する.
  143. if((p = getPhoneme(lyric, note_number)) && p->isValid && p->p){
  144. p->enableBrightness = mEnableBrightness;
  145. p->enableFrequency = mEnableFrequency;
  146. phonemeList.push_back(p);
  147. }
  148. // アペンドがあるならそれを追加.
  149. for(int i = 0; i < mAppendCorpus.size(); i++){
  150. if(mAppendCorpus[i] && p){
  151. p->children = mAppendCorpus[i]->getPhoneme(lyric, note_number, phonemeList);
  152. }
  153. }
  154. return p;
  155. }
  156. void corpusManager::setUtauDB( UtauDB *p, RuntimeOption &options )
  157. {
  158. string tmp;
  159. mUtauDB = p;
  160. if( p ){
  161. this->mDBPath = p->getOtoIniPath();
  162. }
  163. tmp = "vConnect.ini";
  164. mEnableExtention = setting.readSetting( mDBPath, tmp, options.getEncodingOtoIni().c_str()); // 文字コード指定は暫定処置
  165. if(mEnableExtention){
  166. setCorpusSetting(setting.getLibrarySetting(SETTING_BASE));
  167. librarySetting *brightnessSetting = setting.getLibrarySetting(SETTING_BRIGHTNESS);
  168. if(mEnableBrightness && brightnessSetting){
  169. UtauDB *db = new UtauDB(
  170. Path::combine( brightnessSetting->path, "oto.ini" ),
  171. options.getEncodingOtoIni()
  172. );
  173. mAppendCorpus.resize(1, NULL);
  174. mAppendCorpus[0] = new corpusManager();
  175. mAppendCorpus[0]->setBrightness( brightnessSetting->brightness );
  176. mAppendCorpus[0]->setUtauDB( db, options );
  177. mAppendCorpus[0]->setIsAppend(true);
  178. }
  179. }
  180. }
  181. bool corpusManager::checkEnableExtention()
  182. {
  183. return mEnableExtention;
  184. }
  185. void corpusManager::setCorpusSetting(librarySetting *setting)
  186. {
  187. if(!setting){
  188. mEnableBrightness = mEnableFrequency = false;
  189. return;
  190. }
  191. mEnableBrightness = true;
  192. mBrightness = setting->brightness;
  193. // 暫定.
  194. mEnableFrequency = false;
  195. mFrequency = setting->frequency;
  196. }