synthesis_v4.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. *
  3. * Synthesis API for WORLD 0.0.4 by M. Morise
  4. *
  5. * synthesis_v4.cpp
  6. * (c) M. Morise 2010-
  7. * edit and comment by HAL, kbinani
  8. *
  9. * This file is a part of WORLD system.
  10. * WORLD needs FFTW. Please install FFTW to use these files.
  11. * FFTW is here; http://www.fftw.org/
  12. *
  13. * notice: this comment is added by HAL.
  14. * Original files are on the web page below;
  15. * http://www.aspl.is.ritsumei.ac.jp/morise/world/
  16. * (this file is from WORLD 0.0.4
  17. * functions are renamed by HAL to support both 0.0.1 & 0.0.4.)
  18. *
  19. * synthesis_v4.cpp includes a set of functions
  20. * that supports synthesis on WORLD 0.0.4.
  21. * Notice that aperiodicity of 0.0.1 is much different
  22. * from that of 0.0.4. Please use platinum_v4 function
  23. * for synthesis_v4 function.
  24. *
  25. */
  26. #include "world.h"
  27. #include "../stand.h"
  28. #include <stdio.h> // for debug
  29. #include <stdlib.h>
  30. // 特定時刻の応答を取得する.
  31. void getOneFrameSegment_v4(double *f0, int tLen, double **specgram, double **residualSpecgram, int fftl, double framePeriod, double currentTime, int fs, double defaultF0,
  32. fftw_complex *spectrum, fftw_complex *cepstrum,
  33. double *response, int xLen, fftw_plan *inverseFFT_RP, fftw_plan minForward, fftw_plan minInverse)
  34. {
  35. int i;
  36. double real, imag, tmp;
  37. int currentFrame, currentPosition;
  38. currentFrame = (int)(currentTime/(framePeriod/1000.0) + 0.5);
  39. currentPosition = (int)(currentTime*(double)fs);
  40. tmp = currentTime + 1.0/(f0[currentFrame] == 0.0 ? defaultF0 : f0[currentFrame]);
  41. // 値を取り出す
  42. getMinimumPhaseSpectrum(specgram[currentFrame], spectrum, cepstrum, fftl, minForward, minInverse);
  43. spectrum[0][0] *= residualSpecgram[currentFrame][0];
  44. for(i = 1;i < fftl/2;i++)
  45. {
  46. real = spectrum[i][0]*residualSpecgram[currentFrame][(i-1)*2+1] - spectrum[i][1]*residualSpecgram[currentFrame][i*2];
  47. imag = spectrum[i][0]*residualSpecgram[currentFrame][i*2] + spectrum[i][1]*residualSpecgram[currentFrame][(i-1)*2+1];
  48. spectrum[i][0] = real;
  49. spectrum[i][1] = imag;
  50. }
  51. spectrum[fftl/2][0] = spectrum[fftl/2][0] * residualSpecgram[currentFrame][fftl-1];
  52. fftw_execute(*inverseFFT_RP);
  53. }
  54. void synthesis_v4(double *f0, int tLen, double **specgram, double **residualSpecgram, int fftl, double framePeriod, int fs,
  55. double *synthesisOut, int xLen)
  56. {
  57. int i,j;
  58. double *impulseResponse;
  59. impulseResponse = (double *)malloc(sizeof(double) * fftl);
  60. fftw_complex *cepstrum, *spectrum; // ケプストラムとスペクトル
  61. cepstrum = (fftw_complex *)malloc(sizeof(fftw_complex) * fftl);
  62. spectrum = (fftw_complex *)malloc(sizeof(fftw_complex) * fftl);
  63. fftw_plan inverseFFT_RP, minForward, minInverse; // FFTセット
  64. #ifdef STND_MULTI_THREAD
  65. if( hFFTWMutex ){
  66. hFFTWMutex->lock();
  67. }
  68. #endif
  69. inverseFFT_RP = fftw_plan_dft_c2r_1d(fftl, spectrum, impulseResponse , FFTW_ESTIMATE);
  70. minForward = fftw_plan_dft_1d(fftl, spectrum, cepstrum, FFTW_FORWARD, FFTW_ESTIMATE);
  71. minInverse = fftw_plan_dft_1d(fftl, cepstrum, spectrum, FFTW_BACKWARD, FFTW_ESTIMATE);
  72. #ifdef STND_MULTI_THREAD
  73. if( hFFTWMutex ){
  74. hFFTWMutex->unlock();
  75. }
  76. #endif
  77. double currentTime = 0.0;
  78. int currentPosition = 0;//currentTime / framePeriod;
  79. int currentFrame = 0;
  80. for(i = 0;;i++)
  81. {
  82. // 完全な無音は飛ばす.
  83. if(currentFrame < tLen && f0[currentFrame] < 0.0){
  84. currentFrame++;
  85. currentTime = (double)currentFrame * framePeriod / 1000.0;
  86. currentPosition = (int)(currentTime * (double)fs);
  87. if(currentFrame == tLen) break;
  88. continue;
  89. }
  90. for(j = 0;j < fftl;j++) impulseResponse[j] = 0.0; // 配列は毎回初期化
  91. getOneFrameSegment_v4(f0, tLen, specgram, residualSpecgram, fftl, framePeriod, currentTime, fs, DEFAULT_F0,
  92. spectrum, cepstrum, impulseResponse, xLen, &inverseFFT_RP, minForward, minInverse);
  93. currentPosition = (int)(currentTime*(double)fs);
  94. // for(j = 0;j < fftl/2;j++)
  95. for(j = 0;j < 3*fftl/4;j++)
  96. {
  97. if(j+currentPosition >= xLen) break;
  98. synthesisOut[j+currentPosition] += impulseResponse[j];
  99. }
  100. // 更新
  101. currentTime += 1.0/(f0[currentFrame] == 0.0 ? DEFAULT_F0 : f0[currentFrame]);
  102. currentFrame = (int)(currentTime/(framePeriod/1000.0) + 0.5);
  103. currentPosition = (int)(currentTime*(double)fs);
  104. if(j+currentPosition >= xLen || currentFrame >= tLen) break;
  105. }
  106. #ifdef STND_MULTI_THREAD
  107. if( hFFTWMutex ){
  108. hFFTWMutex->lock();
  109. }
  110. #endif
  111. fftw_destroy_plan(inverseFFT_RP);
  112. fftw_destroy_plan(minForward);
  113. fftw_destroy_plan(minInverse);
  114. #ifdef STND_MULTI_THREAD
  115. if( hFFTWMutex ){
  116. hFFTWMutex->unlock();
  117. }
  118. #endif
  119. free(cepstrum); free(spectrum);
  120. free(impulseResponse);
  121. return;
  122. }