1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-09-23 15:41:09 +02:00

Make EXPERIMENTAL_FIND_NOTES work again

This commit is contained in:
Paul Licameli 2017-02-12 10:13:23 -05:00
parent dbb2f04def
commit 463e7d971d
4 changed files with 78 additions and 77 deletions

View File

@ -2155,8 +2155,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
#ifdef EXPERIMENTAL_FIND_NOTES #ifdef EXPERIMENTAL_FIND_NOTES
const bool &fftFindNotes = settings.fftFindNotes; const bool &fftFindNotes = settings.fftFindNotes;
const bool &findNotesMinA = settings.findNotesMinA; const double &findNotesMinA = settings.findNotesMinA;
const bool &numberOfMaxima = settings.numberOfMaxima; const int &numberOfMaxima = settings.numberOfMaxima;
const bool &findNotesQuantize = settings.findNotesQuantize; const bool &findNotesQuantize = settings.findNotesQuantize;
#endif #endif
#ifdef EXPERIMENTAL_FFT_Y_GRID #ifdef EXPERIMENTAL_FFT_Y_GRID
@ -2267,6 +2267,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
#endif #endif
#ifdef EXPERIMENTAL_FIND_NOTES #ifdef EXPERIMENTAL_FIND_NOTES
float log2 = logf( 2.0f ),
lmin = logf( minFreq ), lmax = logf( maxFreq ), scale = lmax - lmin,
lmins = lmin, lmins = lmin,
lmaxs = lmax lmaxs = lmax
; ;
@ -2290,6 +2292,71 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
#pragma omp parallel for #pragma omp parallel for
#endif #endif
for (int xx = 0; xx < hiddenMid.width; ++xx) { for (int xx = 0; xx < hiddenMid.width; ++xx) {
#ifdef EXPERIMENTAL_FIND_NOTES
int maximas = 0;
const int x0 = half * xx;
if (fftFindNotes) {
for (int i = maxTableSize - 1; i >= 0; i--)
indexes[i] = -1;
// Build a table of (most) values, put the index in it.
for (int i = (int)(i0); i < (int)(i1); i++) {
float freqi = freq[x0 + (int)(i)];
int value = (int)((freqi + gain + range) / range*(maxTableSize - 1));
if (value < 0)
value = 0;
if (value >= maxTableSize)
value = maxTableSize - 1;
indexes[value] = i;
}
// Build from the indices an array of maxima.
for (int i = maxTableSize - 1; i >= 0; i--) {
int index = indexes[i];
if (index >= 0) {
float freqi = freq[x0 + index];
if (freqi < findNotesMinA)
break;
bool ok = true;
for (int m = 0; m < maximas; m++) {
// Avoid to store very close maxima.
float maxm = maxima[m];
if (maxm / index < minDistance && index / maxm < minDistance) {
ok = false;
break;
}
}
if (ok) {
maxima[maximas++] = index;
if (maximas >= numberOfMaxima)
break;
}
}
}
// The f2pix helper macro converts a frequency into a pixel coordinate.
#define f2pix(f) (logf(f)-lmins)/(lmaxs-lmins)*hiddenMid.height
// Possibly quantize the maxima frequencies and create the pixel block limits.
for (int i = 0; i < maximas; i++) {
int index = maxima[i];
float f = float(index)*bin2f;
if (findNotesQuantize)
{
f = expf((int)(log(f / 440) / log2 * 12 - 0.5) / 12.0f*log2) * 440;
maxima[i] = f*f2bin;
}
float f0 = expf((log(f / 440) / log2 * 24 - 1) / 24.0f*log2) * 440;
maxima0[i] = f2pix(f0);
float f1 = expf((log(f / 440) / log2 * 24 + 1) / 24.0f*log2) * 440;
maxima1[i] = f2pix(f1);
}
}
int it = 0;
bool inMaximum = false;
#endif //EXPERIMENTAL_FIND_NOTES
for (int yy = 0; yy < hiddenMid.height; ++yy) { for (int yy = 0; yy < hiddenMid.height; ++yy) {
const float bin = bins[yy]; const float bin = bins[yy];
const float nextBin = bins[yy+1]; const float nextBin = bins[yy+1];
@ -2300,72 +2367,6 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
clip->mSpecPxCache->values[xx * hiddenMid.height + yy] = value; clip->mSpecPxCache->values[xx * hiddenMid.height + yy] = value;
} }
else { else {
// Do we need this legacy experiment still?
#ifdef EXPERIMENTAL_FIND_NOTES
int maximas = 0;
const int x0 = half * x;
if (fftFindNotes) {
for (int i = maxTableSize - 1; i >= 0; i--)
indexes[i] = -1;
// Build a table of (most) values, put the index in it.
for (int i = (int)(i0); i < (int)(i1); i++) {
float freqi = freq[x0 + (int)(i)];
int value = (int)((freqi + gain + range) / range*(maxTableSize - 1));
if (value < 0)
value = 0;
if (value >= maxTableSize)
value = maxTableSize - 1;
indexes[value] = i;
}
// Build from the indices an array of maxima.
for (int i = maxTableSize - 1; i >= 0; i--) {
int index = indexes[i];
if (index >= 0) {
float freqi = freq[x0 + index];
if (freqi < findNotesMinA)
break;
bool ok = true;
for (int m = 0; m < maximas; m++) {
// Avoid to store very close maxima.
float maxm = maxima[m];
if (maxm / index < minDistance && index / maxm < minDistance) {
ok = false;
break;
}
}
if (ok) {
maxima[maximas++] = index;
if (maximas >= numberOfMaxima)
break;
}
}
}
// The f2pix helper macro converts a frequency into a pixel coordinate.
#define f2pix(f) (logf(f)-lmins)/(lmaxs-lmins)*hiddenMid.height
// Possibly quantize the maxima frequencies and create the pixel block limits.
for (int i = 0; i < maximas; i++) {
int index = maxima[i];
float f = float(index)*bin2f;
if (findNotesQuantize)
{
f = expf((int)(log(f / 440) / log2 * 12 - 0.5) / 12.0f*log2) * 440;
maxima[i] = f*f2bin;
}
float f0 = expf((log(f / 440) / log2 * 24 - 1) / 24.0f*log2) * 440;
maxima0[i] = f2pix(f0);
float f1 = expf((log(f / 440) / log2 * 24 + 1) / 24.0f*log2) * 440;
maxima1[i] = f2pix(f1);
}
}
int it = 0;
int oldBin0 = -1;
bool inMaximum = false;
#endif //EXPERIMENTAL_FIND_NOTES
float value; float value;
#ifdef EXPERIMENTAL_FIND_NOTES #ifdef EXPERIMENTAL_FIND_NOTES

View File

@ -138,8 +138,8 @@ public:
#ifdef EXPERIMENTAL_FIND_NOTES #ifdef EXPERIMENTAL_FIND_NOTES
bool fftFindNotes; bool fftFindNotes;
bool findNotesMinA; double findNotesMinA;
bool numberOfMaxima; int numberOfMaxima;
bool findNotesQuantize; bool findNotesQuantize;
#endif //EXPERIMENTAL_FIND_NOTES #endif //EXPERIMENTAL_FIND_NOTES

View File

@ -107,7 +107,7 @@ void SpectrumPrefs::Populate(size_t windowSize)
//------------------------- Main section -------------------- //------------------------- Main section --------------------
// Now construct the GUI itself. // Now construct the GUI itself.
ShuttleGui S(this, eIsCreating); ShuttleGui S(this, eIsCreatingFromPrefs);
PopulateOrExchange(S); PopulateOrExchange(S);
// ----------------------- End of main section -------------- // ----------------------- End of main section --------------
} }
@ -265,18 +265,18 @@ void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S)
{ {
mFindNotesMinA = mFindNotesMinA =
S.TieNumericTextBox(_("Minimum Amplitude (dB):"), S.TieNumericTextBox(_("Minimum Amplitude (dB):"),
mTempSettings.fftFindNotes, mTempSettings.findNotesMinA,
8); 8);
mFindNotesN = mFindNotesN =
S.TieNumericTextBox(_("Max. Number of Notes (1..128):"), S.TieNumericTextBox(_("Max. Number of Notes (1..128):"),
mTempSettings.findNotesMinA, mTempSettings.numberOfMaxima,
8); 8);
} }
S.EndTwoColumn(); S.EndTwoColumn();
S.TieCheckBox(_("&Find Notes"), S.TieCheckBox(_("&Find Notes"),
mTempSettings.numberOfMaxima); mTempSettings.fftFindNotes);
S.TieCheckBox(_("&Quantize Notes"), S.TieCheckBox(_("&Quantize Notes"),
mTempSettings.findNotesQuantize); mTempSettings.findNotesQuantize);
@ -353,7 +353,7 @@ bool SpectrumPrefs::Validate()
} }
#endif //EXPERIMENTAL_FIND_NOTES #endif //EXPERIMENTAL_FIND_NOTES
ShuttleGui S(this, eIsGettingFromDialog); ShuttleGui S(this, eIsSavingToPrefs);
PopulateOrExchange(S); PopulateOrExchange(S);
// Delegate range checking to SpectrogramSettings class // Delegate range checking to SpectrogramSettings class
@ -376,7 +376,7 @@ bool SpectrumPrefs::Apply()
static_cast<WaveTrack*>(mWt->GetLink()) static_cast<WaveTrack*>(mWt->GetLink())
: nullptr; : nullptr;
ShuttleGui S(this, eIsGettingFromDialog); ShuttleGui S(this, eIsSavingToPrefs);
PopulateOrExchange(S); PopulateOrExchange(S);

View File

@ -64,7 +64,7 @@ void WaveformPrefs::Populate()
//------------------------- Main section -------------------- //------------------------- Main section --------------------
// Now construct the GUI itself. // Now construct the GUI itself.
ShuttleGui S(this, eIsCreating); ShuttleGui S(this, eIsCreatingFromPrefs);
PopulateOrExchange(S); PopulateOrExchange(S);
// ----------------------- End of main section -------------- // ----------------------- End of main section --------------
} }