From d062a087c5d84bc4a0caecb2b028fbe046f7af7a Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Tue, 31 Jul 2018 14:49:05 -1000 Subject: [PATCH] SampleEditor rendering fixes --- Editor/SampleEditor.cpp | 90 ++++++++++++++++----- Editor/SampleEditor.hpp | 2 +- Editor/resources/IconKill.svg | 34 ++++---- Editor/resources/lang_de.ts | 12 +-- include/amuse/AudioGroupSampleDirectory.hpp | 8 ++ 5 files changed, 103 insertions(+), 43 deletions(-) diff --git a/Editor/SampleEditor.cpp b/Editor/SampleEditor.cpp index 0e7e8a5..226358f 100644 --- a/Editor/SampleEditor.cpp +++ b/Editor/SampleEditor.cpp @@ -30,16 +30,30 @@ void SampleView::seekToSample(qreal sample) uint32_t endRem = uint32_t(sample) % 14; if (startRem) + { + uint32_t end = 14; + if (startBlock == endBlock) + { + end = endRem; + endRem = 0; + } DSPDecompressFrameRangedStateOnly(m_sampleData + 8 * startBlock, m_sample->m_ADPCMParms.dsp.m_coefs, - &m_prev1, &m_prev2, startRem, startBlock == endBlock ? endRem : 14); + &m_prev1, &m_prev2, startRem, end); + if (end == 14) + ++startBlock; + } for (uint32_t b = startBlock; b < endBlock; ++b) + { DSPDecompressFrameStateOnly(m_sampleData + 8 * b, m_sample->m_ADPCMParms.dsp.m_coefs, &m_prev1, &m_prev2, 14); + } if (endRem) + { DSPDecompressFrameStateOnly(m_sampleData + 8 * endBlock, m_sample->m_ADPCMParms.dsp.m_coefs, &m_prev1, &m_prev2, endRem); + } } m_curSamplePos = sample; @@ -72,11 +86,18 @@ std::pair, std::pair> SampleView::iterateS if (startRem) { - uint32_t end = startBlock == endBlock ? endRem : 14; + uint32_t end = 14; + if (startBlock == endBlock) + { + end = endRem; + endRem = 0; + } DSPDecompressFrameRanged(sampleBlock, m_sampleData + 8 * startBlock, m_sample->m_ADPCMParms.dsp.m_coefs, &m_prev1, &m_prev2, startRem, end); for (int s = 0; s < end - startRem; ++s) accumulate(sampleBlock[s]); + if (end == 14) + ++startBlock; } for (uint32_t b = startBlock; b < endBlock; ++b) @@ -129,11 +150,19 @@ void SampleView::paintEvent(QPaintEvent* ev) constexpr int rulerHeight = 28; int sampleHeight = height() - rulerHeight; + qreal deviceRatio = devicePixelRatioF(); qreal rectStart = ev->rect().x(); + qreal deviceWidth = ev->rect().width() * deviceRatio; + qreal increment = 1.0 / deviceRatio; + qreal deviceSamplesPerPx = m_samplesPerPx / deviceRatio; qreal startSample = rectStart * m_samplesPerPx; - qreal deviceWidth = ev->rect().width() * devicePixelRatioF(); - qreal increment = 1.0 / devicePixelRatioF(); - qreal deviceSamplesPerPx = m_samplesPerPx / devicePixelRatioF(); + qreal startSampleRem = std::fmod(startSample, deviceSamplesPerPx); + if (startSampleRem > DBL_EPSILON) + { + startSample -= startSampleRem; + deviceWidth += startSampleRem; + rectStart = startSample / m_samplesPerPx; + } if (m_sample) { @@ -145,11 +174,15 @@ void SampleView::paintEvent(QPaintEvent* ev) seekToSample(startSample); + std::pair, std::pair> avgPeak; for (qreal i = 0.0; i < deviceWidth; i += increment) { if (m_curSamplePos + deviceSamplesPerPx > m_sample->getNumSamples()) break; - auto avgPeak = iterateSampleInterval(deviceSamplesPerPx); + if (i == 0.0 || std::floor(m_curSamplePos) != std::floor(m_curSamplePos + deviceSamplesPerPx)) + avgPeak = iterateSampleInterval(deviceSamplesPerPx); + else + m_curSamplePos += deviceSamplesPerPx; painter.setPen(peakPen); painter.drawLine(QPointF(rectStart + i, avgPeak.first.second * scale + trans), QPointF(rectStart + i, avgPeak.second.second * scale + trans)); @@ -172,13 +205,14 @@ void SampleView::paintEvent(QPaintEvent* ev) qreal numSpacing = binaryDiv / m_samplesPerPx; qreal tickSpacing = numSpacing / 5; - int lastNumDiv = int(ev->rect().x() / numSpacing); - int lastTickDiv = int(ev->rect().x() / tickSpacing); + int startX = std::max(0, int(ev->rect().x() - numSpacing)); + int lastNumDiv = int(startX / numSpacing); + int lastTickDiv = int(startX / tickSpacing); - qreal samplePos = startSample; + qreal samplePos = startX * m_samplesPerPx; painter.setFont(m_rulerFont); painter.setPen(QPen(QColor(127, 127, 127), increment)); - for (int i = ev->rect().x(); i < ev->rect().x() + ev->rect().width(); ++i) + for (int i = startX; i < ev->rect().x() + ev->rect().width() + numSpacing; ++i) { int thisNumDiv = int(i / numSpacing); int thisTickDiv = int(i / tickSpacing); @@ -327,11 +361,6 @@ void SampleView::wheelEvent(QWheelEvent* ev) } } -void SampleView::moveEvent(QMoveEvent* ev) -{ - update(); -} - void SampleView::loadData(ProjectModel::SampleNode* node) { m_node = node; @@ -376,11 +405,28 @@ void SampleView::setSamplePos(int pos) { if (pos != m_displaySamplePos) { - m_displaySamplePos = pos; - update(); + if (pos >= 0) + { + int lastPos = m_displaySamplePos; + m_displaySamplePos = pos; + updateSampleRange(lastPos, pos); + } + else + { + m_displaySamplePos = pos; + update(); + } } } +void SampleView::updateSampleRange(int oldSamp, int newSamp) +{ + qreal lastPos = oldSamp / m_samplesPerPx; + qreal newPos = newSamp / m_samplesPerPx; + update(int(std::min(lastPos, newPos)) - 10, 0, + int(std::fabs(newPos - lastPos)) + 20, height()); +} + SampleView::SampleView(QWidget* parent) : QWidget(parent) { @@ -431,9 +477,12 @@ void SampleControls::startValueChanged(int val) { SampleEditor* editor = qobject_cast(parentWidget()); amuse::SampleEntryData* data = editor->m_sampleView->entryData(); + + int oldPos = data->getLoopStartSample(); data->setLoopStartSample(atUint32(val)); m_loopEnd->setMinimum(val); - editor->m_sampleView->update(); + + editor->m_sampleView->updateSampleRange(oldPos, val); } } @@ -443,9 +492,12 @@ void SampleControls::endValueChanged(int val) { SampleEditor* editor = qobject_cast(parentWidget()); amuse::SampleEntryData* data = editor->m_sampleView->entryData(); + + int oldPos = data->getLoopEndSample(); data->setLoopEndSample(atUint32(val)); m_loopStart->setMaximum(val); - editor->m_sampleView->update(); + + editor->m_sampleView->updateSampleRange(oldPos, val); } } diff --git a/Editor/SampleEditor.hpp b/Editor/SampleEditor.hpp index 74535d7..e394b19 100644 --- a/Editor/SampleEditor.hpp +++ b/Editor/SampleEditor.hpp @@ -44,6 +44,7 @@ public: amuse::SampleEntryData* entryData() const; const amuse::SoundMacro* soundMacro() const; void setSamplePos(int pos); + void updateSampleRange(int oldSamp, int newSamp); void paintEvent(QPaintEvent* ev); void resetZoom(); @@ -53,7 +54,6 @@ public: void mouseReleaseEvent(QMouseEvent* ev); void mouseMoveEvent(QMouseEvent* ev); void wheelEvent(QWheelEvent* ev); - void moveEvent(QMoveEvent* ev); }; class SampleControls : public QFrame diff --git a/Editor/resources/IconKill.svg b/Editor/resources/IconKill.svg index d61d82e..d79d097 100644 --- a/Editor/resources/IconKill.svg +++ b/Editor/resources/IconKill.svg @@ -32,11 +32,11 @@ inkscape:current-layer="layer1" showgrid="true" units="px" - inkscape:window-width="1452" - inkscape:window-height="1061" - inkscape:window-x="651" - inkscape:window-y="170" - inkscape:window-maximized="0" + inkscape:window-width="3840" + inkscape:window-height="2079" + inkscape:window-x="0" + inkscape:window-y="40" + inkscape:window-maximized="1" gridtolerance="10" showguides="false"> + d="m 2.4096386,294.08957 a 0.71268904,0.65353703 0 0 1 -0.6385591,0.64999 0.71268904,0.65353703 0 0 1 -0.7713978,-0.51477 0.71268904,0.65353703 0 0 1 0.4780863,-0.75708 0.71268904,0.65353703 0 0 1 0.8708534,0.35728 l -0.6516718,0.26458 z" /> + style="fill:#000006;fill-opacity:1;stroke:none;stroke-width:0.79053128;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.49803922" /> SampleControls - + + Make WAV Version + + + + Make Compressed Version @@ -521,11 +526,6 @@ Base Pitch - - - Make WAV Version - - SoundMacroCatalogue diff --git a/include/amuse/AudioGroupSampleDirectory.hpp b/include/amuse/AudioGroupSampleDirectory.hpp index 9fce50c..e02cfc6 100644 --- a/include/amuse/AudioGroupSampleDirectory.hpp +++ b/include/amuse/AudioGroupSampleDirectory.hpp @@ -230,10 +230,18 @@ public: m_loopLengthSamples += m_loopStartSample - sample; m_loopStartSample = sample; } + atUint32 getLoopStartSample() const + { + return m_loopStartSample; + } void setLoopEndSample(atUint32 sample) { m_loopLengthSamples = sample + 1 - m_loopStartSample; } + atUint32 getLoopEndSample() const + { + return m_loopStartSample + m_loopLengthSamples - 1; + } EntryData() = default;