Signalsmith-Audio / signalsmith-stretch

C++ polyphonic pitch/time library (GitHub mirror)
https://signalsmith-audio.co.uk/code/stretch/
MIT License
253 stars 24 forks source link

Echo when modifying pitch or leaving it as is #9

Open bojeckkk opened 2 months ago

bojeckkk commented 2 months ago

Hey,

I've a simple code for modifying pitch of an audio. Even when I set factor to 1 (no pitch change), there is significant echo hearable in the resulting audio. Sample code below.

#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
#include <string>

#include "signalsmith-stretch.h"

std::vector<int16_t> convert_to_shorts(const std::vector<float>& input) {
  std::vector<int16_t> shorts;
  shorts.reserve(input.size());
  for (auto&& sample : input) {
    shorts.push_back(sample / 32767.f);
  }
  return shorts;
}

std::vector<float> convert_to_floats(const std::vector<int16_t>&& input) {
  std::vector<float> floats;
  floats.reserve(input.size());
  for (auto&& sample : input) {
    floats.push_back(sample * 32767.f);
  }
  return floats;
}

int main(int argc, char* argv[]) {
std::ifstream input("a.wav", std::ios::binary);
std::vector<unsigned char> input_buffer(std::istreambuf_iterator<char>(input), {});
int samples = (input_buffer.size() - 44) / 2;
auto input_floats = convert_to_floats(std::vector<int16_t>((int16_t*)(input_buffer.data() + 44), (int16_t*)(input_buffer.data() + 44 + samples * 2)));
std::vector<float> output_floats(input_floats.size());
float* input_floats_ptr = input_floats.data();
float* output_floats_ptr = output_floats.data();

signalsmith::stretch::SignalsmithStretch<float> stretch;
stretch.presetDefault(1, 24000);
float factor = 1.5;
if (argc > 1){
  factor = std::stof(argv[1]);
}
stretch.setTransposeFactor(factor);

stretch.process(&input_floats_ptr, samples, &output_floats_ptr, samples);

auto converted = convert_to_shorts(output_floats);

std::ofstream output("a_pitch.wav", std::ios::binary);
output.write(reinterpret_cast<const char*>(input_buffer.data()), 44);
output.write(reinterpret_cast<const char*>(converted.data()), converted.size() * sizeof(decltype(converted)::value_type));
output.close();

}
bojeckkk commented 2 months ago

The echo is not present in web demo, but webassembly is really obfuscated so I could not get anything useful out of it.