vosamp_test.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include <math.h>
  2. #include <sndfile.h>
  3. #include <stdio.h>
  4. #include "sekai/VoiceSampler.h"
  5. class MyVoiceSampler : public VoiceSampler {
  6. virtual bool addOnePulse();
  7. //TODO: voice handle
  8. private:
  9. int _samplerate = 0;
  10. float _scaleFactor = 1.0;
  11. float _pitchShift = 1.0;
  12. public:
  13. MyVoiceSampler(int buffersize, std::string voicepath)
  14. : VoiceSampler(buffersize) {
  15. //FIXME: VoiceSampler::load(voice, _samplerate, voicepath);
  16. }
  17. int samplerate() { return _samplerate; }
  18. void setTimeScale(float factor) { _scaleFactor = factor; }
  19. void setPitchShift(float factor) { _pitchShift = factor; }
  20. };
  21. #if 0
  22. bool MyVoiceSampler::addOnePulse() {
  23. float currentIndex = inputPositionSamples();
  24. currentIndex /= _scaleFactor;
  25. float currentTime = currentIndex / _samplerate;
  26. Pitch pmkL, pmkR;
  27. Pitch f0L, f0R;
  28. float f0_interp = 0;
  29. float pmk_interp = 0;
  30. int pmkIndex =
  31. findPitchMark(voice.pmkTrack, currentTime, pmkL, pmkR, &pmk_interp);
  32. int f0Index = findPitchMark(voice.f0Track, currentTime, f0L, f0R, &f0_interp);
  33. // printf("f0_interp %f\n",f0_interp);
  34. float input_f0 = 500;
  35. if (f0L.f0 > 0 && f0R.f0 > 0) {
  36. input_f0 = f0L.f0 * (1 - f0_interp) + f0R.f0 * f0_interp;
  37. // printf("input_f0: %f\n",input_f0);
  38. }
  39. if (f0Index == -1) return false; // end of file
  40. float output_f0 = input_f0 * _pitchShift;
  41. int period = _samplerate / output_f0;
  42. int posL = pmkL.pos * _samplerate;
  43. int posR = pmkR.pos * _samplerate;
  44. int period2 = _samplerate / input_f0 * 2;
  45. float impulse_response[period2];
  46. float impulse_response_L[period2];
  47. float impulse_response_R[period2];
  48. // if(pmk_interp>0.5) pmk_interp=1.0; else pmk_interp=0.0;
  49. for (int i = 0; i < period2; i++) {
  50. if (i + posL < voice.input_data_length)
  51. impulse_response_L[i] = voice.input_data[i + posL];
  52. else
  53. impulse_response_L[i] = 0;
  54. if (i + posR < voice.input_data_length)
  55. impulse_response_R[i] = voice.input_data[i + posR];
  56. else
  57. impulse_response_R[i] = 0;
  58. impulse_response[i] = impulse_response_L[i] * (1 - pmk_interp) +
  59. impulse_response_L[i] * pmk_interp;
  60. }
  61. VoiceSampler::hanningWindow(impulse_response, period2);
  62. // fractional delay is added here
  63. ola(impulse_response, period2, period);
  64. return true;
  65. }
  66. #endif
  67. int main(int argc, char** argv) {
  68. if (argc < 3) {
  69. printf(
  70. "usage: vosamp_test input.wav output.wav [timescale] [pitchshift]\n");
  71. return 1;
  72. }
  73. std::string voicepath = argv[1];
  74. std::string outfile = argv[2];
  75. MyVoiceSampler vosamp(8192, voicepath);
  76. if (argc > 3) vosamp.setTimeScale(atof(argv[3]));
  77. if (argc > 4) vosamp.setPitchShift(atof(argv[4]));
  78. SF_INFO info = {0};
  79. info.samplerate = vosamp.samplerate();
  80. info.channels = 1;
  81. info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
  82. SNDFILE* sf = sf_open(outfile.c_str(), SFM_WRITE, &info);
  83. while (1) {
  84. int size = 1024;
  85. int fill = size * 4;
  86. float buffer_out[size];
  87. if (vosamp.readData(buffer_out, size, fill) == false) break;
  88. sf_write_float(sf, buffer_out, size);
  89. }
  90. sf_close(sf);
  91. }
  92. // TODO: copyout, window function