comparison layer/SpectrogramLayer.cpp @ 907:28d05ae8741c cxx11

More type fixes, primarily in the spectrogram
author Chris Cannam
date Tue, 10 Mar 2015 10:31:27 +0000
parents 12ab113ca2b1
children 94e4952a6774 b8187c83b93a
comparison
equal deleted inserted replaced
906:12ab113ca2b1 907:28d05ae8741c
39 #include <QMouseEvent> 39 #include <QMouseEvent>
40 #include <QTextStream> 40 #include <QTextStream>
41 41
42 #include <iostream> 42 #include <iostream>
43 43
44
45
46 #include <cassert> 44 #include <cassert>
47 #include <cmath> 45 #include <cmath>
48 46
49 #ifndef __GNUC__ 47 #ifndef __GNUC__
50 #include <alloca.h> 48 #include <alloca.h>
51 #endif 49 #endif
52 50
53 //#define DEBUG_SPECTROGRAM_REPAINT 1 51 //#define DEBUG_SPECTROGRAM_REPAINT 1
52
53 using std::vector;
54 54
55 SpectrogramLayer::SpectrogramLayer(Configuration config) : 55 SpectrogramLayer::SpectrogramLayer(Configuration config) :
56 m_model(0), 56 m_model(0),
57 m_channel(0), 57 m_channel(0),
58 m_windowSize(1024), 58 m_windowSize(1024),
1145 } 1145 }
1146 1146
1147 ColourMapper mapper(m_colourMap, 1.f, 255.f); 1147 ColourMapper mapper(m_colourMap, 1.f, 255.f);
1148 1148
1149 for (int pixel = 1; pixel < 256; ++pixel) { 1149 for (int pixel = 1; pixel < 256; ++pixel) {
1150 m_palette.setColour(pixel, mapper.map(pixel)); 1150 m_palette.setColour((unsigned char)pixel, mapper.map(pixel));
1151 } 1151 }
1152 1152
1153 m_crosshairColour = mapper.getContrastingColour(); 1153 m_crosshairColour = mapper.getContrastingColour();
1154 1154
1155 m_colourRotation = 0; 1155 m_colourRotation = 0;
1168 1168
1169 for (int pixel = 1; pixel < 256; ++pixel) { 1169 for (int pixel = 1; pixel < 256; ++pixel) {
1170 int target = pixel + distance; 1170 int target = pixel + distance;
1171 while (target < 1) target += 255; 1171 while (target < 1) target += 255;
1172 while (target > 255) target -= 255; 1172 while (target > 255) target -= 255;
1173 newPixels[target] = m_palette.getColour(pixel); 1173 newPixels[target] = m_palette.getColour((unsigned char)pixel);
1174 } 1174 }
1175 1175
1176 for (int pixel = 0; pixel < 256; ++pixel) { 1176 for (int pixel = 0; pixel < 256; ++pixel) {
1177 m_palette.setColour(pixel, newPixels[pixel]); 1177 m_palette.setColour((unsigned char)pixel, newPixels[pixel]);
1178 } 1178 }
1179 1179
1180 m_drawBuffer = QImage(); 1180 m_drawBuffer = QImage();
1181 } 1181 }
1182 1182
1183 unsigned char 1183 unsigned char
1184 SpectrogramLayer::getDisplayValue(View *v, float input) const 1184 SpectrogramLayer::getDisplayValue(View *v, double input) const
1185 { 1185 {
1186 int value; 1186 int value;
1187 1187
1188 float min = 0.f; 1188 double min = 0.0;
1189 float max = 1.f; 1189 double max = 1.0;
1190 1190
1191 if (m_normalizeVisibleArea) { 1191 if (m_normalizeVisibleArea) {
1192 min = m_viewMags[v].getMin(); 1192 min = m_viewMags[v].getMin();
1193 max = m_viewMags[v].getMax(); 1193 max = m_viewMags[v].getMax();
1194 } else if (!m_normalizeColumns) { 1194 } else if (!m_normalizeColumns) {
1195 if (m_colourScale == LinearColourScale //|| 1195 if (m_colourScale == LinearColourScale //||
1196 // m_colourScale == MeterColourScale) { 1196 // m_colourScale == MeterColourScale) {
1197 ) { 1197 ) {
1198 max = 0.1f; 1198 max = 0.1;
1199 } 1199 }
1200 } 1200 }
1201 1201
1202 float thresh = -80.f; 1202 double thresh = -80.0;
1203 1203
1204 if (max == 0.f) max = 1.f; 1204 if (max == 0.0) max = 1.0;
1205 if (max == min) min = max - 0.0001f; 1205 if (max == min) min = max - 0.0001;
1206 1206
1207 switch (m_colourScale) { 1207 switch (m_colourScale) {
1208 1208
1209 default: 1209 default:
1210 case LinearColourScale: 1210 case LinearColourScale:
1211 value = int(((input - min) / (max - min)) * 255.f) + 1; 1211 value = int(((input - min) / (max - min)) * 255.0) + 1;
1212 break; 1212 break;
1213 1213
1214 case MeterColourScale: 1214 case MeterColourScale:
1215 value = AudioLevel::multiplier_to_preview 1215 value = AudioLevel::multiplier_to_preview
1216 ((input - min) / (max - min), 254) + 1; 1216 ((input - min) / (max - min), 254) + 1;
1217 break; 1217 break;
1218 1218
1219 case dBSquaredColourScale: 1219 case dBSquaredColourScale:
1220 input = ((input - min) * (input - min)) / ((max - min) * (max - min)); 1220 input = ((input - min) * (input - min)) / ((max - min) * (max - min));
1221 if (input > 0.f) { 1221 if (input > 0.0) {
1222 input = 10.f * log10f(input); 1222 input = 10.0 * log10(input);
1223 } else { 1223 } else {
1224 input = thresh; 1224 input = thresh;
1225 } 1225 }
1226 if (min > 0.f) { 1226 if (min > 0.0) {
1227 thresh = 10.f * log10f(min * min); 1227 thresh = 10.0 * log10(min * min);
1228 if (thresh < -80.f) thresh = -80.f; 1228 if (thresh < -80.0) thresh = -80.0;
1229 } 1229 }
1230 input = (input - thresh) / (-thresh); 1230 input = (input - thresh) / (-thresh);
1231 if (input < 0.f) input = 0.f; 1231 if (input < 0.0) input = 0.0;
1232 if (input > 1.f) input = 1.f; 1232 if (input > 1.0) input = 1.0;
1233 value = int(input * 255.f) + 1; 1233 value = int(input * 255.0) + 1;
1234 break; 1234 break;
1235 1235
1236 case dBColourScale: 1236 case dBColourScale:
1237 //!!! experiment with normalizing the visible area this way. 1237 //!!! experiment with normalizing the visible area this way.
1238 //In any case, we need to have some indication of what the dB 1238 //In any case, we need to have some indication of what the dB
1239 //scale is relative to. 1239 //scale is relative to.
1240 input = (input - min) / (max - min); 1240 input = (input - min) / (max - min);
1241 if (input > 0.f) { 1241 if (input > 0.0) {
1242 input = 10.f * log10f(input); 1242 input = 10.0 * log10(input);
1243 } else { 1243 } else {
1244 input = thresh; 1244 input = thresh;
1245 } 1245 }
1246 if (min > 0.f) { 1246 if (min > 0.0) {
1247 thresh = 10.f * log10f(min); 1247 thresh = 10.0 * log10(min);
1248 if (thresh < -80.f) thresh = -80.f; 1248 if (thresh < -80.0) thresh = -80.0;
1249 } 1249 }
1250 input = (input - thresh) / (-thresh); 1250 input = (input - thresh) / (-thresh);
1251 if (input < 0.f) input = 0.f; 1251 if (input < 0.0) input = 0.0;
1252 if (input > 1.f) input = 1.f; 1252 if (input > 1.0) input = 1.0;
1253 value = int(input * 255.f) + 1; 1253 value = int(input * 255.0) + 1;
1254 break; 1254 break;
1255 1255
1256 case PhaseColourScale: 1256 case PhaseColourScale:
1257 value = int((input * 127.0 / M_PI) + 128); 1257 value = int((input * 127.0 / M_PI) + 128);
1258 break; 1258 break;
1259 } 1259 }
1260 1260
1261 if (value > UCHAR_MAX) value = UCHAR_MAX; 1261 if (value > UCHAR_MAX) value = UCHAR_MAX;
1262 if (value < 0) value = 0; 1262 if (value < 0) value = 0;
1263 return value; 1263 return (unsigned char)value;
1264 } 1264 }
1265 1265
1266 double 1266 double
1267 SpectrogramLayer::getEffectiveMinFrequency() const 1267 SpectrogramLayer::getEffectiveMinFrequency() const
1268 { 1268 {
1269 int sr = m_model->getSampleRate(); 1269 sv_samplerate_t sr = m_model->getSampleRate();
1270 double minf = double(sr) / m_fftSize; 1270 double minf = double(sr) / m_fftSize;
1271 1271
1272 if (m_minFrequency > 0.0) { 1272 if (m_minFrequency > 0.0) {
1273 int minbin = int((double(m_minFrequency) * m_fftSize) / sr + 0.01); 1273 int minbin = int((double(m_minFrequency) * m_fftSize) / sr + 0.01);
1274 if (minbin < 1) minbin = 1; 1274 if (minbin < 1) minbin = 1;
1279 } 1279 }
1280 1280
1281 double 1281 double
1282 SpectrogramLayer::getEffectiveMaxFrequency() const 1282 SpectrogramLayer::getEffectiveMaxFrequency() const
1283 { 1283 {
1284 int sr = m_model->getSampleRate(); 1284 sv_samplerate_t sr = m_model->getSampleRate();
1285 double maxf = double(sr) / 2; 1285 double maxf = double(sr) / 2;
1286 1286
1287 if (m_maxFrequency > 0.0) { 1287 if (m_maxFrequency > 0.0) {
1288 int maxbin = int((double(m_maxFrequency) * m_fftSize) / sr + 0.1); 1288 int maxbin = int((double(m_maxFrequency) * m_fftSize) / sr + 0.1);
1289 if (maxbin > m_fftSize / 2) maxbin = m_fftSize / 2; 1289 if (maxbin > m_fftSize / 2) maxbin = m_fftSize / 2;
1299 Profiler profiler("SpectrogramLayer::getYBinRange"); 1299 Profiler profiler("SpectrogramLayer::getYBinRange");
1300 1300
1301 int h = v->height(); 1301 int h = v->height();
1302 if (y < 0 || y >= h) return false; 1302 if (y < 0 || y >= h) return false;
1303 1303
1304 int sr = m_model->getSampleRate(); 1304 sv_samplerate_t sr = m_model->getSampleRate();
1305 double minf = getEffectiveMinFrequency(); 1305 double minf = getEffectiveMinFrequency();
1306 double maxf = getEffectiveMaxFrequency(); 1306 double maxf = getEffectiveMaxFrequency();
1307 1307
1308 bool logarithmic = (m_frequencyScale == LogFrequencyScale); 1308 bool logarithmic = (m_frequencyScale == LogFrequencyScale);
1309 1309
1325 Profiler profiler("SpectrogramLayer::getSmoothedYBinRange"); 1325 Profiler profiler("SpectrogramLayer::getSmoothedYBinRange");
1326 1326
1327 int h = v->height(); 1327 int h = v->height();
1328 if (y < 0 || y >= h) return false; 1328 if (y < 0 || y >= h) return false;
1329 1329
1330 int sr = m_model->getSampleRate(); 1330 sv_samplerate_t sr = m_model->getSampleRate();
1331 double minf = getEffectiveMinFrequency(); 1331 double minf = getEffectiveMinFrequency();
1332 double maxf = getEffectiveMaxFrequency(); 1332 double maxf = getEffectiveMaxFrequency();
1333 1333
1334 bool logarithmic = (m_frequencyScale == LogFrequencyScale); 1334 bool logarithmic = (m_frequencyScale == LogFrequencyScale);
1335 1335
1346 } 1346 }
1347 1347
1348 bool 1348 bool
1349 SpectrogramLayer::getXBinRange(View *v, int x, double &s0, double &s1) const 1349 SpectrogramLayer::getXBinRange(View *v, int x, double &s0, double &s1) const
1350 { 1350 {
1351 int modelStart = m_model->getStartFrame(); 1351 sv_frame_t modelStart = m_model->getStartFrame();
1352 int modelEnd = m_model->getEndFrame(); 1352 sv_frame_t modelEnd = m_model->getEndFrame();
1353 1353
1354 // Each pixel column covers an exact range of sample frames: 1354 // Each pixel column covers an exact range of sample frames:
1355 int f0 = v->getFrameForX(x) - modelStart; 1355 sv_frame_t f0 = v->getFrameForX(x) - modelStart;
1356 int f1 = v->getFrameForX(x + 1) - modelStart - 1; 1356 sv_frame_t f1 = v->getFrameForX(x + 1) - modelStart - 1;
1357 1357
1358 if (f1 < int(modelStart) || f0 > int(modelEnd)) { 1358 if (f1 < int(modelStart) || f0 > int(modelEnd)) {
1359 return false; 1359 return false;
1360 } 1360 }
1361 1361
1396 if (!getYBinRange(v, y, q0, q1)) return false; 1396 if (!getYBinRange(v, y, q0, q1)) return false;
1397 1397
1398 int q0i = int(q0 + 0.001); 1398 int q0i = int(q0 + 0.001);
1399 int q1i = int(q1); 1399 int q1i = int(q1);
1400 1400
1401 int sr = m_model->getSampleRate(); 1401 sv_samplerate_t sr = m_model->getSampleRate();
1402 1402
1403 for (int q = q0i; q <= q1i; ++q) { 1403 for (int q = q0i; q <= q1i; ++q) {
1404 if (q == q0i) freqMin = (sr * q) / m_fftSize; 1404 if (q == q0i) freqMin = (sr * q) / m_fftSize;
1405 if (q == q1i) freqMax = (sr * (q+1)) / m_fftSize; 1405 if (q == q1i) freqMax = (sr * (q+1)) / m_fftSize;
1406 } 1406 }
1430 int s1i = int(s1); 1430 int s1i = int(s1);
1431 1431
1432 int q0i = int(q0 + 0.001); 1432 int q0i = int(q0 + 0.001);
1433 int q1i = int(q1); 1433 int q1i = int(q1);
1434 1434
1435 int sr = m_model->getSampleRate(); 1435 sv_samplerate_t sr = m_model->getSampleRate();
1436 1436
1437 bool haveAdj = false; 1437 bool haveAdj = false;
1438 1438
1439 bool peaksOnly = (m_binDisplay == PeakBins || 1439 bool peaksOnly = (m_binDisplay == PeakBins ||
1440 m_binDisplay == PeakFrequencies); 1440 m_binDisplay == PeakFrequencies);
1449 if (q == q0i) freqMin = binfreq; 1449 if (q == q0i) freqMin = binfreq;
1450 if (q == q1i) freqMax = binfreq; 1450 if (q == q1i) freqMax = binfreq;
1451 1451
1452 if (peaksOnly && !fft->isLocalPeak(s, q)) continue; 1452 if (peaksOnly && !fft->isLocalPeak(s, q)) continue;
1453 1453
1454 if (!fft->isOverThreshold(s, q, m_threshold * (m_fftSize/2))) continue; 1454 if (!fft->isOverThreshold(s, q, float(m_threshold * double(m_fftSize)/2.0))) continue;
1455 1455
1456 double freq = binfreq; 1456 double freq = binfreq;
1457 1457
1458 if (s < int(fft->getWidth()) - 1) { 1458 if (s < int(fft->getWidth()) - 1) {
1459 1459
1460 fft->estimateStableFrequency(s, q, freq); 1460 fft->estimateStableFrequency(s, q, freq);
1461 1461
1524 1524
1525 value = fft->getPhaseAt(s, q); 1525 value = fft->getPhaseAt(s, q);
1526 if (!have || value < phaseMin) { phaseMin = value; } 1526 if (!have || value < phaseMin) { phaseMin = value; }
1527 if (!have || value > phaseMax) { phaseMax = value; } 1527 if (!have || value > phaseMax) { phaseMax = value; }
1528 1528
1529 value = fft->getMagnitudeAt(s, q) / (m_fftSize/2); 1529 value = fft->getMagnitudeAt(s, q) / (m_fftSize/2.0);
1530 if (!have || value < min) { min = value; } 1530 if (!have || value < min) { min = value; }
1531 if (!have || value > max) { max = value; } 1531 if (!have || value > max) { max = value; }
1532 1532
1533 have = true; 1533 have = true;
1534 } 1534 }
1556 if (smoothing == Preferences::NoSpectrogramSmoothing || 1556 if (smoothing == Preferences::NoSpectrogramSmoothing ||
1557 smoothing == Preferences::SpectrogramInterpolated) return 0; 1557 smoothing == Preferences::SpectrogramInterpolated) return 0;
1558 1558
1559 if (m_frequencyScale == LogFrequencyScale) return 3; 1559 if (m_frequencyScale == LogFrequencyScale) return 3;
1560 1560
1561 int sr = m_model->getSampleRate(); 1561 sv_samplerate_t sr = m_model->getSampleRate();
1562 1562
1563 int maxbin = m_fftSize / 2; 1563 int maxbin = m_fftSize / 2;
1564 if (m_maxFrequency > 0) { 1564 if (m_maxFrequency > 0) {
1565 maxbin = int((double(m_maxFrequency) * m_fftSize) / sr + 0.1); 1565 maxbin = int((double(m_maxFrequency) * m_fftSize) / sr + 0.1);
1566 if (maxbin > m_fftSize / 2) maxbin = m_fftSize / 2; 1566 if (maxbin > m_fftSize / 2) maxbin = m_fftSize / 2;
1725 1725
1726 int x0 = 0, x1 = v->width(); 1726 int x0 = 0, x1 = v->width();
1727 double s00 = 0, s01 = 0, s10 = 0, s11 = 0; 1727 double s00 = 0, s01 = 0, s10 = 0, s11 = 0;
1728 1728
1729 if (!getXBinRange(v, x0, s00, s01)) { 1729 if (!getXBinRange(v, x0, s00, s01)) {
1730 s00 = s01 = m_model->getStartFrame() / getWindowIncrement(); 1730 s00 = s01 = double(m_model->getStartFrame()) / getWindowIncrement();
1731 } 1731 }
1732 1732
1733 if (!getXBinRange(v, x1, s10, s11)) { 1733 if (!getXBinRange(v, x1, s10, s11)) {
1734 s10 = s11 = m_model->getEndFrame() / getWindowIncrement(); 1734 s10 = s11 = double(m_model->getEndFrame()) / getWindowIncrement();
1735 } 1735 }
1736 1736
1737 int s0 = int(std::min(s00, s10) + 0.0001); 1737 int s0 = int(std::min(s00, s10) + 0.0001);
1738 int s1 = int(std::max(s01, s11) + 0.0001); 1738 int s1 = int(std::max(s01, s11) + 0.0001);
1739 1739
1778 SVDEBUG << "SpectrogramLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << ", m_updateTimer " << m_updateTimer << endl; 1778 SVDEBUG << "SpectrogramLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << ", m_updateTimer " << m_updateTimer << endl;
1779 1779
1780 cerr << "rect is " << rect.x() << "," << rect.y() << " " << rect.width() << "x" << rect.height() << endl; 1780 cerr << "rect is " << rect.x() << "," << rect.y() << " " << rect.width() << "x" << rect.height() << endl;
1781 #endif 1781 #endif
1782 1782
1783 int startFrame = v->getStartFrame(); 1783 sv_frame_t startFrame = v->getStartFrame();
1784 if (startFrame < 0) m_candidateFillStartFrame = 0; 1784 if (startFrame < 0) m_candidateFillStartFrame = 0;
1785 else m_candidateFillStartFrame = startFrame; 1785 else m_candidateFillStartFrame = startFrame;
1786 1786
1787 if (!m_model || !m_model->isOK() || !m_model->isReady()) { 1787 if (!m_model || !m_model->isOK() || !m_model->isReady()) {
1788 return; 1788 return;
1879 dx > -cw && 1879 dx > -cw &&
1880 dx < cw) { 1880 dx < cw) {
1881 1881
1882 int dxp = dx; 1882 int dxp = dx;
1883 if (dxp < 0) dxp = -dxp; 1883 if (dxp < 0) dxp = -dxp;
1884 int copy = (cw - dxp) * sizeof(QRgb); 1884 size_t copy = (cw - dxp) * sizeof(QRgb);
1885 for (int y = 0; y < ch; ++y) { 1885 for (int y = 0; y < ch; ++y) {
1886 QRgb *line = (QRgb *)cache.image.scanLine(y); 1886 QRgb *line = (QRgb *)cache.image.scanLine(y);
1887 if (dx < 0) { 1887 if (dx < 0) {
1888 memmove(line, line + dxp, copy); 1888 memmove(line, line + dxp, copy);
1889 } else { 1889 } else {
2104 2104
2105 #ifdef DEBUG_SPECTROGRAM_REPAINT 2105 #ifdef DEBUG_SPECTROGRAM_REPAINT
2106 cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << endl; 2106 cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << endl;
2107 #endif 2107 #endif
2108 2108
2109 int sr = m_model->getSampleRate(); 2109 sv_samplerate_t sr = m_model->getSampleRate();
2110 2110
2111 // Set minFreq and maxFreq to the frequency extents of the possibly 2111 // Set minFreq and maxFreq to the frequency extents of the possibly
2112 // zero-padded visible bin range, and displayMinFreq and displayMaxFreq 2112 // zero-padded visible bin range, and displayMinFreq and displayMaxFreq
2113 // to the actual scale frequency extents (presumably not zero padded). 2113 // to the actual scale frequency extents (presumably not zero padded).
2114 2114
2194 // we draw up to, and one which we subsequently crop at. 2194 // we draw up to, and one which we subsequently crop at.
2195 2195
2196 bool bufferBinResolution = false; 2196 bool bufferBinResolution = false;
2197 if (increment > zoomLevel) bufferBinResolution = true; 2197 if (increment > zoomLevel) bufferBinResolution = true;
2198 2198
2199 int leftBoundaryFrame = -1, leftCropFrame = -1; 2199 sv_frame_t leftBoundaryFrame = -1, leftCropFrame = -1;
2200 int rightBoundaryFrame = -1, rightCropFrame = -1; 2200 sv_frame_t rightBoundaryFrame = -1, rightCropFrame = -1;
2201 2201
2202 int bufwid; 2202 int bufwid;
2203 2203
2204 if (bufferBinResolution) { 2204 if (bufferBinResolution) {
2205 2205
2206 for (int x = x0; ; --x) { 2206 for (int x = x0; ; --x) {
2207 int f = v->getFrameForX(x); 2207 sv_frame_t f = v->getFrameForX(x);
2208 if ((f / increment) * increment == f) { 2208 if ((f / increment) * increment == f) {
2209 if (leftCropFrame == -1) leftCropFrame = f; 2209 if (leftCropFrame == -1) leftCropFrame = f;
2210 else if (x < x0 - 2) { leftBoundaryFrame = f; break; } 2210 else if (x < x0 - 2) { leftBoundaryFrame = f; break; }
2211 } 2211 }
2212 } 2212 }
2213 for (int x = x0 + w; ; ++x) { 2213 for (int x = x0 + w; ; ++x) {
2214 int f = v->getFrameForX(x); 2214 sv_frame_t f = v->getFrameForX(x);
2215 if ((f / increment) * increment == f) { 2215 if ((f / increment) * increment == f) {
2216 if (rightCropFrame == -1) rightCropFrame = f; 2216 if (rightCropFrame == -1) rightCropFrame = f;
2217 else if (x > x0 + w + 2) { rightBoundaryFrame = f; break; } 2217 else if (x > x0 + w + 2) { rightBoundaryFrame = f; break; }
2218 } 2218 }
2219 } 2219 }
2220 #ifdef DEBUG_SPECTROGRAM_REPAINT 2220 #ifdef DEBUG_SPECTROGRAM_REPAINT
2221 cerr << "Left: crop: " << leftCropFrame << " (bin " << leftCropFrame/increment << "); boundary: " << leftBoundaryFrame << " (bin " << leftBoundaryFrame/increment << ")" << endl; 2221 cerr << "Left: crop: " << leftCropFrame << " (bin " << leftCropFrame/increment << "); boundary: " << leftBoundaryFrame << " (bin " << leftBoundaryFrame/increment << ")" << endl;
2222 cerr << "Right: crop: " << rightCropFrame << " (bin " << rightCropFrame/increment << "); boundary: " << rightBoundaryFrame << " (bin " << rightBoundaryFrame/increment << ")" << endl; 2222 cerr << "Right: crop: " << rightCropFrame << " (bin " << rightCropFrame/increment << "); boundary: " << rightBoundaryFrame << " (bin " << rightBoundaryFrame/increment << ")" << endl;
2223 #endif 2223 #endif
2224 2224
2225 bufwid = (rightBoundaryFrame - leftBoundaryFrame) / increment; 2225 bufwid = int((rightBoundaryFrame - leftBoundaryFrame) / increment);
2226 2226
2227 } else { 2227 } else {
2228 2228
2229 bufwid = w; 2229 bufwid = w;
2230 } 2230 }
2231 2231
2232 #ifdef __GNUC__ 2232 vector<int> binforx(bufwid);
2233 int binforx[bufwid]; 2233 vector<double> binfory(h);
2234 double binfory[h]; 2234
2235 #else
2236 int *binforx = (int *)alloca(bufwid * sizeof(int));
2237 double *binfory = (double *)alloca(h * sizeof(double));
2238 #endif
2239
2240 bool usePeaksCache = false; 2235 bool usePeaksCache = false;
2241 2236
2242 if (bufferBinResolution) { 2237 if (bufferBinResolution) {
2243 for (int x = 0; x < bufwid; ++x) { 2238 for (int x = 0; x < bufwid; ++x) {
2244 binforx[x] = (leftBoundaryFrame / increment) + x; 2239 binforx[x] = int(leftBoundaryFrame / increment) + x;
2245 // cerr << "binforx[" << x << "] = " << binforx[x] << endl; 2240 // cerr << "binforx[" << x << "] = " << binforx[x] << endl;
2246 } 2241 }
2247 m_drawBuffer = QImage(bufwid, h, QImage::Format_Indexed8); 2242 m_drawBuffer = QImage(bufwid, h, QImage::Format_Indexed8);
2248 } else { 2243 } else {
2249 for (int x = 0; x < bufwid; ++x) { 2244 for (int x = 0; x < bufwid; ++x) {
2261 if (m_colourScale == PhaseColourScale) usePeaksCache = false; 2256 if (m_colourScale == PhaseColourScale) usePeaksCache = false;
2262 } 2257 }
2263 2258
2264 // No longer exists in Qt5: m_drawBuffer.setNumColors(256); 2259 // No longer exists in Qt5: m_drawBuffer.setNumColors(256);
2265 for (int pixel = 0; pixel < 256; ++pixel) { 2260 for (int pixel = 0; pixel < 256; ++pixel) {
2266 m_drawBuffer.setColor(pixel, m_palette.getColour(pixel).rgb()); 2261 m_drawBuffer.setColor((unsigned char)pixel,
2262 m_palette.getColour((unsigned char)pixel).rgb());
2267 } 2263 }
2268 2264
2269 m_drawBuffer.fill(0); 2265 m_drawBuffer.fill(0);
2270 2266
2271 if (m_binDisplay != PeakFrequencies) { 2267 if (m_binDisplay != PeakFrequencies) {
2455 2451
2456 bool 2452 bool
2457 SpectrogramLayer::paintDrawBufferPeakFrequencies(View *v, 2453 SpectrogramLayer::paintDrawBufferPeakFrequencies(View *v,
2458 int w, 2454 int w,
2459 int h, 2455 int h,
2460 int *binforx, 2456 const vector<int> &binforx,
2461 int minbin, 2457 int minbin,
2462 int maxbin, 2458 int maxbin,
2463 double displayMinFreq, 2459 double displayMinFreq,
2464 double displayMaxFreq, 2460 double displayMaxFreq,
2465 bool logarithmic, 2461 bool logarithmic,
2523 } else if (m_normalizeHybrid) { 2519 } else if (m_normalizeHybrid) {
2524 fft->getNormalizedMagnitudesAt(sx, values, minbin, maxbin - minbin + 1); 2520 fft->getNormalizedMagnitudesAt(sx, values, minbin, maxbin - minbin + 1);
2525 double max = fft->getMaximumMagnitudeAt(sx); 2521 double max = fft->getMaximumMagnitudeAt(sx);
2526 if (max > 0.f) { 2522 if (max > 0.f) {
2527 for (int i = minbin; i <= maxbin; ++i) { 2523 for (int i = minbin; i <= maxbin; ++i) {
2528 values[i - minbin] *= log10(max); 2524 values[i - minbin] = float(values[i - minbin] * log10(max));
2529 } 2525 }
2530 } 2526 }
2531 } else { 2527 } else {
2532 fft->getMagnitudesAt(sx, values, minbin, maxbin - minbin + 1); 2528 fft->getMagnitudesAt(sx, values, minbin, maxbin - minbin + 1);
2533 } 2529 }
2536 2532
2537 for (FFTModel::PeakSet::const_iterator pi = peakfreqs.begin(); 2533 for (FFTModel::PeakSet::const_iterator pi = peakfreqs.begin();
2538 pi != peakfreqs.end(); ++pi) { 2534 pi != peakfreqs.end(); ++pi) {
2539 2535
2540 int bin = pi->first; 2536 int bin = pi->first;
2541 int freq = pi->second; 2537 double freq = pi->second;
2542 2538
2543 if (bin < minbin) continue; 2539 if (bin < minbin) continue;
2544 if (bin > maxbin) break; 2540 if (bin > maxbin) break;
2545 2541
2546 float value = values[bin - minbin]; 2542 double value = values[bin - minbin];
2547 2543
2548 if (m_colourScale != PhaseColourScale) { 2544 if (m_colourScale != PhaseColourScale) {
2549 if (!m_normalizeColumns && !m_normalizeHybrid) { 2545 if (!m_normalizeColumns && !m_normalizeHybrid) {
2550 value /= (m_fftSize/2.f); 2546 value /= (m_fftSize/2.0);
2551 } 2547 }
2552 mag.sample(value); 2548 mag.sample(float(value));
2553 value *= m_gain; 2549 value *= m_gain;
2554 } 2550 }
2555 2551
2556 double y = v->getYForFrequency 2552 double y = v->getYForFrequency
2557 (freq, displayMinFreq, displayMaxFreq, logarithmic); 2553 (freq, displayMinFreq, displayMaxFreq, logarithmic);
2583 2579
2584 bool 2580 bool
2585 SpectrogramLayer::paintDrawBuffer(View *v, 2581 SpectrogramLayer::paintDrawBuffer(View *v,
2586 int w, 2582 int w,
2587 int h, 2583 int h,
2588 int *binforx, 2584 const vector<int> &binforx,
2589 double *binfory, 2585 const vector<double> &binfory,
2590 bool usePeaksCache, 2586 bool usePeaksCache,
2591 MagnitudeRange &overallMag, 2587 MagnitudeRange &overallMag,
2592 bool &overallMagChanged) const 2588 bool &overallMagChanged) const
2593 { 2589 {
2594 Profiler profiler("SpectrogramLayer::paintDrawBuffer"); 2590 Profiler profiler("SpectrogramLayer::paintDrawBuffer");
2595 2591
2596 int minbin = int(binfory[0] + 0.0001); 2592 int minbin = int(binfory[0] + 0.0001);
2597 int maxbin = binfory[h-1]; 2593 int maxbin = int(binfory[h-1]);
2598 2594
2599 #ifdef DEBUG_SPECTROGRAM_REPAINT 2595 #ifdef DEBUG_SPECTROGRAM_REPAINT
2600 cerr << "minbin " << minbin << ", maxbin " << maxbin << "; w " << w << ", h " << h << endl; 2596 cerr << "minbin " << minbin << ", maxbin " << maxbin << "; w " << w << ", h " << h << endl;
2601 #endif 2597 #endif
2602 if (minbin < 0) minbin = 0; 2598 if (minbin < 0) minbin = 0;
2689 fft->getNormalizedMagnitudesAt(sx, autoarray, minbin, maxbin - minbin + 1); 2685 fft->getNormalizedMagnitudesAt(sx, autoarray, minbin, maxbin - minbin + 1);
2690 } else if (m_normalizeHybrid) { 2686 } else if (m_normalizeHybrid) {
2691 fft->getNormalizedMagnitudesAt(sx, autoarray, minbin, maxbin - minbin + 1); 2687 fft->getNormalizedMagnitudesAt(sx, autoarray, minbin, maxbin - minbin + 1);
2692 double max = fft->getMaximumMagnitudeAt(sx); 2688 double max = fft->getMaximumMagnitudeAt(sx);
2693 for (int i = minbin; i <= maxbin; ++i) { 2689 for (int i = minbin; i <= maxbin; ++i) {
2694 if (max > 0.f) { 2690 if (max > 0.0) {
2695 autoarray[i - minbin] *= log10(max); 2691 autoarray[i - minbin] = float(autoarray[i - minbin] * log10(max));
2696 } 2692 }
2697 } 2693 }
2698 } else { 2694 } else {
2699 fft->getMagnitudesAt(sx, autoarray, minbin, maxbin - minbin + 1); 2695 fft->getMagnitudesAt(sx, autoarray, minbin, maxbin - minbin + 1);
2700 } 2696 }
2717 2713
2718 double sy0 = binfory[y]; 2714 double sy0 = binfory[y];
2719 double sy1 = sy0 + 1; 2715 double sy1 = sy0 + 1;
2720 if (y+1 < h) sy1 = binfory[y+1]; 2716 if (y+1 < h) sy1 = binfory[y+1];
2721 2717
2722 double value = 0.f; 2718 double value = 0.0;
2723 2719
2724 if (interpolate && fabsf(sy1 - sy0) < 1.f) { 2720 if (interpolate && fabs(sy1 - sy0) < 1.0) {
2725 2721
2726 double centre = (sy0 + sy1) / 2; 2722 double centre = (sy0 + sy1) / 2;
2727 double dist = (centre - 0.5) - lrintf(centre - 0.5); 2723 double dist = (centre - 0.5) - rint(centre - 0.5);
2728 int bin = int(centre); 2724 int bin = int(centre);
2729 int other = (dist < 0 ? (bin-1) : (bin+1)); 2725 int other = (dist < 0 ? (bin-1) : (bin+1));
2730 if (bin < minbin) bin = minbin; 2726 if (bin < minbin) bin = minbin;
2731 if (bin > maxbin) bin = maxbin; 2727 if (bin > maxbin) bin = maxbin;
2732 if (other < minbin || other > maxbin) other = bin; 2728 if (other < minbin || other > maxbin) other = bin;
2733 double prop = 1.f - fabsf(dist); 2729 double prop = 1.0 - fabs(dist);
2734 2730
2735 double v0 = values[bin - minbin]; 2731 double v0 = values[bin - minbin];
2736 double v1 = values[other - minbin]; 2732 double v1 = values[other - minbin];
2737 if (m_binDisplay == PeakBins) { 2733 if (m_binDisplay == PeakBins) {
2738 if (bin == minbin || bin == maxbin || 2734 if (bin == minbin || bin == maxbin ||
2739 v0 < values[bin-minbin-1] || 2735 v0 < values[bin-minbin-1] ||
2740 v0 < values[bin-minbin+1]) v0 = 0.f; 2736 v0 < values[bin-minbin+1]) v0 = 0.0;
2741 if (other == minbin || other == maxbin || 2737 if (other == minbin || other == maxbin ||
2742 v1 < values[other-minbin-1] || 2738 v1 < values[other-minbin-1] ||
2743 v1 < values[other-minbin+1]) v1 = 0.f; 2739 v1 < values[other-minbin+1]) v1 = 0.0;
2744 } 2740 }
2745 if (v0 == 0.f && v1 == 0.f) continue; 2741 if (v0 == 0.0 && v1 == 0.0) continue;
2746 value = prop * v0 + (1.f - prop) * v1; 2742 value = prop * v0 + (1.0 - prop) * v1;
2747 2743
2748 if (m_colourScale != PhaseColourScale) { 2744 if (m_colourScale != PhaseColourScale) {
2749 if (!m_normalizeColumns) { 2745 if (!m_normalizeColumns) {
2750 value /= (m_fftSize/2.f); 2746 value /= (m_fftSize/2.0);
2751 } 2747 }
2752 mag.sample(value); 2748 mag.sample(float(value));
2753 value *= m_gain; 2749 value *= m_gain;
2754 } 2750 }
2755 2751
2756 peaks[y] = value; 2752 peaks[y] = float(value);
2757 2753
2758 } else { 2754 } else {
2759 2755
2760 int by0 = int(sy0 + 0.0001); 2756 int by0 = int(sy0 + 0.0001);
2761 int by1 = int(sy1 + 0.0001); 2757 int by1 = int(sy1 + 0.0001);
2770 value < values[bin-minbin+1]) continue; 2766 value < values[bin-minbin+1]) continue;
2771 } 2767 }
2772 2768
2773 if (m_colourScale != PhaseColourScale) { 2769 if (m_colourScale != PhaseColourScale) {
2774 if (!m_normalizeColumns) { 2770 if (!m_normalizeColumns) {
2775 value /= (m_fftSize/2.f); 2771 value /= (m_fftSize/2.0);
2776 } 2772 }
2777 mag.sample(value); 2773 mag.sample(float(value));
2778 value *= m_gain; 2774 value *= m_gain;
2779 } 2775 }
2780 2776
2781 if (value > peaks[y]) peaks[y] = value; //!!! not right for phase! 2777 if (value > peaks[y]) {
2778 peaks[y] = float(value); //!!! not right for phase!
2779 }
2782 } 2780 }
2783 } 2781 }
2784 } 2782 }
2785 2783
2786 if (mag.isSet()) { 2784 if (mag.isSet()) {
2901 SpectrogramLayer::getValueExtents(double &min, double &max, 2899 SpectrogramLayer::getValueExtents(double &min, double &max,
2902 bool &logarithmic, QString &unit) const 2900 bool &logarithmic, QString &unit) const
2903 { 2901 {
2904 if (!m_model) return false; 2902 if (!m_model) return false;
2905 2903
2906 int sr = m_model->getSampleRate(); 2904 sv_samplerate_t sr = m_model->getSampleRate();
2907 min = double(sr) / m_fftSize; 2905 min = double(sr) / m_fftSize;
2908 max = double(sr) / 2; 2906 max = double(sr) / 2;
2909 2907
2910 logarithmic = (m_frequencyScale == LogFrequencyScale); 2908 logarithmic = (m_frequencyScale == LogFrequencyScale);
2911 unit = "Hz"; 2909 unit = "Hz";
2928 if (!m_model) return false; 2926 if (!m_model) return false;
2929 2927
2930 // SVDEBUG << "SpectrogramLayer::setDisplayExtents: " << min << "->" << max << endl; 2928 // SVDEBUG << "SpectrogramLayer::setDisplayExtents: " << min << "->" << max << endl;
2931 2929
2932 if (min < 0) min = 0; 2930 if (min < 0) min = 0;
2933 if (max > m_model->getSampleRate()/2.f) max = m_model->getSampleRate()/2.f; 2931 if (max > m_model->getSampleRate()/2.0) max = m_model->getSampleRate()/2.0;
2934 2932
2935 int minf = lrintf(min); 2933 int minf = int(lrint(min));
2936 int maxf = lrintf(max); 2934 int maxf = int(lrint(max));
2937 2935
2938 if (m_minFrequency == minf && m_maxFrequency == maxf) return true; 2936 if (m_minFrequency == minf && m_maxFrequency == maxf) return true;
2939 2937
2940 invalidateImageCaches(); 2938 invalidateImageCaches();
2941 invalidateMagnitudes(); 2939 invalidateMagnitudes();
2962 unit = "Hz"; 2960 unit = "Hz";
2963 return true; 2961 return true;
2964 } 2962 }
2965 2963
2966 bool 2964 bool
2967 SpectrogramLayer::snapToFeatureFrame(View *, int &frame, 2965 SpectrogramLayer::snapToFeatureFrame(View *,
2966 sv_frame_t &frame,
2968 int &resolution, 2967 int &resolution,
2969 SnapType snap) const 2968 SnapType snap) const
2970 { 2969 {
2971 resolution = getWindowIncrement(); 2970 resolution = getWindowIncrement();
2972 int left = (frame / resolution) * resolution; 2971 sv_frame_t left = (frame / resolution) * resolution;
2973 int right = left + resolution; 2972 sv_frame_t right = left + resolution;
2974 2973
2975 switch (snap) { 2974 switch (snap) {
2976 case SnapLeft: frame = left; break; 2975 case SnapLeft: frame = left; break;
2977 case SnapRight: frame = right; break; 2976 case SnapRight: frame = right; break;
2978 case SnapNearest: 2977 case SnapNearest:
3077 cursorPos.y() + paint.fontMetrics().ascent() + 2, 3076 cursorPos.y() + paint.fontMetrics().ascent() + 2,
3078 pitchLabel, 3077 pitchLabel,
3079 View::OutlinedText); 3078 View::OutlinedText);
3080 } 3079 }
3081 3080
3082 int frame = v->getFrameForX(cursorPos.x()); 3081 sv_frame_t frame = v->getFrameForX(cursorPos.x());
3083 RealTime rt = RealTime::frame2RealTime(frame, m_model->getSampleRate()); 3082 RealTime rt = RealTime::frame2RealTime(frame, m_model->getSampleRate());
3084 QString rtLabel = QString("%1 s").arg(rt.toText(true).c_str()); 3083 QString rtLabel = QString("%1 s").arg(rt.toText(true).c_str());
3085 QString frameLabel = QString("%1").arg(frame); 3084 QString frameLabel = QString("%1").arg(frame);
3086 v->drawVisibleText(paint, 3085 v->drawVisibleText(paint,
3087 cursorPos.x() - paint.fontMetrics().width(frameLabel) - 2, 3086 cursorPos.x() - paint.fontMetrics().width(frameLabel) - 2,
3096 3095
3097 int harmonic = 2; 3096 int harmonic = 2;
3098 3097
3099 while (harmonic < 100) { 3098 while (harmonic < 100) {
3100 3099
3101 double hy = lrintf(getYForFrequency(v, fundamental * harmonic)); 3100 int hy = int(lrint(getYForFrequency(v, fundamental * harmonic)));
3102 if (hy < 0 || hy > v->height()) break; 3101 if (hy < 0 || hy > v->height()) break;
3103 3102
3104 int len = 7; 3103 int len = 7;
3105 3104
3106 if (harmonic % 2 == 0) { 3105 if (harmonic % 2 == 0) {
3110 len = 10; 3109 len = 10;
3111 } 3110 }
3112 } 3111 }
3113 3112
3114 paint.drawLine(cursorPos.x() - len, 3113 paint.drawLine(cursorPos.x() - len,
3115 int(hy), 3114 hy,
3116 cursorPos.x(), 3115 cursorPos.x(),
3117 int(hy)); 3116 hy);
3118 3117
3119 ++harmonic; 3118 ++harmonic;
3120 } 3119 }
3121 3120
3122 paint.restore(); 3121 paint.restore();
3210 QString dbMinString; 3209 QString dbMinString;
3211 QString dbMaxString; 3210 QString dbMaxString;
3212 if (dbMin == AudioLevel::DB_FLOOR) { 3211 if (dbMin == AudioLevel::DB_FLOOR) {
3213 dbMinString = tr("-Inf"); 3212 dbMinString = tr("-Inf");
3214 } else { 3213 } else {
3215 dbMinString = QString("%1").arg(lrintf(dbMin)); 3214 dbMinString = QString("%1").arg(lrint(dbMin));
3216 } 3215 }
3217 if (dbMax == AudioLevel::DB_FLOOR) { 3216 if (dbMax == AudioLevel::DB_FLOOR) {
3218 dbMaxString = tr("-Inf"); 3217 dbMaxString = tr("-Inf");
3219 } else { 3218 } else {
3220 dbMaxString = QString("%1").arg(lrintf(dbMax)); 3219 dbMaxString = QString("%1").arg(lrint(dbMax));
3221 } 3220 }
3222 if (lrintf(dbMin) != lrintf(dbMax)) { 3221 if (lrint(dbMin) != lrint(dbMax)) {
3223 text += tr("dB:\t%1 - %2").arg(dbMinString).arg(dbMaxString); 3222 text += tr("dB:\t%1 - %2").arg(dbMinString).arg(dbMaxString);
3224 } else { 3223 } else {
3225 text += tr("dB:\t%1").arg(dbMinString); 3224 text += tr("dB:\t%1").arg(dbMinString);
3226 } 3225 }
3227 if (phaseMin != phaseMax) { 3226 if (phaseMin != phaseMax) {
3280 3279
3281 int tickw = (m_frequencyScale == LogFrequencyScale ? 10 : 4); 3280 int tickw = (m_frequencyScale == LogFrequencyScale ? 10 : 4);
3282 int pkw = (m_frequencyScale == LogFrequencyScale ? 10 : 0); 3281 int pkw = (m_frequencyScale == LogFrequencyScale ? 10 : 0);
3283 3282
3284 int bins = m_fftSize / 2; 3283 int bins = m_fftSize / 2;
3285 int sr = m_model->getSampleRate(); 3284 sv_samplerate_t sr = m_model->getSampleRate();
3286 3285
3287 if (m_maxFrequency > 0) { 3286 if (m_maxFrequency > 0) {
3288 bins = int((double(m_maxFrequency) * m_fftSize) / sr + 0.1); 3287 bins = int((double(m_maxFrequency) * m_fftSize) / sr + 0.1);
3289 if (bins > m_fftSize / 2) bins = m_fftSize / 2; 3288 if (bins > m_fftSize / 2) bins = m_fftSize / 2;
3290 } 3289 }
3313 3312
3314 double dBmin = AudioLevel::multiplier_to_dB(min); 3313 double dBmin = AudioLevel::multiplier_to_dB(min);
3315 double dBmax = AudioLevel::multiplier_to_dB(max); 3314 double dBmax = AudioLevel::multiplier_to_dB(max);
3316 3315
3317 if (dBmax < -60.f) dBmax = -60.f; 3316 if (dBmax < -60.f) dBmax = -60.f;
3318 else top = QString("%1").arg(lrintf(dBmax)); 3317 else top = QString("%1").arg(lrint(dBmax));
3319 3318
3320 if (dBmin < dBmax - 60.f) dBmin = dBmax - 60.f; 3319 if (dBmin < dBmax - 60.f) dBmin = dBmax - 60.f;
3321 bottom = QString("%1").arg(lrintf(dBmin)); 3320 bottom = QString("%1").arg(lrint(dBmin));
3322 3321
3323 //!!! & phase etc 3322 //!!! & phase etc
3324 3323
3325 if (m_colourScale != PhaseColourScale) { 3324 if (m_colourScale != PhaseColourScale) {
3326 paint.drawText((cw + 6 - paint.fontMetrics().width("dBFS")) / 2, 3325 paint.drawText((cw + 6 - paint.fontMetrics().width("dBFS")) / 2,
3346 int idb = int(dBval); 3345 int idb = int(dBval);
3347 3346
3348 double value = AudioLevel::dB_to_multiplier(dBval); 3347 double value = AudioLevel::dB_to_multiplier(dBval);
3349 int colour = getDisplayValue(v, value * m_gain); 3348 int colour = getDisplayValue(v, value * m_gain);
3350 3349
3351 paint.setPen(m_palette.getColour(colour)); 3350 paint.setPen(m_palette.getColour((unsigned char)colour));
3352 3351
3353 int y = textHeight * topLines + 4 + ch - i; 3352 int y = textHeight * topLines + 4 + ch - i;
3354 3353
3355 paint.drawLine(5 + cw - cbw, y, cw + 2, y); 3354 paint.drawLine(5 + cw - cbw, y, cw + 2, y);
3356 3355
3392 bin = int(q0); 3391 bin = int(q0);
3393 } else { 3392 } else {
3394 continue; 3393 continue;
3395 } 3394 }
3396 3395
3397 int freq = (sr * bin) / m_fftSize; 3396 int freq = int((sr * bin) / m_fftSize);
3398 3397
3399 if (py >= 0 && (vy - py) < textHeight - 1) { 3398 if (py >= 0 && (vy - py) < textHeight - 1) {
3400 if (m_frequencyScale == LinearFrequencyScale) { 3399 if (m_frequencyScale == LinearFrequencyScale) {
3401 paint.drawLine(w - tickw, h - vy, w, h - vy); 3400 paint.drawLine(w - tickw, h - vy, w, h - vy);
3402 } 3401 }
3487 int 3486 int
3488 SpectrogramLayer::getVerticalZoomSteps(int &defaultStep) const 3487 SpectrogramLayer::getVerticalZoomSteps(int &defaultStep) const
3489 { 3488 {
3490 if (!m_model) return 0; 3489 if (!m_model) return 0;
3491 3490
3492 int sr = m_model->getSampleRate(); 3491 sv_samplerate_t sr = m_model->getSampleRate();
3493 3492
3494 SpectrogramRangeMapper mapper(sr, m_fftSize); 3493 SpectrogramRangeMapper mapper(sr, m_fftSize);
3495 3494
3496 // int maxStep = mapper.getPositionForValue((double(sr) / m_fftSize) + 0.001); 3495 // int maxStep = mapper.getPositionForValue((double(sr) / m_fftSize) + 0.001);
3497 int maxStep = mapper.getPositionForValue(0); 3496 int maxStep = mapper.getPositionForValue(0);
3498 int minStep = mapper.getPositionForValue(double(sr) / 2); 3497 int minStep = mapper.getPositionForValue(double(sr) / 2);
3499 3498
3500 int initialMax = m_initialMaxFrequency; 3499 int initialMax = m_initialMaxFrequency;
3501 if (initialMax == 0) initialMax = sr / 2; 3500 if (initialMax == 0) initialMax = int(sr / 2);
3502 3501
3503 defaultStep = mapper.getPositionForValue(initialMax) - minStep; 3502 defaultStep = mapper.getPositionForValue(initialMax) - minStep;
3504 3503
3505 // SVDEBUG << "SpectrogramLayer::getVerticalZoomSteps: " << maxStep - minStep << " (" << maxStep <<"-" << minStep << "), default is " << defaultStep << " (from initial max freq " << initialMax << ")" << endl; 3504 // SVDEBUG << "SpectrogramLayer::getVerticalZoomSteps: " << maxStep - minStep << " (" << maxStep <<"-" << minStep << "), default is " << defaultStep << " (from initial max freq " << initialMax << ")" << endl;
3506 3505
3529 double dmin = m_minFrequency, dmax = m_maxFrequency; 3528 double dmin = m_minFrequency, dmax = m_maxFrequency;
3530 // getDisplayExtents(dmin, dmax); 3529 // getDisplayExtents(dmin, dmax);
3531 3530
3532 // cerr << "current range " << dmin << " -> " << dmax << ", range " << dmax-dmin << ", mid " << (dmax + dmin)/2 << endl; 3531 // cerr << "current range " << dmin << " -> " << dmax << ", range " << dmax-dmin << ", mid " << (dmax + dmin)/2 << endl;
3533 3532
3534 int sr = m_model->getSampleRate(); 3533 sv_samplerate_t sr = m_model->getSampleRate();
3535 SpectrogramRangeMapper mapper(sr, m_fftSize); 3534 SpectrogramRangeMapper mapper(sr, m_fftSize);
3536 double newdist = mapper.getValueForPosition(step); 3535 double newdist = mapper.getValueForPosition(step);
3537 3536
3538 double newmin, newmax; 3537 double newmin, newmax;
3539 3538
3558 // so exp(2logmid) = exp(log(dmin) + log(dmax)) 3557 // so exp(2logmid) = exp(log(dmin) + log(dmax))
3559 // = exp(log(dmin.dmax)) 3558 // = exp(log(dmin.dmax))
3560 // = dmin.dmax 3559 // = dmin.dmax
3561 // so newmax = (newdist + sqrtf(newdist^2 + 4dmin.dmax)) / 2 3560 // so newmax = (newdist + sqrtf(newdist^2 + 4dmin.dmax)) / 2
3562 3561
3563 newmax = (newdist + sqrtf(newdist*newdist + 4*dmin*dmax)) / 2; 3562 newmax = (newdist + sqrt(newdist*newdist + 4*dmin*dmax)) / 2;
3564 newmin = newmax - newdist; 3563 newmin = newmax - newdist;
3565 3564
3566 // cerr << "newmin = " << newmin << ", newmax = " << newmax << endl; 3565 // cerr << "newmin = " << newmin << ", newmax = " << newmax << endl;
3567 3566
3568 } else { 3567 } else {
3583 newmax = mmax; 3582 newmax = mmax;
3584 } 3583 }
3585 3584
3586 // SVDEBUG << "SpectrogramLayer::setVerticalZoomStep: " << step << ": " << newmin << " -> " << newmax << " (range " << newdist << ")" << endl; 3585 // SVDEBUG << "SpectrogramLayer::setVerticalZoomStep: " << step << ": " << newmin << " -> " << newmax << " (range " << newdist << ")" << endl;
3587 3586
3588 setMinFrequency(lrintf(newmin)); 3587 setMinFrequency(int(lrint(newmin)));
3589 setMaxFrequency(lrintf(newmax)); 3588 setMaxFrequency(int(lrint(newmax)));
3590 } 3589 }
3591 3590
3592 RangeMapper * 3591 RangeMapper *
3593 SpectrogramLayer::getNewVerticalZoomRangeMapper() const 3592 SpectrogramLayer::getNewVerticalZoomRangeMapper() const
3594 { 3593 {
3598 3597
3599 void 3598 void
3600 SpectrogramLayer::updateMeasureRectYCoords(View *v, const MeasureRect &r) const 3599 SpectrogramLayer::updateMeasureRectYCoords(View *v, const MeasureRect &r) const
3601 { 3600 {
3602 int y0 = 0; 3601 int y0 = 0;
3603 if (r.startY > 0.0) y0 = getYForFrequency(v, r.startY); 3602 if (r.startY > 0.0) y0 = int(getYForFrequency(v, r.startY));
3604 3603
3605 int y1 = y0; 3604 int y1 = y0;
3606 if (r.endY > 0.0) y1 = getYForFrequency(v, r.endY); 3605 if (r.endY > 0.0) y1 = int(getYForFrequency(v, r.endY));
3607 3606
3608 // SVDEBUG << "SpectrogramLayer::updateMeasureRectYCoords: start " << r.startY << " -> " << y0 << ", end " << r.endY << " -> " << y1 << endl; 3607 // SVDEBUG << "SpectrogramLayer::updateMeasureRectYCoords: start " << r.startY << " -> " << y0 << ", end " << r.endY << " -> " << y1 << endl;
3609 3608
3610 r.pixrect = QRect(r.pixrect.x(), y0, r.pixrect.width(), y1 - y0); 3609 r.pixrect = QRect(r.pixrect.x(), y0, r.pixrect.width(), y1 - y0);
3611 } 3610 }