How can change frequency of audio file

Since the videos you posted are of a specific piece of hardware, the Percussa SSP, it is possibly useful to refer to the manual if you want to know what it’s Frequency and Pitch settings do:

The Pitch, TuneC (coarse tune) and TuneF (fine tune) settings seem to correspond to what’s seen in the videos.

I agree with what others have said, that in terms of how each parameter operates on the sound they essentially do the same thing. Freq/Tune are for setting the pitch (playback speed) of the sample. The Pitch parameter is 1v/octave MIDI input: for every volt increase of the input, the sample’s pitch will go up by one octave.

your audio is in some kind of buffer. maybe a vector or an array. you’d usually increment its read index by 1 for each sample to play the sound. try incrementing by 2 and you’ll notice it’s an octave higher and twice as fast now. then ask yourself: “what happens if i increment by 1.5? and how do i use a float value to access the buffer?” this will lead you to the field of interpolation. the simplest one is just int(index). try that and hear the sound. it’s probably quite crushy, especially for value lower than 1 but you’ll already hear the pitching effect well. then learn about linear interpolation and if you feel adventurous maybe go on with splines. at that point your resampler should sound quite good for most cases

Hello Friends,
Thank you so much for your valuable reply, I am referring to all that you suggest me. Also, reading more about this. Because I thought that there should be some JUCE APIs to directly affect pitch and I can change sample rate/frequency by increment/decrement index value of buffer.

Hello Friends,
So, now i am very clear to distinguish frequency and pitch. So, let me make my question to specific. Actually, i want to change rate of sample. Currently, i am trying by changing index value of buffer. But is there any APIs to change rate of sample? or have to use classes suggested by @maxwellp777?

Yes, you will need to use interpolation to achieve that. Either roll your own or use the above suggested class.

So, i am trying to use Interpolation. But still not succeed to change sample rate. I have also check some examples. I am sharing one link which also used.

I also uploaded some lines of code which I modified to change sample rate.

Hello Guys,
Thank you so much for your support. I have stuck on this issue from a long time.
Now I am thinking to use a 3rd party library to solve this issue.
So, can I use the “Rubber Band” library here to add the functionality of pitch and frequency?

Hello Howard,

First, Let me clear my question. Sorry guys for the misunderstanding.
I need to use “Frequency” and “Pitch” Slider/Encoders as like below:

The pitch moves the speed of the sample in terms of semitones which are the musical intervals of a piano and freq. moves the pitch or speed of the sample based on hertz so as to be gradually increased or decreased in hertz

This still sounds like they are two controls that do the same thing

Indeed.

@kishanpatel in case you are not aware of it, but 12 semitones on the piano are the same thing as doubling the frequency in Hz.

For everything in between the mathematical ratio is a bit more odd, but you can always calculate “x semitones are the same as a frequency factor of y”. So yes. You likely want two controls with different value scales setting the very same thing under the hood. You have to controls expressing the same thing with different numerical values. I really hope you are aware of that. May I ask you from which background you are coming?

You could even build it in a way that moving one slider will simultaneously move the other one to the position where you would have achieved the same sound with the other option.

Sure.

I am from Embedded programming background but new to the audio plugin.
So, I think our requirement is doable. Right?
Or still, I am on wrong track?

// i decided to make a little code snippet to make your life a little easier.
// people will not often do that but since you are a beginner just like me
// 3/2 years ago I totally feel you.

AudioBuffer buffer; // let's pretend like we have an audio buffer.
// this is an imaginary object that has a 2dimensional array, for channels and samples.

buffer = import(someAudioFile.wav); // i know this is more complicated in juce,
// but i'm too lazy to check how it works now.

auto tune = 1; // let's introduce a variable that will tune our signal.
auto readHead = 0; // we need a variable that acts as sort of an index

for(auto i = 0; i < audioBuffer.numSamples; ++i) {
    for(auto ch = 0; ch < numChannels; ++ch)
        audioBuffer[ch][i] = buffer[ch][readHead];
    readHead += tune;
    while(readHead >= buffer.numSamples) readHead -= buffer.numSamples;
}
// please beware that this is all pseudocode. it looks different with JUCE objects.
// however if audioBuffer was the buffer that will be given to the output
// you'd put the sample at readHead into it for each sample and channel.
// then you update the readHead with tune.
// in this case the audio file's data will be looped infinitely. when the readHead
// reaches the end of its buffer's numSamples it flips back. this is not the
// audioBuffer's numSamples btw.

auto tune = 2.5;
auto readhead = 0.; // now instead of using integers you can use any
// float-point for these two.
// the only thing that changes then is that you don't do this anymore:
audioBuffer[ch][i] = buffer[ch][readHead];
// but:
audioBuffer[ch][i] = buffer[ch][(int)readHead];
// hop into your code, implement this and experiment with the tune-variable to see its
// relationship to the playback speed in action.
// then you can search for the formulars that convert other measures to this
// so you can make your frequency / pitch-knobs.
static double semitonesToTuneRatio(double semitones) {
    return 1. + (semitones / 12.);
}
// for example this considering that you use a xenharmonic scale
// of 12 tones per octave
2 Likes

