MBRSynth.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. #include "sekai/MBRSynth.h"
  2. #include "sekai/Track.h"
  3. #include <string.h>
  4. #include <fstream>
  5. #include <iostream>
  6. #include <sstream>
  7. #include <json/json.h>
  8. #include <math.h>
  9. #include <sndfile.h>
  10. #include <boost/filesystem.hpp>
  11. #include <sekai/VoiceDefESPEAK.h>
  12. class VoiceDefMBR : public VoiceDef {
  13. private:
  14. float *_input_data=nullptr;
  15. int _input_data_length;
  16. int _input_data_length_ref;
  17. int _samplerate;
  18. public:
  19. VoiceDefMBR(std::string path,std::string ref)
  20. {
  21. SF_INFO info = {0};
  22. SNDFILE *sf = sf_open(path.c_str(), SFM_READ, &info);
  23. if (sf == nullptr) {
  24. return; // false
  25. }
  26. _input_data = new float[info.frames];
  27. _input_data_length = info.frames;
  28. assert(info.channels == 1);
  29. _samplerate = info.samplerate;
  30. sf_read_float(sf, _input_data, info.frames);
  31. sf_close(sf);
  32. if(ref.length())
  33. {
  34. SNDFILE *sf = sf_open(ref.c_str(), SFM_READ, &info);
  35. assert(_samplerate==info.samplerate);
  36. _input_data_length_ref = info.frames;
  37. if(sf) sf_close(sf);
  38. }
  39. }
  40. virtual float getLength() {
  41. if(_input_data_length_ref)
  42. return _input_data_length_ref*1.0/_samplerate;
  43. else
  44. return _input_data_length*1.0/_samplerate;
  45. }
  46. virtual void getImpulseResponse(float pos, float *impulseResponse, int *impulseResponseLength, float morph) {
  47. //FIXME: do not hardcode
  48. float frame_period = 5.0;
  49. int fft_size = 2048;
  50. float fract = pos * 1000 / frame_period;
  51. int frame_index = (int)fract;
  52. int frame_offset_l = frame_index * fft_size;
  53. int frame_offset_r = (frame_index+1) * fft_size;
  54. float pmk_interp = fract-frame_index;
  55. if(frame_offset_l<0 || frame_offset_r<0) return;
  56. for(int i=0; i<fft_size; i++)
  57. {
  58. float x=0;
  59. float l=0;
  60. float r=0;
  61. if(i+frame_offset_l<_input_data_length)
  62. l = _input_data[i+frame_offset_l];
  63. if(i+frame_offset_r<_input_data_length)
  64. r = _input_data[i+frame_offset_r];
  65. x = r * (1 - pmk_interp) + l * pmk_interp;
  66. if (morph) {
  67. r = x;
  68. l = impulseResponse[i];
  69. x = r * morph + l * (1.0f - morph);
  70. }
  71. impulseResponse[i] = x;
  72. }
  73. *impulseResponseLength=fft_size;
  74. }
  75. virtual int getSamplerate() {
  76. return _samplerate;
  77. }
  78. virtual std::string getPhoLine(int index) {
  79. return "";
  80. }
  81. };
  82. MBRSynth::MBRSynth(ControlTrack *ctrl, int buffer_size)
  83. : VoiceSampler(buffer_size) {
  84. _impulseResponse = new float[IMPULSE_RESPONSE_MAX];
  85. _ctrl = ctrl;
  86. _samplerate = 0;
  87. _debugfile = fopen("/tmp/maxvol.txt","w");
  88. }
  89. void MBRSynth::addUnit(const std::string &lyric, int count, float *a,float *b) {
  90. load(lyric);
  91. PhoEvent *e = new PhoEvent;
  92. e->points = count;
  93. e->voice = _voicemap[lyric];
  94. for (int i = 0; i < count; i++) {
  95. e->x[i] = a[i];
  96. e->y[i] = b[i];
  97. }
  98. _phoEvents.addEvent(e);
  99. }
  100. bool MBRSynth::addOnePulse() {
  101. float currentTime = inputPositionSamples() / _samplerate;
  102. if(isnan(currentTime))
  103. {
  104. printf("MBRSynth: samplerate is invalid\n");
  105. return false;
  106. }
  107. _phoEvents.selectNext(currentTime);
  108. PhoEvent *pho0 = _phoEvents.current();
  109. PhoEvent *pho1 = _phoEvents.next();
  110. if (pho0 == nullptr) return false;
  111. assert(_ctrl);
  112. float output_f0= _ctrl->getF0atTime(currentTime);
  113. if (output_f0 == 0) output_f0 = 50;
  114. if (currentTime < pho0->start()) {
  115. // rest: output silence
  116. output_f0 = 500;
  117. float period = _samplerate * 1.0f / output_f0;
  118. float dummy;
  119. ola(&dummy, 0, period);
  120. return true;
  121. }
  122. if (currentTime >= pho0->start() && currentTime < pho0->end()) {
  123. float interp = 0;
  124. int impulseResponseLength = 0;
  125. getImpulseResponse(currentTime, pho0, _impulseResponse,
  126. &impulseResponseLength,
  127. 0); // TODO get impulse response from mapped index
  128. if (pho1 && currentTime >= pho1->start()) {
  129. interp = (currentTime - pho1->start()) / (pho0->end() - pho1->start());
  130. }
  131. if (interp > 0) {
  132. getImpulseResponse(currentTime, pho1, _impulseResponse,
  133. &impulseResponseLength,
  134. interp); // needs interp as input
  135. }
  136. // int tmp = static_cast<int>(_samplerate * 1.0f / output_f0);
  137. // float period = tmp;
  138. float period = _samplerate * 1.0f / output_f0;
  139. VoiceSampler::hanningWindow(_impulseResponse, impulseResponseLength);
  140. ola(_impulseResponse, impulseResponseLength, period);
  141. return true;
  142. }
  143. {
  144. // rest: output silence
  145. output_f0 = 500;
  146. float period = _samplerate * 1.0f / output_f0;
  147. float dummy;
  148. ola(&dummy, 0, period);
  149. return true;
  150. }
  151. return false;
  152. }
  153. void MBRSynth::postProcess(float* data, int size)
  154. {
  155. float thresh=0.95;
  156. for(int i=0;i<size;i++)
  157. {
  158. float t = (i + outputPos)*1.0/_samplerate;
  159. data[i] *= _ctrl->getDynamicsAtTime(t);
  160. float vol = fabs(data[i]);
  161. if(vol > _maxvol) _maxvol = vol;
  162. if(_maxvol > thresh)
  163. {
  164. float a = thresh/_maxvol;
  165. data[i] *= a;
  166. }
  167. }
  168. fprintf(_debugfile,"maxvol = %f\n",_maxvol);
  169. }
  170. void MBRSynth::getImpulseResponse(float currentTime, PhoEvent *event,
  171. float *impulseResponse,
  172. int *impulseResponseLength, float morph) {
  173. auto voice = event->voice;
  174. float localTime =
  175. interp_linear(event->x, event->y, event->points, currentTime);
  176. assert(voice);
  177. if(voice==nullptr) return;
  178. voice->getImpulseResponse(localTime,impulseResponse,impulseResponseLength,morph);
  179. //TODO: morph is ignored
  180. }
  181. float MBRSynth::getLengthForUnit(const std::string &fileName) {
  182. load(fileName);
  183. return _voicemap[fileName]->getLength();
  184. }
  185. std::string MBRSynth::getPhoLine(const std::string &fileName, int index)
  186. {
  187. load(fileName);
  188. return _voicemap[fileName]->getPhoLine(index);
  189. }
  190. void MBRSynth::load(const std::string &unit)
  191. {
  192. if (_voicemap[unit] == nullptr) {
  193. synthType type = synthType::FVOX;
  194. if(_config) type = _config->type;
  195. switch(type)
  196. {
  197. case synthType::UTAU:
  198. {
  199. std::string debug = _basedir+"/"+unit+".ogg";
  200. _voicemap[unit] = new VoiceDefMBR(_basedir+"/"+unit+".ogg",_basedir+"/"+unit+".wav");
  201. break;
  202. }
  203. case synthType::ESPEAK:
  204. {
  205. _voicemap[unit] = new VoiceDefESPEAK(unit);
  206. break;
  207. }
  208. case synthType::FVOX:
  209. {
  210. printf("VoiceDefFOX %s %s\n",_basedir.c_str(),unit.c_str());
  211. _voicemap[unit] = new VoiceDefMBR(_basedir+"/ogg/"+unit+".ogg",_basedir+"/wav/"+unit+".wav");
  212. break;
  213. }
  214. default:
  215. {
  216. printf("MBRSynth::load failed %s\n",unit.c_str());
  217. throw new std::runtime_error("unknown voice type");
  218. }
  219. }
  220. if(_samplerate==0) {
  221. _samplerate=_voicemap[unit]->getSamplerate();
  222. }
  223. else
  224. assert(_samplerate==_voicemap[unit]->getSamplerate());
  225. }
  226. }
  227. bool MBRSynth::saveWave(const std::string &filename)
  228. {
  229. SF_INFO info = {0};
  230. info.samplerate = _samplerate;
  231. info.channels = 1;
  232. info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
  233. SNDFILE *sf = sf_open(filename.c_str(), SFM_WRITE, &info);
  234. if(sf==nullptr) return false;
  235. while (1) {
  236. const int size = 1024;
  237. int fill = size * 4;
  238. float buffer_out[size];
  239. if (readData(buffer_out, size, fill) == false) break;
  240. sf_write_float(sf, buffer_out, size);
  241. }
  242. sf_close(sf);
  243. return true;
  244. }