27 Resampling
Phil Schatzmann edited this page 2024-03-25 21:14:50 +01:00

I have implemented some simple functionality to resample from an input rate to a output rate. This can be achieved with the help of the ResampleStream class. The resampling is done with the help of the step_size parameter. In an earlier version I was only supporting integer values, but I refactored the class to support a floating point step size:

  • If step_size is > 1.0 we perform an upsamping and the pitch gets higher
  • If step_size is < 1.0 we perform an downsamping and the pitch gets lower.

There are quite a few other possibilities to specify the resampling: please have a look at the different begin methods in the class documentation.

We can resample both on the input and on the output side:

Resampling of Input

We wrap the original input stream in a ResampleStream. In the configuration we can indicate the from rate and the (fixed) target rate or a step size. In this example we perform a upsampling because we define a step size (factor) 1.5 times the input rate. There are also quite a few begin() method alternatives that let you do define the same thing.

AudioInfo info(44100,2,16);
SineWaveGenerator<int16_t> sineWave(32000);                // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave);             // Stream generated from sine wave
ResampleStream resample(sound);
CsvStream<int16_t> out(Serial); 
StreamCopy copier(out, resample);                        // copies sound to out

// Arduino Setup
void setup(void) {  
  // Open Serial 
  Serial.begin(115200);
  AudioLogger::instance().begin(Serial, AudioLogger::Info);

  // define resampling info
  auto rcfg = resample.defaultConfig();
  rcfg.copyFrom(info);
  rcrg.step_size = 1.5;
  resample.begin(rcfg);

  // Define CSV Output
  auto config = out.defaultConfig();
  config.sample_rate = sample_rate; 
  config.channels = channels;
  out.begin(config);

  // Setup sine wave
  sineWave.begin(channels, sample_rate, N_B4);
  Serial.println("started...");
}

// Arduino loop - copy sound to out 
void loop() {
  copier.copy();
}

Resampling of Output

We can achieve the same result on the output side: We wrap the target output stream in a ResampleStream. In the configuration we indicate the from rate and the target rate. In this example we perform a upsampling because the target rate is 1.5 times the input rate.

AudioInfo info(44100,2,16);
SineWaveGenerator<int16_t> sineWave(32000);                // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> in(sineWave);             // Stream generated from sine wave
CsvStream<int16_t> out(Serial); 
ResampleStream resample(out);
StreamCopy copier(resample, in);                        // copies sound to out

// Arduino Setup
void setup(void) {  
  // Open Serial 
  Serial.begin(115200);
  AudioLogger::instance().begin(Serial, AudioLogger::Info);

  // define resampling info
  auto rcfg = resample.defaultConfig();
  rcfg.copyFrom(info);
  rcrg.step_size = 1.5;
  resample.begin(rcfg);

  // Define CSV Output
  auto config = out.defaultConfig();
  config.sample_rate = sample_rate; 
  config.channels = channels;
  out.begin(config);

  // Setup sine wave
  sineWave.begin(channels, sample_rate, N_B4);
  Serial.println("started...");
}

// Arduino loop - copy sound to out 
void loop() {
  copier.copy();
}