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 }