test_mbrola.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include <sekai/VoiceDefMBROLA.h>
  2. #include <sekai/VoiceSampler.h>
  3. #include <sndfile.h>
  4. int g_samplerate = 0;
  5. float interp_linear(float *x, float *y, int nx, float ref) {
  6. int i;
  7. for (i = 0; i < nx - 1; i++) {
  8. if (ref >= x[i] && ref <= x[i + 1]) {
  9. float x1 = x[i];
  10. float x2 = x[i + 1];
  11. float tmp = (ref - x1) / (x2 - x1);
  12. return y[i] * (1 - tmp) + y[i + 1] * tmp;
  13. }
  14. }
  15. fprintf(stderr, "INTERP_LINEAR: out of range\n");
  16. return NAN;
  17. }
  18. // new ;
  19. class TestSynth : public VoiceSampler {
  20. public:
  21. TestSynth() : VoiceSampler(8192) {
  22. vox = new VoiceDefMBROLA(
  23. "/home/isengaara/Hacking/Audio/VoiceSynth/MBROLA/MBROLA-voices/tmp/de1/"
  24. "de1");
  25. g_samplerate = vox->getSamplerate();
  26. diph[0] = vox->getDiphone("d-o:");
  27. diph[1] = vox->getDiphone("R-e:");
  28. diph[2] = vox->getDiphone("m-I");
  29. printf("diph %p %p %p\n", diph[0], diph[1], diph[2]);
  30. _impulseResponse = new float[1024];
  31. }
  32. protected:
  33. virtual bool addOnePulse() {
  34. int samplerate = vox->getSamplerate();
  35. float currentTime = inputPositionSamples() / samplerate;
  36. int index = (int)currentTime;
  37. if (index == 3) return false;
  38. // get impulse response
  39. float otoTime = currentTime;
  40. while (otoTime > 1.0) otoTime -= 1.0;
  41. diphone *current_diph = diph[index];
  42. float diph_start = current_diph->begin * 1.0 / samplerate;
  43. float diph_middle = current_diph->middle * 1.0 / samplerate;
  44. float diph_end = current_diph->end * 1.0 / samplerate;
  45. printf("DIPH %f\n", diph_start - diph_middle);
  46. float x[3] = {0, diph_middle - diph_start, 1.0};
  47. float y[3] = {diph_start, diph_middle, diph_end};
  48. float index_time = interp_linear(x, y, 3, otoTime);
  49. int impulseResponseLength = 0;
  50. vox->getImpulseResponse(index_time, _impulseResponse,
  51. &impulseResponseLength,0);
  52. float f0[3] = {261.63, 293.67, 329.63};
  53. float output_f0 = f0[index];
  54. float period = samplerate * 1.0f / output_f0;
  55. if (otoTime > 0.95) impulseResponseLength = 0;
  56. VoiceSampler::hanningWindow(_impulseResponse, impulseResponseLength);
  57. ola(_impulseResponse, impulseResponseLength, period);
  58. return true;
  59. }
  60. private:
  61. VoiceDefMBROLA *vox;
  62. diphone *diph[3];
  63. float *_impulseResponse;
  64. };
  65. int main() {
  66. TestSynth *synth = new TestSynth();
  67. SF_INFO info = {0};
  68. info.samplerate = g_samplerate;
  69. info.channels = 1;
  70. info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
  71. SNDFILE *sf = sf_open("/tmp/test_mbrola.wav", SFM_WRITE, &info);
  72. while (1) {
  73. const int size = 1024;
  74. int fill = size * 4;
  75. float buffer_out[size];
  76. if (synth->readData(buffer_out, size, fill) == false) break;
  77. sf_write_float(sf, buffer_out, size);
  78. }
  79. sf_close(sf);
  80. }