So far I have provided some resampling functionality that was working with some integer factors to up- and downsample. After the work on the Pitch Shifting I realized that we can easily resample using a float based step size to achieve any resampling factor and determine the new values with the help of linear interpolation.

This is cool because we can now speed up or slow down the audio by any rate!
And the beauty of this: I could considerably reduce the code size and complexity of the implementation.

Example Arduino Sketch

#include "AudioTools.h"

uint16_t sample_rate=44100;
uint8_t channels = 1;                                      
SineWaveGenerator<int16_t> sineWave(32000);               
GeneratedSoundStream<int16_t> sound(sineWave);             
ResampleStream<int16_t> resample(sound);
CsvStream<int16_t> out(Serial); 
StreamCopy copier(out, resample);                        

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

  // Setup sine wave
  sineWave.begin(channels, sample_rate, N_B4);

  // define resample
  auto resample_cfg = resample.defaultConfig();
  resample_cfg.step_size = 0.51;
  resample_cfg.channels = channels;
  resample.begin(resample_cfg); 

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

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

After the initialization you can change the rate at any time by calling resample.setStepSize(size). In the example above I am using the resampling on the input side, but we can also use it on the output side.

The Result

Here is the original output of the sine wave:

And this is the result of the resampling:

Jupyter

And last but not least here is a link to some resampling and mixing examples using Jupyter.


6 Comments

Hobman · 21. December 2022 at 1:52

Don’t think it is the pitch shifting routines that causing the delay. If instead of polling the touch pins I generate a random(7) numbers in the loop for the pitch shifts I can generate very fast short sounds approx 500 samples each looking at the wave out in Audacity…… all a continuous wave no breakups or crackling.
If I put any delay() or millis() in the loop for longer sounds it blocks andgives intermittent sound.
???? I think need the touchread faster and more sensitive.

Hobman · 20. December 2022 at 2:04

Just browsing your pages… very interesting and informative, briefly tried a few examples
You mention “you can change the rate at any time by calling” the step size routine.???
Where and how do I do that…..I assume in loop… So if I want to call it on the press of a button do I “poll” the buttons or setup interrupts. Does the timing of the loop matter..?

    pschatzmann · 20. December 2022 at 2:13

    Polling pins is quite fast, so I would expect that this should work w/o any problems in the loop

      Hobman · 20. December 2022 at 18:17

      Thanks for reply. My initial test, I probably didn’t read your notes close enough, I was trying resample_cfg.step_size = 0.51 etc etc in the loop and getting “not declared in scope etc etc”. I now see your notes say use “resample.setStepSize(size)”. This works and works well.so far just tried the your sine wave out to pin25 Internal DAC. I polled 7 touchRead pins with a change in pitch each pin.. All worked no “blocking” or crackling of sound. The response of each touch is a bit slow “has a delay latency prob guess 250ms”. Don;t know at this stage if it is the touch that has delay or the change of pitch processing has the delay. The ESP32 touch is not very touch sensitive “readings very low” . I wonder is there any way of improving that. ??

        pschatzmann · 20. December 2022 at 18:22

        You can optimize the lag by making the I2S buffers and the copy buffer size smaller

Leave a Reply

Avatar placeholder

Your email address will not be published.