Using simple C library in Juce project


#1

Hi all

I am working on my first project, a pitch tracker, and found a nice looking library to use: http://www.schmittmachine.com/dywapitchtrack.html

I have use the LiveScrollingAudioDisplay class from the Juce Demo as a starting point, to learn about live sampling of audio input. I managed to extract that class into a seperate project and get it working. However it is only a header file with definitions inside.. I'm not sure the reason for this. 

I am having troubles getting the dywapitchtrack library working. When I use the 'dywapitch_computepitch' function I get a 'No matching function for call' error. However, I have included the header file, and can navigate to it by ctrl-click and 'Jump to definition'. 

My code is below if anyone feels like having a look.

Thanks in advance!

 

 

 

#include "dywapitchtrack.h"




//==============================================================================

/* This component scrolls a continuous waveform showing the audio that's

 coming into whatever audio inputs this object is connected to.


 Copied from Juce demo.

 */

class LiveScrollingAudioDisplay  : public Component,

public AudioIODeviceCallback,

public dywapitchtracker,

private Timer

{

public:

    LiveScrollingAudioDisplay()

    : nextSample (0), subSample (0), accumulator (0)

    {

        setOpaque (true);

        clear();

        

        startTimer (1000 / 75); // use a timer to keep repainting this component

        

        dywapitch_inittracking (&pitchtracker);

        

        

    }

    

    //==============================================================================

    void audioDeviceAboutToStart (AudioIODevice*) override

    {

        clear();

    }


    void audioDeviceStopped() override

    {

        clear();

    }


    void audioDeviceIOCallback (const float** inputChannelData, int numInputChannels,

                                float** outputChannelData, int numOutputChannels,

                                int numSamples) override

    {




        for (int i = 0; i < numSamples; ++i)

        {

            float inputSample = 0;

    

            for (int chan = 0; chan < numInputChannels; ++chan)

                if (inputChannelData[chan] != nullptr)

                    inputSample += std::abs (inputChannelData[chan][i]);  // find the sum of all the channels <-- might not want to do this...

                

            

            psamples[i] = inputSample;

            

            pushSample (5.0f * inputSample); // boost the level to make it more easily visible.

        }



    // We need to clear the output buffers before returning, in case they're full of junk..

    for (int j = 0; j < numOutputChannels; ++j)

        if (outputChannelData[j] != nullptr)

    zeromem (outputChannelData[j], sizeof (float) * (size_t) numSamples);

}


private:

    static const int bufferSize = 1024;

    float samples[bufferSize];

    float psamples[bufferSize];

    double currentPitch;

    int nextSample, subSample;

    float accumulator;

    dywapitchtracker pitchtracker;


void clear()

{

    zeromem (samples, sizeof (samples));

    accumulator = 0;

    subSample = 0;

}


void paint (Graphics& g) override

{

    g.fillAll (Colours::black);


    const float midY = getHeight() * 0.5f;

    int samplesAgo = (nextSample + numElementsInArray (samples) - 1);


    RectangleList<float> waveform;


    for (int x = jmin (getWidth(), (int) numElementsInArray (samples)); --x >= 0;)

    {

        const float sampleSize = midY * samples [samplesAgo-- % numElementsInArray (samples)];

        waveform.addWithoutMerging (Rectangle<float> ((float) x, midY - sampleSize, 1.0f, sampleSize * 2.0f));

    }


    currentPitch = dywapitch_computepitch(&pitchtracker, psamples, 0, 1024);


    g.drawText((String)currentPitch, 1, 1, 50, 15, Justification::topLeft, true);



    g.setColour (Colours::lightgreen);

    g.fillRectList (waveform);

}


void timerCallback() override

{

    repaint();

    

}


void pushSample (const float newSample)

{

    accumulator += newSample;

    

    if (subSample == 0)

    {

        const int inputSamplesPerPixel = 200;

        

        samples[nextSample] = accumulator / inputSamplesPerPixel;

        nextSample = (nextSample + 1) % numElementsInArray (samples);

        subSample = inputSamplesPerPixel;

        accumulator = 0;

    }

    else

    {

        --subSample;

    }

}


JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LiveScrollingAudioDisplay);

};

 


#2

Have you included src/dywapitchtrack.c from the distribution in your project? 

PS. I'm not sure you need to inherit dywapitchtracker? Might need to have an instance of it as a private member of your class?


#3

Turned out to be a schoolboy error - function was expecting a pointer to an array... I tried passing it by ref but still didnt work. Passing it a pointer to an array created with malloc as in the example code has got me over that hurdle. 

Sorry for posting general C++ coding problems here... !