LibPyin icon indicating copy to clipboard operation
LibPyin copied to clipboard

How to detect if pitch is present?

Open mrdeveloperdude opened this issue 3 years ago • 2 comments

Hello!

I am currently implementing a karaoke machine with a sing-star like game for fun and so far I love your lib, it seems to work out of the box with minimal changes for my C++ Qt5 project which is awesome! Except for my one issue:

This could very well be just me not using the library properly, maybe just a change in documentation?

I am doing the following:

void PitchDetector::processBuffer(QVector<float> &in){
    //lib is in QSharedPointer
    if(!mPyin.isNull()){
        auto instd=in.toStdVector();
        auto sz=in.size();
        std::vector<float> pitches = mPyin->feed(instd);
        auto np=pitches.size();
        auto lastPitchPresent=mPitchPresent;
        // How can I tell if a pitch is present?
        mPitchPresent=(np>0);
        if(mPitchPresent){
            // Just care about first pitch we found
            auto p=pitches[0];
            // What is a valid pitch?
            if(p>0.0){
                mPitch=p;
            }
        }
        auto change=((mPitch!=lastPitch) || (mPitchPresent != lastPitchPresent) );
        if(change){
            qDebug()<<"PITCH SIGNAL: "<<mPitchPresent << mPitch;
            emit noteChanged(mPitchPresent, mPitch);
        }
    }
}

So this works, but the feed() method does always return a pitch! I tried setting different values for ::setCutOff(), including 0.0 and 1.0, but feed never returns without a pitch. The ouput looks like this:

PITCH SIGNAL: true 153 PITCH SIGNAL: true 138 PITCH SIGNAL: true 276 PITCH SIGNAL: true 138 PITCH SIGNAL: true 153 PITCH SIGNAL: true 138 PITCH SIGNAL: true 122 PITCH SIGNAL: true -430 PITCH SIGNAL: true -774 PITCH SIGNAL: true 106 PITCH SIGNAL: true 122

So my question/issue is; How can I know if a pitch was found or not, according to the cut off value selected?

Should I preprocess audio to remove noise?

mrdeveloperdude avatar Mar 14 '22 22:03 mrdeveloperdude

I had a quick look in libpyincpp and there seems to be a bug:

_cut_off member variable is int while setCutOff() accepts float from 0 to 1. This does not use the range of the float properly. In effect it will be a binary 0 or 1 switch.

mrdeveloperdude avatar Mar 14 '22 23:03 mrdeveloperdude

Hi, thanks for finding the issue. As I assume you fixed it already on your end, could you make a pull request? I'd merge it into main.

xstreck1 avatar Mar 17 '22 13:03 xstreck1