Mercurial > hg > svgui
changeset 1064:77564d4fff43 spectrogram-minor-refactor
Extend column logic to peak frequency display as well, and correct some scopes according to whether values are per source column or per target pixel
author | Chris Cannam |
---|---|
date | Mon, 20 Jun 2016 12:00:32 +0100 |
parents | a0f234acd6e7 |
children | 85e49aa7fe77 |
files | layer/SpectrogramLayer.cpp |
diffstat | 1 files changed, 88 insertions(+), 84 deletions(-) [+] |
line wrap: on
line diff
--- a/layer/SpectrogramLayer.cpp Mon Jun 20 11:30:15 2016 +0100 +++ b/layer/SpectrogramLayer.cpp Mon Jun 20 12:00:32 2016 +0100 @@ -2212,15 +2212,10 @@ if (!fft) return 0; FFTModel::PeakSet peakfreqs; - + vector<float> preparedColumn; + int psx = -1; -#ifdef __GNUC__ - float values[maxbin - minbin + 1]; -#else - float *values = (float *)alloca((maxbin - minbin + 1) * sizeof(float)); -#endif - int minColumns = 4; bool haveTimeLimits = (softTimeLimit > 0.0); double hardTimeLimit = softTimeLimit * 2.0; @@ -2252,75 +2247,72 @@ if (sx0 < 0) continue; if (sx1 <= sx0) sx1 = sx0 + 1; + vector<float> pixelPeakColumn; + for (int sx = sx0; sx < sx1; ++sx) { - if (sx < 0 || sx >= int(fft->getWidth())) continue; - - MagnitudeRange mag; + if (sx < 0 || sx >= int(fft->getWidth())) { + continue; + } if (sx != psx) { + + ColumnOp::Column column; + + column = getColumnFromFFTModel(fft, + sx, + minbin, + maxbin - minbin + 1); + + if (m_colourScale != PhaseColourScale) { + column = ColumnOp::fftScale(column, m_fftSize); + } + + recordColumnExtents(column, + sx, + overallMag, + overallMagChanged); + + if (m_colourScale != PhaseColourScale) { + column = ColumnOp::normalize(column, m_normalization); + } + + preparedColumn = ColumnOp::applyGain(column, m_gain); + + psx = sx; + } + + if (sx == sx0) { + pixelPeakColumn = preparedColumn; peakfreqs = fft->getPeakFrequencies(FFTModel::AllPeaks, sx, minbin, maxbin - 1); - if (m_colourScale == PhaseColourScale) { - fft->getPhasesAt(sx, values, minbin, maxbin - minbin + 1); - /*!!! - } else if (m_normalization == ColumnOp::NormalizeColumns) { - fft->getNormalizedMagnitudesAt(sx, values, minbin, maxbin - minbin + 1); - } else if (m_normalization == ColumnOp::NormalizeHybrid) { - float max = fft->getNormalizedMagnitudesAt - (sx, values, minbin, maxbin - minbin + 1); - float scale = log10f(max + 1.f); - for (int i = minbin; i <= maxbin; ++i) { - values[i - minbin] *= scale; - }*/ - } else { - fft->getMagnitudesAt(sx, values, minbin, maxbin - minbin + 1); - } - psx = sx; - } - - for (FFTModel::PeakSet::const_iterator pi = peakfreqs.begin(); - pi != peakfreqs.end(); ++pi) { - - int bin = pi->first; - double freq = pi->second; - - if (bin < minbin) continue; - if (bin > maxbin) break; - - double value = values[bin - minbin]; - - if (m_colourScale != PhaseColourScale) { - if (m_normalization != ColumnOp::NormalizeColumns) { - value /= (m_fftSize/2.0); - } - mag.sample(float(value)); - value *= m_gain; - } - - double y = v->getYForFrequency - (freq, displayMinFreq, displayMaxFreq, logarithmic); - - int iy = int(y + 0.5); - if (iy < 0 || iy >= h) continue; - - m_drawBuffer.setPixel(x, iy, getDisplayValue(v, value)); - } - - if (mag.isSet()) { - if (sx >= int(m_columnMags.size())) { -#ifdef DEBUG_SPECTROGRAM - cerr << "INTERNAL ERROR: " << sx << " >= " - << m_columnMags.size() - << " at SpectrogramLayer.cpp::paintDrawBuffer" - << endl; -#endif - } else { - m_columnMags[sx].sample(mag); - if (overallMag.sample(mag)) overallMagChanged = true; + } else { + for (int i = 0; in_range_for(pixelPeakColumn, i); ++i) { + pixelPeakColumn[i] = std::max(pixelPeakColumn[i], + preparedColumn[i]); } } } + + for (FFTModel::PeakSet::const_iterator pi = peakfreqs.begin(); + pi != peakfreqs.end(); ++pi) { + + int bin = pi->first; + double freq = pi->second; + + if (bin < minbin) continue; + if (bin > maxbin) break; + + double value = pixelPeakColumn[bin - minbin]; + + double y = v->getYForFrequency + (freq, displayMinFreq, displayMaxFreq, logarithmic); + + int iy = int(y + 0.5); + if (iy < 0 || iy >= h) continue; + + m_drawBuffer.setPixel(x, iy, getDisplayValue(v, value)); + } if (haveTimeLimits) { if (columnCount >= minColumns) { @@ -2491,8 +2483,6 @@ if (binforx[x] < 0) continue; - float columnMax = 0.f; - int sx0 = binforx[x] / divisor; int sx1 = sx0; if (x+1 < w) sx1 = binforx[x+1] / divisor; @@ -2500,19 +2490,22 @@ if (sx0 < 0) continue; if (sx1 <= sx0) sx1 = sx0 + 1; + vector<float> pixelPeakColumn; + for (int sx = sx0; sx < sx1; ++sx) { #ifdef DEBUG_SPECTROGRAM_REPAINT // cerr << "sx = " << sx << endl; #endif - if (sx < 0 || sx >= sourceModel->getWidth()) continue; - - MagnitudeRange mag; + if (sx < 0 || sx >= sourceModel->getWidth()) { + continue; + } if (sx != psx) { - // order: get column -> scale -> record extents -> + // order: + // get column -> scale -> record extents -> // normalise -> peak pick -> apply display gain -> // distribute/interpolate @@ -2530,36 +2523,47 @@ maxbin - minbin + 1); } - column = ColumnOp::fftScale(column, m_fftSize); + if (m_colourScale != PhaseColourScale) { + column = ColumnOp::fftScale(column, m_fftSize); + } recordColumnExtents(column, sx, overallMag, overallMagChanged); - column = ColumnOp::normalize(column, m_normalization); + if (m_colourScale != PhaseColourScale) { + column = ColumnOp::normalize(column, m_normalization); + } if (m_binDisplay == PeakBins) { column = ColumnOp::peakPick(column); } preparedColumn = - ColumnOp::distribute - (ColumnOp::applyGain(column, m_gain), - h, - binfory, - minbin, - interpolate); + ColumnOp::distribute(ColumnOp::applyGain(column, m_gain), + h, + binfory, + minbin, + interpolate); psx = sx; } - //!!! now peak of all preparedColumns for this pixel + if (sx == sx0) { + pixelPeakColumn = preparedColumn; + } else { + for (int i = 0; in_range_for(pixelPeakColumn, i); ++i) { + pixelPeakColumn[i] = std::max(pixelPeakColumn[i], + preparedColumn[i]); + } + } } for (int y = 0; y < h; ++y) { - unsigned char pixel = getDisplayValue(v, preparedColumn[y]); - m_drawBuffer.setPixel(x, h-y-1, pixel); + m_drawBuffer.setPixel(x, + h-y-1, + getDisplayValue(v, pixelPeakColumn[y])); } if (haveTimeLimits) {