VoiceSampler.cpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /*
  2. Copyright 2011 Tobias "Tomoko" Platen
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include "sekai/VoiceSampler.h"
  15. // FIXME: do not hardcode
  16. #define factor 4
  17. #define delay 0
  18. #include <sndfile.h>
  19. #include <boost/filesystem.hpp>
  20. VoiceSampler::VoiceSampler(int buffer_size) : OLABuffer(buffer_size) {}
  21. VoiceSampler::~VoiceSampler() {}
  22. bool VoiceSampler::readData(float* data, int size, int fill) {
  23. // TODO: fill if no data
  24. while (!isFilled(fill)) {
  25. if (addOnePulse() == false) return false;
  26. }
  27. pop(data, size);
  28. postProcess(data,size);
  29. outputPos+=size;
  30. return true;
  31. }
  32. #if 0
  33. int VoiceSampler::findPitchMark(struct Track& track, float pos,
  34. struct Pitch& p0, struct Pitch& p1,
  35. float* out) {
  36. int count = track.getPitchCount();
  37. for (int i = 0; i < count - 1; i++) {
  38. p0 = track.getPitch(i);
  39. p1 = track.getPitch(i + 1);
  40. if (p0.pos <= pos && p1.pos > pos) {
  41. if (out) *out = (pos - p0.pos) / (p1.pos - p0.pos);
  42. return i;
  43. }
  44. }
  45. return -1;
  46. }
  47. #endif
  48. #if 0
  49. bool VoiceSampler::load(struct VoiceRecord& record, int& samplerate,
  50. std::string fileName) {
  51. std::string f0 =
  52. boost::filesystem::change_extension(fileName, ".f0").string();
  53. std::string pmk =
  54. boost::filesystem::change_extension(fileName, ".pmk").string();
  55. record.f0Track.readFromFile(f0);
  56. record.pmkTrack.readFromFile(pmk);
  57. SF_INFO info = {0};
  58. SNDFILE* sf = sf_open(fileName.c_str(), SFM_READ, &info);
  59. if (sf == nullptr) return false;
  60. record.input_data = new float[info.frames];
  61. record.input_data_length = info.frames;
  62. assert(info.channels == 1);
  63. samplerate = info.samplerate;
  64. sf_read_float(sf, record.input_data, info.frames);
  65. sf_close(sf);
  66. return true;
  67. }
  68. #endif
  69. void VoiceSampler::hanningWindow(float* signal, int size) {
  70. // see https://github.com/numediart/MBROLA/blob/master/Engine/mbrola.c for
  71. // reference
  72. for (int i = 0; i < size; i++)
  73. signal[i] *= (0.5 * (1.0 - cos((double)i * 2 * M_PI / (float)size)));
  74. }