Thanks for the reply,

I appreciate your process to tune audio playback.
Can we also slow down the speed of audio playback using this process?

Yes, in the example given when tune > 1.0 the audio is playing back faster and raised in pitch. Putting tune < 1.0 will do the opposite.

You can use the following to convert from a MIDI note number to a 12-TET playback ratio centered around C3:

/**
 Calculate playback ratio from MIDI note number (centered around MIDI note 60)

 @param note MIDI note number
 @return Playback ratio
 */
double calculate12TETratio(const double note)
{
    return std::pow(2.0, (note - 60) / 12.0);
}

Okay,

Let me test this.
I will inform once test the above formula.

Hello,

I tried above lines with my application as below:

void MyappAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
    juce::ScopedNoDenormals noDenormals;
    auto totalNumInputChannels  = getTotalNumInputChannels();
    auto totalNumOutputChannels = getTotalNumOutputChannels();
    auto tune = 2.0; // let's introduce a variable that will tune our signal.
    auto readHead = 0; // we need a variable that acts as sort of an index

    for (auto i = 0; i < buffer.getNumSamples(); ++i) {
        for (auto ch = 0; ch < buffer.getNumChannels(); ++ch)
        {
            int chantoread = ch % fileBuffer.getNumChannels();

            //buffer[ch][i] = fileBuffer[ch][readHead]; //this expression not possible
            buffer.setSample(ch, i, tune * fileBuffer.getSample(chantoread, filepos_start));
        }
        readHead += tune;
        while (readHead >= buffer.getNumSamples()) readHead -= buffer.getNumSamples();
    }
}

Is it okay or something wrong?

I am sharing one more function. So you can understand how i am trying to load audio file.

void MyappAudioProcessor::loadFile(juce::File file)
{             
    std::cout << "File path: " << file.getFullPathName() << std::endl;    
    myFormatReader = formatManager.createReaderFor (file);

    if (myFormatReader != nullptr)
    {
        fileBuffer.setSize (myFormatReader->numChannels, (int)myFormatReader->lengthInSamples);   
        
        std::cout << "Number of samples in buffer "<<fileBuffer.getNumSamples()<<std::endl;
        std::cout << "lengthInSamples "<<myFormatReader->lengthInSamples<<std::endl;
        
        myFormatReader->read (&fileBuffer, 0, (int) myFormatReader->lengthInSamples, 0, true, true);

        filepos_end = fileBuffer.getNumSamples();
        

        if (mute == false)
            filepos_start = 0;
        else
            filepos_start = filepos_end;

        thumbnail.setSource (new juce::FileInputSource (file));
        
        play = false;
        mute = false;
        reverse = false;
    }
}

the readHead reads from your file:

buffer.setSample(ch, i, fileBuffer.getSample(chantoread, readHead));

multiplicating something with a signal is applying gain. tune is really just for defining the playback speed:

readHead += tune;
while (readHead >= fileBuffer.getNumSamples()) readHead -= fileBuffer.getNumSamples();

Hello,
Okay.
Then I think it’s the same as I used before.
I used filepos_start instead of tune.
You can see more details as discussed on 11 Sept.

Let me share last one modified definition of “processBlock” function. Its as below:

void MyappAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
    juce::ScopedNoDenormals noDenormals;
    auto totalNumInputChannels  = getTotalNumInputChannels();
    auto totalNumOutputChannels = getTotalNumOutputChannels();
    
    if (fileBuffer.getNumSamples() == 0)
        return;
    
    
    if(play == true)
    {   
        if (reverse == false)
        {
            for (int i = 0; i < buffer.getNumSamples(); ++i)
            {
                for (int j = 0; j < buffer.getNumChannels(); ++j)
                {
                    int chantoread = j % fileBuffer.getNumChannels();

                    if (mute == false)
                    {
                        buffer.setSample(j, i, volume_level * fileBuffer.getSample(chantoread, filepos_start));
                    }
                }
                if ((filepos_start + curFreq) < filepos_end)
                    filepos_start += curFreq;

                ++filepos_start;

                if (filepos_start == filepos_end)
                    filepos_start = filepos_start_temp;
            }
        }
        else
        {
            for (int i = 0; i < buffer.getNumSamples(); ++i)
            {
                for (int j = 0; j < buffer.getNumChannels(); ++j)
                {
                    int chantoread = j % fileBuffer.getNumChannels();

                    if (mute == false)
                    {
                        buffer.setSample(j, i, volume_level * fileBuffer.getSample(chantoread, filepos_start));
                    }
                }
                if ((filepos_start - curFreq) > filepos_start_temp)
                    filepos_start -= curFreq;

                filepos_start--;

                if (filepos_start == filepos_start_temp)
                    filepos_start = filepos_end;
            }
        }
    }
    else
        return;
}

Right?

if your version already worked then what’s still the problem?

Hello,

I shared the same thing before.
But we have doubt that what we are doing. Is it proper or not.
We can speed up/down of audio file by tuning frequency and pitch. Right?
This means if we increase frequency/pitch, speed will be increase by some mathematical expression and the same to down speed. Right?