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