-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
make scaling of GLSL RGB and RGB L/R waveform amplitudes consistent with simple waveform #12205
Changes from 2 commits
d26931f
f036b0a
52a0956
20bbf26
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,7 +74,7 @@ void WaveformRendererLRRGB::paintGL() { | |
const float breadth = static_cast<float>(m_waveformRenderer->getBreadth()) * devicePixelRatio; | ||
const float halfBreadth = breadth / 2.0f; | ||
|
||
const float heightFactorAbs = allGain * halfBreadth / std::sqrt(3.f * 256.f * 256.f); | ||
const float heightFactorAbs = allGain * halfBreadth / 255.f; | ||
const float heightFactor[2] = {-heightFactorAbs, heightFactorAbs}; | ||
|
||
const float low_r = static_cast<float>(m_rgbLowColor_r); | ||
|
@@ -92,13 +92,12 @@ void WaveformRendererLRRGB::paintGL() { | |
|
||
const int numVerticesPerLine = 6; // 2 triangles | ||
|
||
const int linesReserved = numVerticesPerLine * (length * 2 + 1); | ||
const int colorsReserved = numVerticesPerLine * (length * 2 + 1); | ||
const int reserved = numVerticesPerLine * (length * 2 + 1); | ||
|
||
m_vertices.clear(); | ||
m_vertices.reserve(linesReserved); | ||
m_vertices.reserve(reserved); | ||
m_colors.clear(); | ||
m_colors.reserve(colorsReserved); | ||
m_colors.reserve(reserved); | ||
|
||
m_vertices.addRectangle(0.f, | ||
halfBreadth - 0.5f * devicePixelRatio, | ||
|
@@ -140,48 +139,61 @@ void WaveformRendererLRRGB::paintGL() { | |
const float fpos = static_cast<float>(pos); | ||
|
||
for (int chn = 0; chn < 2; chn++) { | ||
float maxLow{}; | ||
float maxMid{}; | ||
float maxHigh{}; | ||
float maxAll{}; | ||
|
||
// Find the max values for low, mid, high and all in the waveform data | ||
uchar u8maxLow{}; | ||
uchar u8maxMid{}; | ||
uchar u8maxHigh{}; | ||
uchar u8maxAll{}; | ||
// data is interleaved left / right | ||
for (int i = visualIndexStart + chn; i < visualIndexStop + chn; i += 2) { | ||
const WaveformData& waveformData = data[i]; | ||
|
||
const float filteredLow = static_cast<float>(waveformData.filtered.low); | ||
const float filteredMid = static_cast<float>(waveformData.filtered.mid); | ||
const float filteredHigh = static_cast<float>(waveformData.filtered.high); | ||
u8maxLow = math_max(u8maxLow, waveformData.filtered.low); | ||
u8maxMid = math_max(u8maxMid, waveformData.filtered.mid); | ||
u8maxHigh = math_max(u8maxHigh, waveformData.filtered.high); | ||
u8maxAll = math_max(u8maxAll, waveformData.filtered.all); | ||
} | ||
|
||
maxLow = math_max(maxLow, filteredLow); | ||
maxMid = math_max(maxMid, filteredMid); | ||
maxHigh = math_max(maxHigh, filteredHigh); | ||
// Cast to float | ||
float maxLow = static_cast<float>(u8maxLow); | ||
float maxMid = static_cast<float>(u8maxMid); | ||
float maxHigh = static_cast<float>(u8maxHigh); | ||
float maxAll = static_cast<float>(u8maxAll); | ||
|
||
const float all = math_pow2(filteredLow) * lowGain + | ||
math_pow2(filteredMid) * midGain + | ||
math_pow2(filteredHigh) * highGain; | ||
maxAll = math_max(maxAll, all); | ||
} | ||
// Calculate the magnitude of the maxLow, maxMid and maxHigh values | ||
const float magnitude = std::sqrt( | ||
math_pow2(maxLow) + math_pow2(maxMid) + math_pow2(maxHigh)); | ||
|
||
// Apply the gains | ||
maxLow *= lowGain; | ||
maxMid *= midGain; | ||
maxHigh *= highGain; | ||
|
||
// Calculate the magnitude of the gained maxLow, maxMid and maxHigh values | ||
const float magnitudeGained = std::sqrt( | ||
math_pow2(maxLow) + math_pow2(maxMid) + math_pow2(maxHigh)); | ||
|
||
// The maxAll value will be used to draw the amplitude. We scale them according to | ||
// magnitude of the gained maxLow, maxMid and maxHigh values | ||
Comment on lines
+158
to
+159
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bit more background info is useful here. |
||
if (magnitude != 0.f) { | ||
const float factor = magnitudeGained / magnitude; | ||
maxAll *= factor; | ||
} | ||
|
||
// Use the gained maxLow, maxMid and maxHigh values to calculate the color components | ||
float red = maxLow * low_r + maxMid * mid_r + maxHigh * high_r; | ||
float green = maxLow * low_g + maxMid * mid_g + maxHigh * high_g; | ||
float blue = maxLow * low_b + maxMid * mid_b + maxHigh * high_b; | ||
|
||
const float max = math_max3(red, green, blue); | ||
|
||
// Normalize red, green, blue, using the maximum of the three | ||
|
||
if (max == 0.f) { | ||
// avoid division by 0 | ||
// Normalize the color components using the maximum of the three | ||
const float maxComponent = math_max3(red, green, blue); | ||
if (maxComponent == 0.f) { | ||
// Avoid division by 0 | ||
red = 0.f; | ||
green = 0.f; | ||
blue = 0.f; | ||
} else { | ||
const float normFactor = 1.f / max; | ||
const float normFactor = 1.f / maxComponent; | ||
red *= normFactor; | ||
green *= normFactor; | ||
blue *= normFactor; | ||
|
@@ -193,15 +205,15 @@ void WaveformRendererLRRGB::paintGL() { | |
m_vertices.addRectangle(fpos - 0.5f, | ||
halfBreadth, | ||
fpos + 0.5f, | ||
halfBreadth + heightFactor[chn] * std::sqrt(maxAll)); | ||
halfBreadth + heightFactor[chn] * maxAll); | ||
m_colors.addForRectangle(red, green, blue); | ||
} | ||
|
||
xVisualSampleIndex += visualIncrementPerPixel; | ||
} | ||
|
||
DEBUG_ASSERT(linesReserved == m_vertices.size()); | ||
DEBUG_ASSERT(colorsReserved == m_colors.size()); | ||
DEBUG_ASSERT(reserved == m_vertices.size()); | ||
DEBUG_ASSERT(reserved == m_colors.size()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so I guess m_colors and m_vertices are the same size? (do we need to check both these things? This seems like an odd place to enforce this restriction rather than when reserved is calculated) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, they are the same size. we could remove these asserts, it's just to make sure i didn't make a mistake when filling these vectors. but they don't enforce anything, they merly check. and checking doesn't hurt. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it. Wouldn't it be better to check them back up where reserved is created, then? If there's something wrong with that size, then we will encounter problems before we get to this check. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is being checked with this assert is that the amount of data that we push to the m_vertices / m_colors vectors is correct (in m_vertices.addRectangle and m_colors.addForRectangle), to make sure we reserve exactly the amount we are going to push. |
||
|
||
const QMatrix4x4 matrix = matrixForWidgetGeometry(m_waveformRenderer, true); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,7 +74,7 @@ void WaveformRendererRGB::paintGL() { | |
const float breadth = static_cast<float>(m_waveformRenderer->getBreadth()) * devicePixelRatio; | ||
const float halfBreadth = breadth / 2.0f; | ||
|
||
const float heightFactor = allGain * halfBreadth / std::sqrt(3.f * 256.f * 256.f); | ||
const float heightFactor = allGain * halfBreadth / 255.f; | ||
|
||
const float low_r = static_cast<float>(m_rgbLowColor_r); | ||
const float mid_r = static_cast<float>(m_rgbMidColor_r); | ||
|
@@ -137,63 +137,76 @@ void WaveformRendererRGB::paintGL() { | |
|
||
const float fpos = static_cast<float>(pos); | ||
|
||
// combined left+right | ||
float maxLow{}; | ||
float maxMid{}; | ||
float maxHigh{}; | ||
// per channel | ||
float maxAll[2]{}; | ||
|
||
// Find the max values for low, mid, high and all in the waveform data. | ||
// - Max of left and right | ||
uchar u8maxLow{}; | ||
uchar u8maxMid{}; | ||
uchar u8maxHigh{}; | ||
// - Per channel | ||
uchar u8maxAllChn[2]{}; | ||
for (int chn = 0; chn < 2; chn++) { | ||
// data is interleaved left / right | ||
for (int i = visualIndexStart + chn; i < visualIndexStop + chn; i += 2) { | ||
const WaveformData& waveformData = data[i]; | ||
|
||
const float filteredLow = static_cast<float>(waveformData.filtered.low); | ||
const float filteredMid = static_cast<float>(waveformData.filtered.mid); | ||
const float filteredHigh = static_cast<float>(waveformData.filtered.high); | ||
|
||
maxLow = math_max(maxLow, filteredLow); | ||
maxMid = math_max(maxMid, filteredMid); | ||
maxHigh = math_max(maxHigh, filteredHigh); | ||
|
||
const float all = math_pow2(filteredLow) * lowGain + | ||
math_pow2(filteredMid) * midGain + | ||
math_pow2(filteredHigh) * highGain; | ||
maxAll[chn] = math_max(maxAll[chn], all); | ||
u8maxLow = math_max(u8maxLow, waveformData.filtered.low); | ||
u8maxMid = math_max(u8maxMid, waveformData.filtered.mid); | ||
u8maxHigh = math_max(u8maxHigh, waveformData.filtered.high); | ||
u8maxAllChn[chn] = math_max(u8maxAllChn[chn], waveformData.filtered.all); | ||
} | ||
} | ||
|
||
// Cast to float | ||
float maxLow = static_cast<float>(u8maxLow); | ||
float maxMid = static_cast<float>(u8maxMid); | ||
float maxHigh = static_cast<float>(u8maxHigh); | ||
float maxAllChn[2]{static_cast<float>(u8maxAllChn[0]), static_cast<float>(u8maxAllChn[1])}; | ||
|
||
// Calculate the magnitude of the maxLow, maxMid and maxHigh values | ||
const float magnitude = std::sqrt( | ||
math_pow2(maxLow) + math_pow2(maxMid) + math_pow2(maxHigh)); | ||
|
||
// Apply the gains | ||
maxLow *= lowGain; | ||
maxMid *= midGain; | ||
maxHigh *= highGain; | ||
|
||
// Calculate the magnitude of the gained maxLow, maxMid and maxHigh values | ||
const float magnitudeGained = std::sqrt( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use only one std::sqrt() if you build the quotient (factor below) before. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I understand what you mean here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can make use of the rule: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah, well spotted! i'll make the change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
math_pow2(maxLow) + math_pow2(maxMid) + math_pow2(maxHigh)); | ||
|
||
// The maxAll values will be used to draw the amplitude. We scale them according to | ||
// magnitude of the gained maxLow, maxMid and maxHigh values | ||
if (magnitude != 0.f) { | ||
const float factor = magnitudeGained / magnitude; | ||
maxAllChn[0] *= factor; | ||
maxAllChn[1] *= factor; | ||
} | ||
|
||
// Use the gained maxLow, maxMid and maxHigh values to calculate the color components | ||
float red = maxLow * low_r + maxMid * mid_r + maxHigh * high_r; | ||
float green = maxLow * low_g + maxMid * mid_g + maxHigh * high_g; | ||
float blue = maxLow * low_b + maxMid * mid_b + maxHigh * high_b; | ||
|
||
const float max = math_max3(red, green, blue); | ||
|
||
// Normalize red, green, blue, using the maximum of the three | ||
|
||
if (max == 0.f) { | ||
// avoid division by 0 | ||
// Normalize the color components using the maximum of the three | ||
const float maxComponent = math_max3(red, green, blue); | ||
if (maxComponent == 0.f) { | ||
ywwg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Avoid division by 0 | ||
red = 0.f; | ||
green = 0.f; | ||
blue = 0.f; | ||
} else { | ||
const float normFactor = 1.f / max; | ||
const float normFactor = 1.f / maxComponent; | ||
red *= normFactor; | ||
green *= normFactor; | ||
blue *= normFactor; | ||
} | ||
|
||
// lines are thin rectangles | ||
// maxAll[0] is for left channel, maxAll[1] is for right channel | ||
// Lines are thin rectangles | ||
m_vertices.addRectangle(fpos - 0.5f, | ||
halfBreadth - heightFactor * std::sqrt(maxAll[0]), | ||
halfBreadth - heightFactor * maxAllChn[0], | ||
fpos + 0.5f, | ||
halfBreadth + heightFactor * std::sqrt(maxAll[1])); | ||
halfBreadth + heightFactor * maxAllChn[1]); | ||
m_colors.addForRectangle(red, green, blue); | ||
|
||
xVisualSampleIndex += visualIncrementPerPixel; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I understand why maxLow is a different type than u8maxLow. are we casting from uchar to float because of math max?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, this way we cast only once, rather than casting for every iteration in the for loop in line 148.