void NoteData::recalcAvgPitch() { _numPeriods = 0.0f; for(int j=startChunk(); j<endChunk(); j++) { _numPeriods += float(channel->framesPerChunk()) / float(channel->dataAtChunk(j)->period); } _avgPitch = bound(freq2pitch(avgFreq()), 0.0, gdata->topPitch()); }
//################################################################################################# //################### PROTECTED ############################################ //################################################################################################# void NootiniSettings::accept() { Tcore::gl()->A->detectMethod = m_methodCombo->currentIndex(); Tcore::gl()->A->minDuration = (qreal)m_durationSpin->value() / 1000.0; Tcore::gl()->A->minimalVol = m_volumeSlider->value(); if (m_freqSpin->value() == 440 ) Tcore::gl()->A->a440diff = 0.0; else Tcore::gl()->A->a440diff = float(freq2pitch((double)m_freqSpin->value()) - freq2pitch(440.0)); m_tartiniParams->threshold = m_thresholdSpin->value(); Tcore::gl()->A->equalLoudness = m_noiseFilterChB->isChecked(); Tcore::gl()->A->minSplitVol = m_splitVolChB->isChecked() ? (qreal)m_splitVolSpin->value() : 0.0; Tcore::gl()->A->skipStillerVal = m_skipStillerChB->isChecked() ? (qreal)m_skipStillerSpin->value() : 0.0; m_tartiniParams->dBFloor = m_dbFlorSpin->value(); m_tartiniParams->doingAutoNoiseFloor = m_calcNoiseChB->isChecked(); QDialog::accept(); }
void NoteData::addData(AnalysisData *analysisData, float periods) { maxLogRMS = MAX(maxLogRMS, analysisData->logrms()); maxIntensityDB = MAX(maxIntensityDB, analysisData->maxIntensityDB()); maxCorrelation = MAX(maxCorrelation, analysisData->correlation()); maxPurity = MAX(maxPurity, analysisData->volumeValue()); _volume = MAX(_volume, dB2Normalised(analysisData->logrms())); _numPeriods += periods; //sum up the periods //_periodOctaveEstimate = analysisData->periodOctaveEstimate; //overwrite the old estimate _avgPitch = bound(freq2pitch(avgFreq()), 0.0, gdata->topPitch()); }
void GData::setFreqA(double x) { _freqA = x; _semitoneOffset = freq2pitch(x) - freq2pitch(440.0); qsettings->setValue("View/freqA", x); }
/** Do a Windowed FFT for use in the Active FFT data window */ void MyTransforms::doChannelDataFFT(Channel *ch, float *curInput, int chunk) { std::copy(curInput, curInput+n, dataTime); applyHanningWindow(dataTime); fftwf_execute(planDataTime2FFT); int nDiv2 = n/2; //LOG RULES: log(sqrt(x)) = log(x) / 2.0 //LOG RULES: log(a * b) = log(a) + log(b) myassert(ch->fftData1.size() == nDiv2); double logSize = log10(double(ch->fftData1.size())); //0.0 //Adjust the coefficents, both real and imaginary part by same amount double sqValue; const double logBase = 100.0; for(int j=1; j<nDiv2; j++) { sqValue = sq(dataFFT[j]) + sq(dataFFT[n-j]); //ch->fftData1[j] = log10(sqrt(sq(dataFFT[j]) + sq(dataFFT[n-j])) / ds); //ch->fftData2[j] = log10(1.0 + sqrt(sqValue)); //ch->fftData2[j] = log10(0.1 + 2.0*sqrt(sqValue) / double(nDiv2) * 9.9) / 2.0 + 0.5; ch->fftData2[j] = logBaseN(logBase, 1.0 + 2.0*sqrt(sqValue) / double(nDiv2) * (logBase-1.0)); if(sqValue > 0.0) ch->fftData1[j] = bound(log10(sqValue) / 2.0 - logSize, gdata->dBFloor(), 0.0); else ch->fftData1[j] = gdata->dBFloor(); } //ch->fftData1[0] = log10(sqrt(sq(dataFFT[0]) + sq(dataFFT[n/2])) / ds); sqValue = sq(dataFFT[0]) + sq(dataFFT[nDiv2]); //ch->fftData2[0] = log10(1.0 + sqrt(sqValue)); //ch->fftData2[0] = log10(0.1 + 2.0*sqrt(sqValue) / double(nDiv2) * 9.9) / 2.0 + 0.5; ch->fftData2[0] = logBaseN(logBase, 1.0 + 2.0*sqrt(sqValue) / double(nDiv2) * (logBase-1.0)); if(sqValue > 0.0) ch->fftData1[0] = bound(log10(sqValue) / 2.0 - logSize, gdata->dBFloor(), 0.0); else ch->fftData1[0] = gdata->dBFloor(); //printf("n = %d, fff = %f\n", nDiv2, *std::max_element(ch->fftData2.begin(), ch->fftData2.end())); //if(gdata->doingActiveCepstrum()) { if(gdata->analysisType() == MPM_MODIFIED_CEPSTRUM) { //std::complex<float> z, y; for(int j=1; j<nDiv2; j++) { //z = std::complex<float>(dataFFT[j], dataFFT[n-j]); //z = std::polar(std::abs(z)+1.0f, std::arg(z)); //y = std::log(z); //dataFFT[j] = y.real(); //dataFFT[n-j] = y.imag(); //dataFFT[j] = ch->fftData1[j]; //dataFFT[j] = log10(1 + sq(dataFFT[j]) + sq(dataFFT[n-j])) * 2; //dataFFT[j] = log10(1.0 + sqrt(sq(dataFFT[j]) + sq(dataFFT[n-j]))); dataFFT[j] = ch->fftData2[j]; dataFFT[n-j] = 0.0; } //dataFFT[0] = ch->fftData1[0]; //dataFFT[0] = log10(1 + sq(dataFFT[0]) + sq(dataFFT[nDiv2])) * 2; //dataFFT[0] = log10(1.0 + sqrt(sq(dataFFT[0]) + sq(dataFFT[nDiv2]))); //dataFFT[0] = log10(1.0 + sqrt(sq(dataFFT[0]) + sq(dataFFT[nDiv2]))); dataFFT[0] = ch->fftData2[0]; //dataFFT[0] = 0.0; dataFFT[nDiv2] = 0.0; fftwf_execute(planDataFFT2Time); //std::copy(dataTime, dataTime + nDiv2, ch->cepstrumData.begin()); //float theMax = *std::max_element(dataTime, dataTime+nDiv2); //printf("theMax = %f\n", dataTime[0]); for(int j=1; j<n; j++) { dataTime[j] /= dataTime[0]; } dataTime[0] = 1.0; for(int j=0; j<nDiv2; j++) ch->cepstrumData[j] = dataTime[j]; AnalysisData &analysisData = *ch->dataAtChunk(chunk); //analysisData.cepstrumIndex = findCepstrumMaximum(dataTime, nDiv2, 0.8f); analysisData.cepstrumIndex = findNSDFsubMaximum(dataTime, nDiv2, 0.6f); analysisData.cepstrumPitch = freq2pitch(double(analysisData.cepstrumIndex) / ch->rate()); /* //Take out everything above the pitch and reverse the cepstrum to get the frequency curve int maxIndex = int(std::max_element(dataTime+10, dataTime+nDiv2) - dataTime) - 3; maxIndex /= 2; //maxIndex = 8; if(maxIndex < 0) maxIndex = 0; //printf("maxIndex = %d\n", maxIndex); for(int j=maxIndex; j<n-maxIndex; j++) dataTime[j] = 0.0; //for(int j=0; j<nDiv2; j++) ch->cepstrumData[j] = dataTime[j]; fftwf_execute(planDataTime2FFT); for(int j=0; j<nDiv2; j++) ch->fftData3[j] = sqrt(sq(dataFFT[j])+sq(dataFFT[n-j]))/2; */ } }
void AudioInSettings::intervalFromFreq(int bFreq) { int interval = qRound(freq2pitch((double)bFreq) - 69.0); m_intervalSpin->setValue(qAbs(interval)); setTransposeInterval(interval); }
float AudioInSettings::getDiff(int freq) { return float(freq2pitch((double)freq) - freq2pitch(440.0)); // in semitones }
int AudioInSettings::getFreq(double freq) { return qRound((pitch2freq(freq2pitch(freq) + m_glParams->a440diff))); }
NootiniSettings::NootiniSettings(TartiniParams* tp, QWidget* parent) : QDialog(parent), m_tartiniParams(tp) { setWindowTitle(tr("Parameters of processing")); setWindowIcon(parent->windowIcon()); QLabel *methodLab = new QLabel(tr("pitch detection mode"), this); m_methodCombo = new QComboBox(this); m_methodCombo->addItem("MPM"); m_methodCombo->addItem("autocorrelation"); m_methodCombo->addItem("MPM + modified cepstrum"); if (Tcore::gl()->A->detectMethod == e_MPM) m_methodCombo->setCurrentIndex(0); else if (Tcore::gl()->A->detectMethod == e_AUTOCORRELATION) m_methodCombo->setCurrentIndex(1); else m_methodCombo->setCurrentIndex(2); QLabel *durHeadLab = new QLabel(tr("minimum note duration"), this); m_durationSpin = new QSpinBox(this); m_durationSpin->setMinimum(10); m_durationSpin->setMaximum(1000); m_durationSpin->setSuffix(" " + tr("[milliseconds]")); m_durationSpin->setSingleStep(50); m_durationSpin->setValue(qRound(Tcore::gl()->A->minDuration * 1000)); // minimum duration is stored in seconds but displayed in milliseconds QLabel *volLabel = new QLabel(tr("minimum volume"), this); m_volumeSlider = new TvolumeSlider(this); m_volumeSlider->setValue(Tcore::gl()->A->minimalVol); m_lowRadio = new QRadioButton(tr("low") + " (2048)", this); m_middleRadio = new QRadioButton(tr("middle") + " (1024)", this); m_highRadio = new QRadioButton(tr("high") + " (512)", this); QButtonGroup *rangeGr = new QButtonGroup(this); rangeGr->addButton(m_lowRadio); rangeGr->addButton(m_middleRadio); rangeGr->addButton(m_highRadio); QLabel *frLab = new QLabel(tr("frequency:"), this); m_freqSpin = new QSpinBox(this); m_freqSpin->setMinimum(200); m_freqSpin->setMaximum(900); m_freqSpin->setSuffix(" Hz"); m_freqSpin->setValue(qRound((pitch2freq(freq2pitch(440) + Tcore::gl()->A->a440diff)))); QLabel *threshLab = new QLabel(tr("threshold of lowest loudness (MPM methods)"), this); m_thresholdSpin = new QSpinBox(this); m_thresholdSpin->setRange(80, 100); m_thresholdSpin->setSuffix(" %"); m_thresholdSpin->setValue(m_tartiniParams->threshold); m_noiseFilterChB = new QCheckBox(tr("noise filter"), this); m_noiseFilterChB->setChecked(Tcore::gl()->A->equalLoudness); m_calcNoiseChB = new QCheckBox(tr("Automatically calculate noise-floor"), this); m_calcNoiseChB->setChecked(m_tartiniParams->doingAutoNoiseFloor); m_splitVolChB = new QCheckBox(tr("split when volume rise"), this); m_splitVolSpin = new QSpinBox(this); m_splitVolChB->setChecked(Tcore::gl()->A->minSplitVol > 0.0); m_splitVolSpin->setRange(5, 50); m_splitVolSpin->setSingleStep(5); m_splitVolSpin->setSuffix(" %"); m_splitVolSpin->setValue(Tcore::gl()->A->minSplitVol); m_skipStillerChB = new QCheckBox(tr("skip stiller than"), this); m_skipStillerSpin = new QSpinBox(this); m_skipStillerSpin->setRange(10, 95); m_skipStillerSpin->setSingleStep(5); m_skipStillerSpin->setSuffix(" %"); m_skipStillerSpin->setStatusTip(m_skipStillerChB->statusTip()); m_skipStillerSpin->setValue(Tcore::gl()->A->skipStillerVal); m_skipStillerChB->setChecked(Tcore::gl()->A->skipStillerVal > 0.0); QLabel *dbLab = new QLabel(tr("dbFloor"), this); m_dbFlorSpin = new QDoubleSpinBox(this); m_dbFlorSpin->setRange(-300, 0); m_dbFlorSpin->setValue(m_tartiniParams->dBFloor); m_drawVolChB = new QCheckBox(tr("draw volume chart"), this); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); QVBoxLayout *lay = new QVBoxLayout; QHBoxLayout *methodLay = new QHBoxLayout; methodLay->addStretch(); methodLay->addWidget(methodLab); methodLay->addWidget(m_methodCombo); methodLay->addStretch(); lay->addLayout(methodLay); QHBoxLayout *durLay = new QHBoxLayout; durLay->addStretch(); durLay->addWidget(durHeadLab); durLay->addWidget(m_durationSpin, 0, Qt::AlignLeft); durLay->addStretch(); lay->addLayout(durLay); QHBoxLayout *volLay = new QHBoxLayout; volLay->addWidget(volLabel); volLay->addWidget(m_volumeSlider); lay->addLayout(volLay); QHBoxLayout *rangeLay = new QHBoxLayout; rangeLay->addWidget(m_lowRadio); rangeLay->addWidget(m_middleRadio); rangeLay->addWidget(m_highRadio); QGroupBox *rangeBox = new QGroupBox(tr("Range of note pitches:"), this); rangeBox->setLayout(rangeLay); lay->addWidget(rangeBox); QHBoxLayout *freqLay = new QHBoxLayout; freqLay->addStretch(); freqLay->addWidget(frLab); freqLay->addWidget(m_freqSpin); freqLay->addStretch(); lay->addLayout(freqLay); QHBoxLayout *threshLay = new QHBoxLayout; threshLay->addStretch(); threshLay->addWidget(threshLab); threshLay->addWidget(m_thresholdSpin); threshLay->addStretch(); lay->addLayout(threshLay); QHBoxLayout *noiseLay = new QHBoxLayout; noiseLay->addStretch(); noiseLay->addWidget(m_noiseFilterChB); noiseLay->addStretch(); noiseLay->addWidget(m_calcNoiseChB); noiseLay->addStretch(); lay->addLayout(noiseLay); QHBoxLayout *splitLay = new QHBoxLayout; splitLay->addStretch(); splitLay->addWidget(m_splitVolChB); splitLay->addWidget(m_splitVolSpin); splitLay->addStretch(); splitLay->addWidget(m_skipStillerChB); splitLay->addWidget(m_skipStillerSpin); splitLay->addStretch(); lay->addLayout(splitLay); QHBoxLayout *dbLay = new QHBoxLayout; dbLay->addStretch(); dbLay->addWidget(dbLab); dbLay->addWidget(m_dbFlorSpin); dbLay->addStretch(); lay->addLayout(dbLay); QHBoxLayout *nootLay = new QHBoxLayout; nootLay->addStretch(); nootLay->addWidget(m_drawVolChB); nootLay->addStretch(); lay->addLayout(nootLay); lay->addWidget(buttonBox); setLayout(lay); connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(m_splitVolChB, &QCheckBox::toggled, this, &NootiniSettings::splitByVolChanged); connect(m_skipStillerChB, &QCheckBox::toggled, this, &NootiniSettings::skipStillerChanged); }