Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 31:fc802f7b112e
* Change SpectrogramLayer to use its own cache type instead of a QImage
* Some gcc-4.0 compile fixes
author | Chris Cannam |
---|---|
date | Tue, 14 Feb 2006 17:43:14 +0000 |
parents | 9f55af9676b4 |
children | 651e4e868bcc |
comparison
equal
deleted
inserted
replaced
30:ea6fe8cfcdd5 | 31:fc802f7b112e |
---|---|
80 void | 80 void |
81 SpectrogramLayer::setModel(const DenseTimeValueModel *model) | 81 SpectrogramLayer::setModel(const DenseTimeValueModel *model) |
82 { | 82 { |
83 m_mutex.lock(); | 83 m_mutex.lock(); |
84 m_model = model; | 84 m_model = model; |
85 delete m_cache; | |
86 m_cache = 0; | |
85 m_mutex.unlock(); | 87 m_mutex.unlock(); |
86 | 88 |
87 if (!m_model || !m_model->isOK()) return; | 89 if (!m_model || !m_model->isOK()) return; |
88 | 90 |
89 connect(m_model, SIGNAL(modelChanged()), this, SIGNAL(modelChanged())); | 91 connect(m_model, SIGNAL(modelChanged()), this, SIGNAL(modelChanged())); |
695 { | 697 { |
696 if (m_cacheInvalid || !m_cache) return; | 698 if (m_cacheInvalid || !m_cache) return; |
697 | 699 |
698 int formerRotation = m_colourRotation; | 700 int formerRotation = m_colourRotation; |
699 | 701 |
700 m_cache->setNumColors(256); | 702 // m_cache->setNumColors(256); |
701 | 703 |
702 m_cache->setColor(0, qRgb(255, 255, 255)); | 704 // m_cache->setColour(0, qRgb(255, 255, 255)); |
705 m_cache->setColour(0, Qt::white); | |
703 | 706 |
704 for (int pixel = 1; pixel < 256; ++pixel) { | 707 for (int pixel = 1; pixel < 256; ++pixel) { |
705 | 708 |
706 QColor colour; | 709 QColor colour; |
707 int hue, px; | 710 int hue, px; |
740 case RedOnBlack: | 743 case RedOnBlack: |
741 colour = QColor::fromHsv(10, pixel, pixel); | 744 colour = QColor::fromHsv(10, pixel, pixel); |
742 break; | 745 break; |
743 } | 746 } |
744 | 747 |
745 m_cache->setColor | 748 // m_cache->setColor |
746 (pixel, qRgb(colour.red(), colour.green(), colour.blue())); | 749 // (pixel, qRgb(colour.red(), colour.green(), colour.blue())); |
750 m_cache->setColour(pixel, colour); | |
747 } | 751 } |
748 | 752 |
749 m_colourRotation = 0; | 753 m_colourRotation = 0; |
750 rotateCacheColourmap(m_colourRotation - formerRotation); | 754 rotateCacheColourmap(m_colourRotation - formerRotation); |
751 m_colourRotation = formerRotation; | 755 m_colourRotation = formerRotation; |
754 void | 758 void |
755 SpectrogramLayer::rotateCacheColourmap(int distance) | 759 SpectrogramLayer::rotateCacheColourmap(int distance) |
756 { | 760 { |
757 if (!m_cache) return; | 761 if (!m_cache) return; |
758 | 762 |
759 QRgb newPixels[256]; | 763 QColor newPixels[256]; |
760 | 764 |
761 newPixels[0] = m_cache->color(0); | 765 newPixels[0] = m_cache->getColour(0); |
762 | 766 |
763 for (int pixel = 1; pixel < 256; ++pixel) { | 767 for (int pixel = 1; pixel < 256; ++pixel) { |
764 int target = pixel + distance; | 768 int target = pixel + distance; |
765 while (target < 1) target += 255; | 769 while (target < 1) target += 255; |
766 while (target > 255) target -= 255; | 770 while (target > 255) target -= 255; |
767 newPixels[target] = m_cache->color(pixel); | 771 newPixels[target] = m_cache->getColour(pixel); |
768 } | 772 } |
769 | 773 |
770 for (int pixel = 0; pixel < 256; ++pixel) { | 774 for (int pixel = 0; pixel < 256; ++pixel) { |
771 m_cache->setColor(pixel, newPixels[pixel]); | 775 m_cache->setColour(pixel, newPixels[pixel]); |
772 } | 776 } |
773 } | 777 } |
774 | 778 |
775 bool | 779 bool |
776 SpectrogramLayer::fillCacheColumn(int column, double *input, | 780 SpectrogramLayer::fillCacheColumn(int column, double *input, |
856 if (m_cacheInvalid || m_exiting) { | 860 if (m_cacheInvalid || m_exiting) { |
857 interrupted = true; | 861 interrupted = true; |
858 break; | 862 break; |
859 } | 863 } |
860 | 864 |
861 if (column < m_cache->width() && (int)i < m_cache->height()) { | 865 m_cache->setValueAt(column, i, value + 1); |
862 m_cache->setPixel(column, i, value + 1); // 0 is "unset" | |
863 } | |
864 } | 866 } |
865 | 867 |
866 if (lock) m_mutex.unlock(); | 868 if (lock) m_mutex.unlock(); |
867 return !interrupted; | 869 return !interrupted; |
870 } | |
871 | |
872 SpectrogramLayer::Cache::Cache(size_t width, size_t height) : | |
873 m_width(width), | |
874 m_height(height) | |
875 { | |
876 m_values = new unsigned char[m_width * m_height]; | |
877 MUNLOCK(m_values, m_width * m_height * sizeof(unsigned char)); | |
878 } | |
879 | |
880 SpectrogramLayer::Cache::~Cache() | |
881 { | |
882 delete[] m_values; | |
883 } | |
884 | |
885 size_t | |
886 SpectrogramLayer::Cache::getWidth() const | |
887 { | |
888 return m_width; | |
889 } | |
890 | |
891 size_t | |
892 SpectrogramLayer::Cache::getHeight() const | |
893 { | |
894 return m_height; | |
895 } | |
896 | |
897 unsigned char | |
898 SpectrogramLayer::Cache::getValueAt(size_t x, size_t y) const | |
899 { | |
900 if (x >= m_width || y >= m_height) return 0; | |
901 return m_values[y * m_width + x]; | |
902 } | |
903 | |
904 void | |
905 SpectrogramLayer::Cache::setValueAt(size_t x, size_t y, unsigned char value) | |
906 { | |
907 if (x >= m_width || y >= m_height) return; | |
908 m_values[y * m_width + x] = value; | |
909 } | |
910 | |
911 QColor | |
912 SpectrogramLayer::Cache::getColour(unsigned char index) const | |
913 { | |
914 return m_colours[index]; | |
915 } | |
916 | |
917 void | |
918 SpectrogramLayer::Cache::setColour(unsigned char index, QColor colour) | |
919 { | |
920 m_colours[index] = colour; | |
921 } | |
922 | |
923 void | |
924 SpectrogramLayer::Cache::fill(unsigned char value) | |
925 { | |
926 for (size_t i = 0; i < m_width * m_height; ++i) { | |
927 m_values[i] = value; | |
928 } | |
868 } | 929 } |
869 | 930 |
870 void | 931 void |
871 SpectrogramLayer::CacheFillThread::run() | 932 SpectrogramLayer::CacheFillThread::run() |
872 { | 933 { |
917 } | 978 } |
918 | 979 |
919 delete m_layer.m_cache; | 980 delete m_layer.m_cache; |
920 size_t width = (end - start) / windowIncrement + 1; | 981 size_t width = (end - start) / windowIncrement + 1; |
921 size_t height = windowSize / 2; | 982 size_t height = windowSize / 2; |
922 m_layer.m_cache = new QImage(width, height, | 983 m_layer.m_cache = new Cache(width, height); |
923 QImage::Format_Indexed8); | 984 |
924 | |
925 // If we're using JACK in mlock mode, this will be locked | |
926 // and we ought to unlock to avoid memory exhaustion. | |
927 // Shame it doesn't appear to be possible to allocate | |
928 // unlocked in the first place. | |
929 //!!! hm, I don't think this is working. | |
930 MUNLOCK((void *)m_layer.m_cache, width * height); | |
931 | |
932 m_layer.setCacheColourmap(); | 985 m_layer.setCacheColourmap(); |
933 | 986 |
934 m_layer.m_cache->fill(0); | 987 m_layer.m_cache->fill(0); |
935 m_layer.m_mutex.unlock(); | 988 m_layer.m_mutex.unlock(); |
936 | 989 |
1192 int s1i = int(s1); | 1245 int s1i = int(s1); |
1193 | 1246 |
1194 if (m_mutex.tryLock()) { | 1247 if (m_mutex.tryLock()) { |
1195 if (m_cache && !m_cacheInvalid) { | 1248 if (m_cache && !m_cacheInvalid) { |
1196 | 1249 |
1197 int cw = m_cache->width(); | 1250 int cw = m_cache->getWidth(); |
1198 int ch = m_cache->height(); | 1251 int ch = m_cache->getHeight(); |
1199 | 1252 |
1200 int min = -1, max = -1; | 1253 int min = -1, max = -1; |
1201 | 1254 |
1202 for (int q = q0i; q <= q1i; ++q) { | 1255 for (int q = q0i; q <= q1i; ++q) { |
1203 for (int s = s0i; s <= s1i; ++s) { | 1256 for (int s = s0i; s <= s1i; ++s) { |
1204 if (s >= 0 && q >= 0 && s < cw && q < ch) { | 1257 if (s >= 0 && q >= 0 && s < cw && q < ch) { |
1205 int value = m_cache->scanLine(q)[s]; | 1258 int value = int(m_cache->getValueAt(s, q)); |
1206 if (min == -1 || value < min) min = value; | 1259 if (min == -1 || value < min) min = value; |
1207 if (max == -1 || value > max) max = value; | 1260 if (max == -1 || value > max) max = value; |
1208 } | 1261 } |
1209 } | 1262 } |
1210 } | 1263 } |
1393 if (m_cacheInvalid) { | 1446 if (m_cacheInvalid) { |
1394 m_mutex.unlock(); | 1447 m_mutex.unlock(); |
1395 break; | 1448 break; |
1396 } | 1449 } |
1397 | 1450 |
1398 int cw = m_cache->width(); | 1451 int cw = m_cache->getWidth(); |
1399 int ch = m_cache->height(); | 1452 int ch = m_cache->getHeight(); |
1400 | 1453 |
1401 float q0 = 0, q1 = 0; | 1454 float q0 = 0, q1 = 0; |
1402 | 1455 |
1403 if (!getYBinRange(y0 + y, q0, q1)) { | 1456 if (!getYBinRange(y0 + y, q0, q1)) { |
1404 for (int x = 0; x < w; ++x) { | 1457 for (int x = 0; x < w; ++x) { |
1438 float qprop = sprop; | 1491 float qprop = sprop; |
1439 if (q == q0i) qprop *= (q + 1) - q0; | 1492 if (q == q0i) qprop *= (q + 1) - q0; |
1440 if (q == q1i) qprop *= q1 - q; | 1493 if (q == q1i) qprop *= q1 - q; |
1441 | 1494 |
1442 if (s >= 0 && q >= 0 && s < cw && q < ch) { | 1495 if (s >= 0 && q >= 0 && s < cw && q < ch) { |
1443 total += qprop * m_cache->scanLine(q)[s]; | 1496 total += qprop * m_cache->getValueAt(s, q); |
1444 divisor += qprop; | 1497 divisor += qprop; |
1445 } | 1498 } |
1446 } | 1499 } |
1447 } | 1500 } |
1448 | 1501 |
1449 if (divisor > 0.0) { | 1502 if (divisor > 0.0) { |
1450 /* | |
1451 int pixel = int(total / divisor); | 1503 int pixel = int(total / divisor); |
1452 if (pixel > 255) pixel = 255; | 1504 if (pixel > 255) pixel = 255; |
1453 if (pixel < 1) pixel = 1; | 1505 if (pixel < 1) pixel = 1; |
1454 assert(x <= scaled.width()); | 1506 assert(x <= scaled.width()); |
1455 scaled.setPixel(x, y, m_cache->color(pixel)); | 1507 QColor c = m_cache->getColour(pixel); |
1456 */ | 1508 scaled.setPixel(x, y, |
1509 qRgb(c.red(), c.green(), c.blue())); | |
1510 /* | |
1457 float pixel = total / divisor; | 1511 float pixel = total / divisor; |
1458 float lq = pixel - int(pixel); | 1512 float lq = pixel - int(pixel); |
1459 float hq = int(pixel) + 1 - pixel; | 1513 float hq = int(pixel) + 1 - pixel; |
1460 int pixNum = int(pixel); | 1514 int pixNum = int(pixel); |
1461 QRgb low = m_cache->color(pixNum > 255 ? 255 : pixNum); | 1515 QRgb low = m_cache->color(pixNum > 255 ? 255 : pixNum); |
1463 QRgb mixed = qRgb | 1517 QRgb mixed = qRgb |
1464 (qRed(low) * lq + qRed(high) * hq + 0.01, | 1518 (qRed(low) * lq + qRed(high) * hq + 0.01, |
1465 qGreen(low) * lq + qGreen(high) * hq + 0.01, | 1519 qGreen(low) * lq + qGreen(high) * hq + 0.01, |
1466 qBlue(low) * lq + qBlue(high) * hq + 0.01); | 1520 qBlue(low) * lq + qBlue(high) * hq + 0.01); |
1467 scaled.setPixel(x, y, mixed); | 1521 scaled.setPixel(x, y, mixed); |
1468 | 1522 */ |
1469 } else { | 1523 } else { |
1470 assert(x <= scaled.width()); | 1524 assert(x <= scaled.width()); |
1471 scaled.setPixel(x, y, qRgb(0, 0, 0)); | 1525 scaled.setPixel(x, y, qRgb(0, 0, 0)); |
1472 } | 1526 } |
1473 } | 1527 } |