Skip to content

Resampling

Phil Schatzmann edited this page Dec 13, 2022 · 28 revisions

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 easiest is, when the target and source can be described by an integer factor. If this is not the case we try to perform some upsampling and downsampling with a combination of rates that comes closest to the expected rate.

  • If the from rate is smaller then the target rate we perform an upsamping.
  • If the from rate is bigger then the target rate we perform an downsamping.

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 indicate the from rate and the target rate. In this example we perform a upsampling because the target rate is double the input rate.

uint16_t sample_rate=44100;
uint8_t channels = 2;                                      // The stream will have 2 channels 
SineWaveGenerator<int16_t> sineWave(32000);                // subclass of SoundGenerator with max amplitude of 32000
GeneratedSoundStream<int16_t> sound(sineWave);             // Stream generated from sine wave
ResampleStream<int16_t> 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 resample
  resample.begin(1.5); 

  // 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 double the input rate.

uint16_t sample_rate=44100;
uint8_t channels = 2;                                      // The stream will have 2 channels 
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<int16_t> 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
  resample.setAudioInfo(in.audioInfo());
  resample.begin(1.5); 

  // 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();
}

Final Notes

You can also use the regular pattern with if you prefer:

auto rcfg = resample.defaultConfig();
rcfg.channels = channels;
rcrg.step_size = 1.5;
resample.begin(rcfg);
Clone this wiki locally