comparison layer/WaveformLayer.cpp @ 274:b9380f679f70

* Fix centre line position * Fix failure to update overview when generating peaks from wav file * Provide y-coordinate scale values and differences for spectrum measurement mode, and fix values for waveform (inc dB for both) * Add Printer colour scheme (may be futile)
author Chris Cannam
date Mon, 02 Jul 2007 13:04:17 +0000
parents 4ed1446ad604
children 9dd432665059
comparison
equal deleted inserted replaced
273:e954c00cbe55 274:b9380f679f70
635 break; 635 break;
636 } 636 }
637 637
638 if (val < -1.0 || val > 1.0) continue; 638 if (val < -1.0 || val > 1.0) continue;
639 639
640 int y = getYForValue(v, m_scale, val, ch, minChannel, maxChannel); 640 int y = getYForValue(v, val, ch);
641 641
642 if (py >= 0 && abs(y - py) < 10) continue; 642 if (py >= 0 && abs(y - py) < 10) continue;
643 else py = y; 643 else py = y;
644 644
645 int ny = y; 645 int ny = y;
646 if (nval != 0.0) { 646 if (nval != 0.0) {
647 ny = getYForValue(v, m_scale, nval, ch, minChannel, maxChannel); 647 ny = getYForValue(v, nval, ch);
648 } 648 }
649 649
650 paint->drawLine(x0, y, x1, y); 650 paint->drawLine(x0, y, x1, y);
651 if (ny != y) { 651 if (ny != y) {
652 paint->drawLine(x0, ny, x1, ny); 652 paint->drawLine(x0, ny, x1, ny);
993 993
994 return text; 994 return text;
995 } 995 }
996 996
997 int 997 int
998 WaveformLayer::getYForValue(const View *v, Scale scale, float value, size_t channel, 998 WaveformLayer::getYForValue(const View *v, float value, size_t channel) const
999 size_t minChannel, size_t maxChannel) const 999 {
1000 { 1000 size_t channels = 0, minChannel = 0, maxChannel = 0;
1001 bool mergingChannels = false, mixingChannels = false;
1002
1003 channels = getChannelArrangement(minChannel, maxChannel,
1004 mergingChannels, mixingChannels);
1005
1001 if (maxChannel < minChannel || channel < minChannel) return 0; 1006 if (maxChannel < minChannel || channel < minChannel) return 0;
1002 1007
1003 int h = v->height(); 1008 int h = v->height();
1004
1005 int channels = maxChannel - minChannel + 1;
1006 int m = (h / channels) / 2; 1009 int m = (h / channels) / 2;
1007 int my = m + (((channel - minChannel) * h) / channels);
1008 1010
1009 if ((m_scale == dBScale || m_scale == MeterScale) && 1011 if ((m_scale == dBScale || m_scale == MeterScale) &&
1010 m_channelMode != MergeChannels) { 1012 m_channelMode != MergeChannels) {
1011 m = (h / channels); 1013 m = (h / channels);
1012 my = m + (((channel - minChannel) * h) / channels); 1014 }
1013 } 1015
1016 int my = m + (((channel - minChannel) * h) / channels);
1014 1017
1015 int vy = 0; 1018 int vy = 0;
1016 1019
1017 switch (scale) { 1020 switch (m_scale) {
1018 1021
1019 case LinearScale: 1022 case LinearScale:
1020 vy = int(m * value); 1023 vy = int(m * value);
1021 break; 1024 break;
1022 1025
1031 1034
1032 return my - vy; 1035 return my - vy;
1033 } 1036 }
1034 1037
1035 float 1038 float
1036 WaveformLayer::getValueForY(const View *v, Scale scale, int y, 1039 WaveformLayer::getValueForY(const View *v, int y, size_t &channel) const
1037 size_t minChannel, size_t maxChannel) const 1040 {
1038 { 1041 size_t channels = 0, minChannel = 0, maxChannel = 0;
1042 bool mergingChannels = false, mixingChannels = false;
1043
1044 channels = getChannelArrangement(minChannel, maxChannel,
1045 mergingChannels, mixingChannels);
1046
1039 if (maxChannel < minChannel) return 0; 1047 if (maxChannel < minChannel) return 0;
1040 1048
1041 int h = v->height(); 1049 int h = v->height();
1042
1043 int channels = maxChannel - minChannel + 1;
1044 int m = (h / channels) / 2; 1050 int m = (h / channels) / 2;
1045 1051
1046 if ((m_scale == dBScale || m_scale == MeterScale) && 1052 if ((m_scale == dBScale || m_scale == MeterScale) &&
1047 m_channelMode != MergeChannels) { 1053 m_channelMode != MergeChannels) {
1048 m = (h / channels); 1054 m = (h / channels);
1049 } 1055 }
1050 1056
1051 int channel = minChannel; 1057 channel = (y * channels) / h + minChannel;
1052 int mind = 0; 1058
1053
1054 for (int c = minChannel; c <= maxChannel; ++c) {
1055 int my = m + (((c - minChannel) * h) / channels);
1056 int d = y - my;
1057 if (d < 0) d = -d;
1058 if (c == minChannel || d < mind) {
1059 mind = d;
1060 channel = c;
1061 }
1062 }
1063
1064 int my = m + (((channel - minChannel) * h) / channels); 1059 int my = m + (((channel - minChannel) * h) / channels);
1065 1060
1066 int vy = my - y; 1061 int vy = my - y;
1067 float value = 0; 1062 float value = 0;
1068 1063 float thresh = -50.f;
1069 switch (scale) { 1064
1065 switch (m_scale) {
1070 1066
1071 case LinearScale: 1067 case LinearScale:
1072 value = float(vy) / m; 1068 value = float(vy) / m;
1073 break; 1069 break;
1074 1070
1075 case MeterScale: 1071 case MeterScale:
1076 value = AudioLevel::preview_to_multiplier(vy, m); 1072 value = AudioLevel::preview_to_multiplier(vy, m);
1077 break; 1073 break;
1078 1074
1079 case dBScale: 1075 case dBScale:
1080 value = AudioLevel::dB_to_multiplier((50 * float(vy)) / m - 50); 1076 value = (-thresh * float(vy)) / m + thresh;
1077 value = AudioLevel::dB_to_multiplier(value);
1081 break; 1078 break;
1082 } 1079 }
1083 1080
1084 return value; 1081 return value / m_gain;
1085 } 1082 }
1086 1083
1087 bool 1084 bool
1088 WaveformLayer::getYScaleValue(const View *v, int y, 1085 WaveformLayer::getYScaleValue(const View *v, int y,
1089 float &value, QString &unit) const 1086 float &value, QString &unit) const
1090 { 1087 {
1091 size_t channels = 0, minChannel = 0, maxChannel = 0; 1088 size_t channel;
1092 bool mergingChannels = false, mixingChannels = false; 1089
1093 1090 value = getValueForY(v, y, channel);
1094 channels = getChannelArrangement(minChannel, maxChannel, 1091
1095 mergingChannels, mixingChannels); 1092 if (m_scale == dBScale || m_scale == MeterScale) {
1096 1093
1097 if (channels == 0) return false; 1094 float thresh = -50.f;
1098 1095
1099 value = getValueForY(v, m_scale, y, minChannel, maxChannel); 1096 if (value > 0.f) {
1100 unit = "V"; 1097 value = 10.f * log10f(value);
1098 if (value < thresh) value = thresh;
1099 } else value = thresh;
1100
1101 unit = "dBV";
1102
1103 } else {
1104 unit = "V";
1105 }
1106
1107 return true;
1108 }
1109
1110 bool
1111 WaveformLayer::getYScaleDifference(const View *v, int y0, int y1,
1112 float &diff, QString &unit) const
1113 {
1114 size_t c0, c1;
1115 float v0 = getValueForY(v, y0, c0);
1116 float v1 = getValueForY(v, y1, c1);
1117
1118 if (c0 != c1) {
1119 // different channels, not comparable
1120 diff = 0.f;
1121 unit = "";
1122 return false;
1123 }
1124
1125 if (m_scale == dBScale || m_scale == MeterScale) {
1126
1127 float thresh = -50.f;
1128
1129 if (v1 == v0) diff = thresh;
1130 else {
1131 if (v1 > v0) diff = v0 / v1;
1132 else diff = v1 / v0;
1133
1134 diff = 10.f * log10f(diff);
1135 if (diff < thresh) diff = thresh;
1136 }
1137
1138 unit = "dBV";
1139
1140 } else {
1141 diff = fabsf(v1 - v0);
1142 unit = "V";
1143 }
1144
1101 return true; 1145 return true;
1102 } 1146 }
1103 1147
1104 int 1148 int
1105 WaveformLayer::getVerticalScaleWidth(View *, QPainter &paint) const 1149 WaveformLayer::getVerticalScaleWidth(View *, QPainter &paint) const
1178 break; 1222 break;
1179 } 1223 }
1180 1224
1181 if (val < -1.0 || val > 1.0) continue; 1225 if (val < -1.0 || val > 1.0) continue;
1182 1226
1183 int y = getYForValue(v, m_scale, val, ch, minChannel, maxChannel); 1227 int y = getYForValue(v, val, ch);
1184 1228
1185 int ny = y; 1229 int ny = y;
1186 if (nval != 0.0) { 1230 if (nval != 0.0) {
1187 ny = getYForValue(v, m_scale, nval, ch, minChannel, maxChannel); 1231 ny = getYForValue(v, nval, ch);
1188 } 1232 }
1189 1233
1190 bool spaceForLabel = (i == 0 || 1234 bool spaceForLabel = (i == 0 ||
1191 abs(y - lastLabelledY) >= textHeight - 1); 1235 abs(y - lastLabelledY) >= textHeight - 1);
1192 1236