Tutorial - Changing sample pitch in real time

Implementing New Voice Type for Melody - Sampled Instrument

Objective: Demonstrate how to expand the functionality using the framework, showing examples of how to:

  • add a new type of voice, played by a real instrument
  • use this voice for melody, by changing pitch in real time

Prerequisities

If you haven't done so, please start with the first tutorial in the series to make sure you have all equipment and software ready.

Get Started

Let's assume you got the IDE installed, board connected to SWD and you tried the flashing utility to see that it communicates well.

Find a sample you want to use for the new instrument, it should be a WAV file, mono, 16bit. The sampling rate is not too important here.

Remove headers, so we have raw data (if you don't, some glitches might be heard) and save the file with "bin" extension.

Note down the file size.

Upload the bin file to a location in memory, where there is free space, using ST-Link utility (detailed steps here).

The Code

This may be surprising, but only one or two lines needs to be added to the code, as we have ready from previous tutorial.You remember the bit that looked like this:

if(drum_samples_ptr[i] >= 0) //if playing
{
//translate from 16-bit binary format to float
drum_machine_return_sample +=
((float)((int16_t*)(drum_bases[i]))[drum_samples_ptr[i]])
* DRUM_SAMPLE_VOLUME;
drum_samples_ptr[i]++;
 
...
}

In order to change the pitch of sample played back, let's change code like this (Variables have been renamed slightly too, from drum_* to bell_*):

if(bell_samples_ptr[i] >= 0) //if playing
{
//all the magic happens here:
sample_ptr = bell_samples_ptr[i] * bell_note_freq / 523.3f * 2;
 
if(sample_ptr < wavetable_lengths[i]) //do not overrun real sample length
{
//translate from 16-bit binary format to float
bell_return_sample +=
((float)((int16_t*)(bell_bases[i]))[sample_ptr]) * BELL_SAMPLE_VOLUME;
}
bell_samples_ptr[i]++;
 
...
}

Why "bell_note_freq / 523.3f * 2;"?

The goal here is to move the pointer slower or faster, depending on how far the desired note's frequency is from "base" frequency, in which the sample has been recorded at given sampling rate. In our case, the sample is C5 note, which has 523.3 Hz. Sample pointer's position will be recalculated by the ratio of our desired melody note's frequency vs this basic frequency.

Also, you know that difference between two octaves means doubling the frequency. Original sample might have been recorded at different sampling rate (for example. 44.1k vs 22.05k , and therefore sounded too high pitched. The last multiplication by two will move the pointer twice the speed, producing one octave lower sounding output.

Curious how it sounds?

This time sound recording only, check it you here on SoundCloud.

Comments

Your Changing sample pitch in real time/tutorial are excellent! You explained the functionality using the framework very detail.The Code give more picture.From the site(usawriters dot org)I got some information.But does not contain detail.Thank you for sharing me.

Thank you so much for providing the code snippet. I was working on this for few days and was not getting the right code that executes properly. I often get my essays from custom essay writing service.

I'm curious indeed and I cannot wait to experiment on this code. I hope it works using this code. www⋅musicmixpromotion⋅com

Hi,
I will publish source codes, binaries and firmware-updating application soon - you will find it under the "For Gechologists" tab. Watch that space! :)
Cheers,
Mario