Mercurial > hg > svgui
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 } |