test_unisyn.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #include <sekai/UnisynIndex.h>
  2. #include <sekai/VoiceSampler.h>
  3. #include <sndfile.h>
  4. #include <assert.h>
  5. int g_samplerate = 0;
  6. float interp_linear(float *x, float *y, int nx, float ref) {
  7. int i;
  8. for (i = 0; i < nx - 1; i++) {
  9. if (ref >= x[i] && ref <= x[i + 1]) {
  10. float x1 = x[i];
  11. float x2 = x[i + 1];
  12. float tmp = (ref - x1) / (x2 - x1);
  13. return y[i] * (1 - tmp) + y[i + 1] * tmp;
  14. }
  15. }
  16. fprintf(stderr, "INTERP_LINEAR: out of range\n");
  17. return NAN;
  18. }
  19. // new ;
  20. class TestSynth : public VoiceSampler {
  21. public:
  22. TestSynth() : VoiceSampler(8192) {
  23. _index = new UnisynIndex();
  24. std::string dir = "/home/isengaara/Hacking/Audio/VoiceSynth/FESTIVAL/festival-czech-voices/voice-czech-krb/";
  25. _index->readFromFile(dir+"dic/krbdiph.est");
  26. _info[0] = _index->getPho("d-o");
  27. _info[1] = _index->getPho("r-e");
  28. _info[2] = _index->getPho("m-i");
  29. for(int i=0;i<3;i++)
  30. {
  31. std::string ogg = dir+"ogg/"+_info[i].basename+".ogg";
  32. SF_INFO info;
  33. _sf[i] = sf_open(ogg.c_str(), SFM_READ, &info);
  34. g_samplerate = info.samplerate;
  35. }
  36. _impulseResponse = new float[2048];
  37. }
  38. protected:
  39. virtual bool addOnePulse() {
  40. float currentTime = inputPositionSamples() / g_samplerate;
  41. int index = (int)currentTime;
  42. if (index == 3) return false;
  43. // get impulse response
  44. float otoTime = currentTime;
  45. while (otoTime > 1.0) otoTime -= 1.0;
  46. PhoInfo info = _info[index];
  47. assert(info.alignment.size()==3);
  48. float diph_start = info.alignment[0];
  49. float diph_middle = info.alignment[1];
  50. float diph_end = info.alignment[2];
  51. float x[3] = {0, diph_middle - diph_start, 1.0};
  52. float y[3] = {diph_start, diph_middle, diph_end};
  53. float index_time = interp_linear(x, y, 3, otoTime);
  54. // SynthesisMBR fft_size=2048 frame_period=5.000000
  55. float frame_period = 5.0;
  56. int fft_size = 2048;
  57. int frame_index = index_time * 1000 / frame_period;
  58. int frame_offset = frame_index * fft_size;
  59. sf_seek(_sf[index],frame_offset,SEEK_SET);
  60. sf_read_float(_sf[index],_impulseResponse,fft_size);
  61. float f0[3] = {261.63, 293.67, 329.63};
  62. float output_f0 = f0[index];
  63. float period = g_samplerate * 1.0f / output_f0;
  64. VoiceSampler::hanningWindow(_impulseResponse, fft_size);
  65. ola(_impulseResponse, fft_size, period);
  66. return true;
  67. }
  68. private:
  69. UnisynIndex* _index;
  70. PhoInfo _info[3];
  71. SNDFILE* _sf[3];
  72. float *_impulseResponse;
  73. };
  74. int main() {
  75. TestSynth *synth = new TestSynth();
  76. SF_INFO info = {0};
  77. info.samplerate = g_samplerate;
  78. info.channels = 1;
  79. info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
  80. SNDFILE *sf = sf_open("/tmp/test_unisyn.wav", SFM_WRITE, &info);
  81. while (1) {
  82. const int size = 1024;
  83. int fill = size * 4;
  84. float buffer_out[size];
  85. if (synth->readData(buffer_out, size, fill) == false) break;
  86. sf_write_float(sf, buffer_out, size);
  87. }
  88. sf_close(sf);
  89. }