From d2dee5ce3d575f81b7540d39f8b029e6ae643718 Mon Sep 17 00:00:00 2001 From: David Guglielmi Date: Mon, 14 May 2018 21:25:38 +0200 Subject: [PATCH] media-sound/mixxx: update pre-2.1.1 patches #3 --- media-sound/mixxx/Manifest | 5 +- ...etect-m4a-decoding-errors-on-windows.patch | 124 +++++++++++ ...ler-warnings-about-non-trivial-types.patch | 164 ++++++++++++++ .../mixxx-2.1.0-optimize-flac-decoding.patch | 208 ++++++++++++++++++ media-sound/mixxx/mixxx-2.1.0.ebuild | 4 + 5 files changed, 504 insertions(+), 1 deletion(-) create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-detect-m4a-decoding-errors-on-windows.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-fix-cachingreader-compiler-warnings-about-non-trivial-types.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-optimize-flac-decoding.patch diff --git a/media-sound/mixxx/Manifest b/media-sound/mixxx/Manifest index 1b88876..5dcfe62 100644 --- a/media-sound/mixxx/Manifest +++ b/media-sound/mixxx/Manifest @@ -2,7 +2,9 @@ AUX mixxx-2.0.0-docs.patch 435 BLAKE2B c2e9b09abb293e59b2af49527eccf07c9488ae5e3 AUX mixxx-2.1.0-debug-assert-and-fix-false-poisitiv-restart-request.patch 5694 BLAKE2B 7732252cf6438df9d52e6de8ceaaf6b2e1c30e35d8154eb7af5d94641346117d4ab0b5501686909d35c81a5fd5aa9442831f11b66faaec782c11a55e14a11363 SHA512 ee35ea84db8bf91cd2f14dd779faa91857df7bcc376525d533e65c778e241a5e66c829ab208e2da5d4afb3a48571042c13e5092c4974a07a9ea11146df68d326 AUX mixxx-2.1.0-deere-add-gain-knob-to-expanded-sampler-view.patch 1116 BLAKE2B a32d877d6877a2dfc3b12b1dc6e6b40342120a735aa35814d203a7c9e5581f40ec9950c5732f6698e4facbe0e3b98d278e1c2ca39c880e141d863e3042407863 SHA512 8b7093ded2c79ab7f7adc7b578f3b349a364fe5c3d01a4617184a64f30799f336d5911221f79478bf8e61159b99144584efef1add0df835fa84d309ba68ea0cb AUX mixxx-2.1.0-denon-mc6000mk2-use-ramping-for-back-spins.patch 64070 BLAKE2B fd6941c4c995559e12900db68a92c32e79ee94841cb0c7f536296ef079db39fdcde6014c697f94d2f2d92d17c8e41f72c02343cdadc8054816ca2d6ca98b4dc4 SHA512 7d481cec81e88f7fefeff92969a49881ffaca9bd7fb17c215c45363d3078e9e31350829299479eb111000a04924634ff1b25579f951d6da9dc52ac4d3ac38a96 +AUX mixxx-2.1.0-detect-m4a-decoding-errors-on-windows.patch 6352 BLAKE2B 6d7e83f037089729c085c7458fba7580063cff2a01bbc9b2260688cb350ebc3924da0190dab5d353b1e6db4766b6ef1ca63d5e7776728eddfd7032bfb355738b SHA512 18fbbf80fa72aaf50b1f716b220ea741d9deb3c003f56bdb34e10f9c4421b1b0c8ad19775927be93e3ca6b0aea35c10c3927dcb8f1ffcf95a5b60203fce452b5 AUX mixxx-2.1.0-fidlib-thread-safe-and-reentrant-generation-of-filters.patch 35122 BLAKE2B 976c623afc6f62fb5ee5082bcc503b7ca4bf5af160e102257024874e750a681347d6e4b70328a6596c88b261ed02f66ccb7c5897d1cf8174a92e4bb50d1e55c9 SHA512 377e2cd176264849f7de28d48107dca1c41b18a02c610d4f8c1ac824dc6e4c3d8b18363a7a3ae0d585157fed33592ad6cf578148508416b0783bd6b4084aaeb1 +AUX mixxx-2.1.0-fix-cachingreader-compiler-warnings-about-non-trivial-types.patch 7055 BLAKE2B 669038949243674c8b7aaccd0cea4cc6c21644dd4bc2de463800bed71677d4e77cc5b3f5da89d0be3bdc44c847247afbf7b6248a29840aec676916bc8b9bc96f SHA512 45ec03e0d37b72d969fa730348a068df61200bae0a613045d9711637b6abc04608f2b3e7c2d99551dfa24c86846b3426c9f3600518258012e6e4d118f7beb947 AUX mixxx-2.1.0-fix-clearing-of-replaygain-gain-ratio-in-file-tags.patch 6898 BLAKE2B 7e20e44b0d6646cf410473b3d4c1ca310aa1b9ec8fafb06ee4480a90be7cb6fd3b67ac1a425d98beed03eef22016ad76f127ddcb46c6a7a22237ca93b59826ab SHA512 ecffb8bab5ad1d1f55acc2c3187a4dd10edda22e6708754e76184181808afc3fb014d43544b0a1006c9a439673bb56ab54549a0d95c0a05e709dcaba3600f8cc AUX mixxx-2.1.0-fix-crash-when-removing-a-quick-link.patch 3143 BLAKE2B e0562c35c83fcefe50362a5f2359cbca10853a0a4c2285866a5bd48a8ff7d13de066c2a153e86dd657c18fe1a30610f55f8e2ec95a958c9d0cc3a6288064f572 SHA512 94ba8e2e94f6f5ed8152f9499b5334211e812e374a5fafd48b8dc21e9e0b0ae8d6919f6a59fb3bae6c1d86de820ad654be45b0813f896cf4819dfaf2bebedc2d AUX mixxx-2.1.0-fix-decoding-of-improperly-encoded-flac-files.patch 8256 BLAKE2B 5fd8a4ddb15449477212f077b7b176ffe30adfbb5521eece8e9fa5e7af17a2247f3f9936841ebfcf271664e1cf8928f71426019e5b8e02ae4972193c4351de21 SHA512 0c44bbd9d8d67b843420de6cafeb3e10f2ed31ff8af424d5e9d219d41f3e465ddee40141530fcba000cb99e4a136850c418dcae5bd73047328c7436635d85071 @@ -15,8 +17,9 @@ AUX mixxx-2.1.0-fix-navigation-usability-issues-in-sidebar-tree.patch 15383 BLAK AUX mixxx-2.1.0-fix-s4-mk2-for-windows.patch 2065 BLAKE2B aa36275f3e0fdb08c73408941f7374f5818890d0de119a6992a811f58c5da76ad45d47c5a2e5668eca47131eca12f565b4016c7b8510fb35f6ad03cd429cc0c8 SHA512 196ff5a3769a31b8b1fb264b8a3de1eccdd10c3764a4dd2c4c411ab3d886cd232601b86b119b375c0a08141f86afd8551a4315610cfd39459c3b0cb806246f6e AUX mixxx-2.1.0-fix-spinback-inertia-effect-partial-revert-of-2b612c2.patch 1151 BLAKE2B a49e171ca017e3b36b7271859093e77bedd038dc42085330babc39a675549b708fa8b2a9b0774a44fa6cc0abbfcddad57173e75d7ce3d163828bfa6e727a1a6c SHA512 1bcda1e863337f9e330fb04ecdee1b0600093bad069bc0d48b3ac4e0c456471319bb42a0f5e9aa8b42bc1e88db81795063290733c57a1dff60f4750e55a206de AUX mixxx-2.1.0-fix-unresponsive-scrolling-through-crates-and-playlists-using-encoder.patch 10554 BLAKE2B fedfdb247f55ac438635a527e30b132386e95f40143c26b581f6929a45126b7d97a4ea98d84582a6dded002afa623a7fac3a0f1e2e03499e592967df0fbe7646 SHA512 18b3d51f5c341e412f9fae2bb596ef569906e628ea5102d35864f299be2c2f21853833964b0566f4c3c6a964ee52627eb6ec0982ebc3d4151b3e6210765504e1 +AUX mixxx-2.1.0-optimize-flac-decoding.patch 9430 BLAKE2B f3d0b707f69332f94db54416fc9a9a6374302853daa8fb3046048e66f25259081f9bbe46c1dc8620076904a7f1a57abf051be0db3af02378ac9df06dc353f765 SHA512 5d244f8fe606eab6c6bea64439a520ada568dd2681d05fcdbdd1abebabf5bc74eecf3aa67765f4d2d78295a9a87c9ca7746cfc59cfd5db1a4b8a085f36b95cd6 AUX mixxx-2.1.0-pioneer-ddj-sx-mapping-bugfixes.patch 11255 BLAKE2B 9e15935f3fcfe9e26c04960496998450ee15cf8eb7b98e0439064caf9653617b94e0bf4c93f13ee49d169accabe662f9f8ca2abea05559b91d7f5362225de1c9 SHA512 f4774fe4884d339f2929468551b2f248200f3dc1c31c436070c8a439d18cf524aab0dd7ca990595e0c88ddd70e1e71dee025a641df6d240724fec94f2087ebd0 AUX mixxx-2.1.0-swap-default-values-for-temp-perm-ratechanges.patch 1534 BLAKE2B 30e2c7fe396919fcdfba7102f360e307e2104bfa6480ec5615bc1482f2e496f99435d745468621f6ff7ae15e0e4857fd6db692061cf5d7b19b0bc7672b889aea SHA512 e0c6365f26313935b503de36edb9ed247333e892352645d5379659bc7a53761b7b24d1a162dee38cb776e17f5e8741d5235713d47f5812975169395bb4d00f05 AUX mixxx-2.1.0-use-an-in-memory-database-to-speed-up-library-tests.patch 3086 BLAKE2B d2cb0b7992cdb07b1ba2accde1d272cd3f75adf8bd3bb2450ad9203db5d7978c9b29dbf6e278a2a1f1fb8fb84f28b23f276f0f999b3e5d77c272b91716dcc9f1 SHA512 a6fefbc80f8facc8cd0bf501858b4dadb6ebe4bf476dc97273ad7e97ae2c0840ca9bd6b0b3aaa34caa837b967ee7fa12635c7c2957241ca6aff5a26531b6e25f DIST mixxx-2.1.0-src.tar.gz 34835250 BLAKE2B 7a90c3794a146001fd0df6bb7c9c6231c0d26814eafc5c83da666d511d7af0e193b75da9b8728ad399dbef208cf2437881df2c87818e503945b02591bc300567 SHA512 d9f4fab92c2896ec455e2041aa6033f9a9091d2915a185a99427b9c35afe7c99565350ce477bf0487c6276c9585875f0be61f310779ae90195917d2e995bbf90 -EBUILD mixxx-2.1.0.ebuild 4022 BLAKE2B c54d9fba59d76a6c6119f29e5e549c324f1afda4aaddda572b0d6c3216566d6765bce280f33fe48c4a3d40ff580f3e03e52d10247e9b54dcc1bbd6686f4ccd7f SHA512 e4406c1d6efe023ab7533c358bbc7761f39126e3d5a96ee0004fc5089976b8636bd5770966356e84971e627ac631630a85a9718051d0f5c99ec147b1502f084d +EBUILD mixxx-2.1.0.ebuild 4222 BLAKE2B 11bc982a6ebd2c5b4a0070f9b0f4de511092741694b93929161875f7f4c438072dabec7ba5a407a12d8a5a267556da503aeb720d3df7cd0a5132b6373bff52f2 SHA512 f14876e9651a37c4f2982fb66b4a9d08f7a798f5e56ce16942189b7ae3c4a6b296b5a6812f9f537ec24185336d1b0f67907d759d002298c9dce669efea8dde42 diff --git a/media-sound/mixxx/files/mixxx-2.1.0-detect-m4a-decoding-errors-on-windows.patch b/media-sound/mixxx/files/mixxx-2.1.0-detect-m4a-decoding-errors-on-windows.patch new file mode 100644 index 0000000..c77e1d8 --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-detect-m4a-decoding-errors-on-windows.patch @@ -0,0 +1,124 @@ +From 901b65b785f6c55e7b484350fea02b6d328e8094 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Wed, 25 Apr 2018 11:17:00 +0200 +Subject: [PATCH 1/2] Windows MF: Fix rounding errors when seeking and reading + +--- + .../soundsourcemediafoundation.h | 37 ++++++++++++---------- + 1 file changed, 21 insertions(+), 16 deletions(-) + +diff --git a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h +index 7e1abf4da5..e9a8d608f1 100755 +--- a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h ++++ b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.h +@@ -17,37 +17,42 @@ class StreamUnitConverter final { + public: + StreamUnitConverter() + : m_pAudioSource(nullptr), +- m_streamUnitsPerFrame(0.0), +- m_toFrameIndexBias(0) { ++ m_fromSampleFramesToStreamUnits(0), ++ m_fromStreamUnitsToSampleFrames(0) { + } + explicit StreamUnitConverter(const AudioSource* pAudioSource) + : m_pAudioSource(pAudioSource), +- m_streamUnitsPerFrame(double(kStreamUnitsPerSecond) / double(pAudioSource->sampleRate())), +- m_toFrameIndexBias(kStreamUnitsPerSecond / pAudioSource->sampleRate() / 2) { +- // The stream units should actually be much shorter +- // than the frames to minimize jitter. Even a frame +- // at 192 kHz has a length of about 5000 ns >> 100 ns. +- DEBUG_ASSERT(m_streamUnitsPerFrame >= 50); +- DEBUG_ASSERT(m_toFrameIndexBias > 0); ++ m_fromSampleFramesToStreamUnits(double(kStreamUnitsPerSecond) / double(pAudioSource->sampleRate())), ++ m_fromStreamUnitsToSampleFrames(double(pAudioSource->sampleRate()) / double(kStreamUnitsPerSecond)){ ++ // The stream units should actually be much shorter than ++ // sample frames to minimize jitter and rounding. Even a ++ // frame at 192 kHz has a length of about 5000 ns >> 100 ns. ++ DEBUG_ASSERT(m_fromStreamUnitsToSampleFrames >= 50); + } + + LONGLONG fromFrameIndex(SINT frameIndex) const { ++ DEBUG_ASSERT(m_fromSampleFramesToStreamUnits > 0); + // Used for seeking, so we need to round down to hit the + // corresponding stream unit where the given stream unit +- // starts +- return floor((frameIndex - m_pAudioSource->frameIndexMin()) * m_streamUnitsPerFrame); ++ // starts. The reader will skip samples until it reaches ++ // the actual target position for reading. ++ const SINT frameIndexOffset = frameIndex - m_pAudioSource->frameIndexMin(); ++ return static_cast(floor(frameIndexOffset * m_fromSampleFramesToStreamUnits)); + } + + SINT toFrameIndex(LONGLONG streamPos) const { +- // NOTE(uklotzde): Add m_toFrameIndexBias to account for rounding errors +- return m_pAudioSource->frameIndexMin() + +- static_cast(floor((streamPos + m_toFrameIndexBias) / m_streamUnitsPerFrame)); ++ DEBUG_ASSERT(m_fromStreamUnitsToSampleFrames > 0); ++ // The stream reports positions in units of 100ns. We have ++ // to round(!) this value to obtain the actual position in ++ // sample frames. ++ const SINT frameIndexOffset = static_cast(round(streamPos * m_fromStreamUnitsToSampleFrames)); ++ return m_pAudioSource->frameIndexMin() + frameIndexOffset; + } + + private: + const AudioSource* m_pAudioSource; +- double m_streamUnitsPerFrame; +- SINT m_toFrameIndexBias; ++ double m_fromSampleFramesToStreamUnits; ++ double m_fromStreamUnitsToSampleFrames; + }; + + class SoundSourceMediaFoundation: public mixxx::SoundSourcePlugin { + +From e9474dcdf752d51fc3390ff6851c02f8e249fb4d Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Wed, 25 Apr 2018 16:24:35 +0200 +Subject: [PATCH 2/2] Windows MF: Validate the current position while reading + +...and avoid to update if not necessary to prevent rounding errors. +Just log any suspicious values. +--- + .../soundsourcemediafoundation.cpp | 29 +++++++++++++++++++--- + 1 file changed, 25 insertions(+), 4 deletions(-) + +diff --git a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp +index 3ed0d3b5e8..8eac78220d 100755 +--- a/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp ++++ b/plugins/soundsourcemediafoundation/soundsourcemediafoundation.cpp +@@ -351,10 +351,31 @@ ReadableSampleFrames SoundSourceMediaFoundation::readSampleFramesClamped( + } + DEBUG_ASSERT(pSample != nullptr); + SINT readerFrameIndex = m_streamUnitConverter.toFrameIndex(streamPos); +- DEBUG_ASSERT( +- (m_currentFrameIndex == kUnknownFrameIndex) || // unknown position after seeking +- (m_currentFrameIndex == readerFrameIndex)); +- m_currentFrameIndex = readerFrameIndex; ++ if (m_currentFrameIndex == kUnknownFrameIndex) { ++ // Unknown position after seeking ++ m_currentFrameIndex = readerFrameIndex; ++ /* ++ kLogger.debug() ++ << "Stream position (in sample frames) after seeking:" ++ << "target =" << writableSampleFrames.frameIndexRange().end() ++ << "current =" << readerFrameIndex; ++ */ ++ } else { ++ // Both positions should match, otherwise readerFrameIndex ++ // is inaccurate due to rounding errors after conversion from ++ // stream units to frames! But if this ever happens we better ++ // trust m_currentFrameIndex that is continuously updated while ++ // reading in forward direction. ++ VERIFY_OR_DEBUG_ASSERT(m_currentFrameIndex == readerFrameIndex) { ++ kLogger.debug() ++ << "streamPos [100 ns] =" << streamPos ++ << ", sampleRate [Hz] =" << sampleRate(); ++ kLogger.warning() ++ << "Stream position (in sample frames) while reading is inaccurate:" ++ << "expected =" << m_currentFrameIndex ++ << "actual =" << readerFrameIndex; ++ } ++ } + + DWORD dwSampleBufferCount = 0; + HRESULT hrGetBufferCount = diff --git a/media-sound/mixxx/files/mixxx-2.1.0-fix-cachingreader-compiler-warnings-about-non-trivial-types.patch b/media-sound/mixxx/files/mixxx-2.1.0-fix-cachingreader-compiler-warnings-about-non-trivial-types.patch new file mode 100644 index 0000000..6734ccb --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-fix-cachingreader-compiler-warnings-about-non-trivial-types.patch @@ -0,0 +1,164 @@ +From 901cacb96a0c3898b7b7af3cddd87e0d02f67235 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Sat, 12 May 2018 00:20:59 +0200 +Subject: [PATCH] Fix CachingReader compiler warnings about non-trivial types + +--- + src/engine/cachingreader.cpp | 8 ++++---- + src/engine/cachingreaderworker.cpp | 17 +++++++++++------ + src/engine/cachingreaderworker.h | 36 ++++++++++++++++++++++-------------- + 3 files changed, 37 insertions(+), 24 deletions(-) + +diff --git a/src/engine/cachingreader.cpp b/src/engine/cachingreader.cpp +index 2764e5c96c..2440b3a8f8 100644 +--- a/src/engine/cachingreader.cpp ++++ b/src/engine/cachingreader.cpp +@@ -204,7 +204,7 @@ void CachingReader::process() { + } else if (status.status == TRACK_LOADED) { + m_readerStatus = status.status; + // Reset the max. readable frame index +- m_readableFrameIndexRange = status.readableFrameIndexRange; ++ m_readableFrameIndexRange = status.readableFrameIndexRange(); + // Free all chunks with sample data from a previous track + freeAllChunks(); + } +@@ -212,7 +212,7 @@ void CachingReader::process() { + // Adjust the readable frame index range after loading or reading + m_readableFrameIndexRange = intersect( + m_readableFrameIndexRange, +- status.readableFrameIndexRange); ++ status.readableFrameIndexRange()); + } else { + // Reset the readable frame index range + m_readableFrameIndexRange = mixxx::IndexRange(); +@@ -467,8 +467,8 @@ void CachingReader::hintAndMaybeWake(const HintVector& hintList) { + } + // Do not insert the allocated chunk into the MRU/LRU list, + // because it will be handed over to the worker immediately +- CachingReaderChunkReadRequest request(pChunk); +- pChunk->giveToWorker(); ++ CachingReaderChunkReadRequest request; ++ request.giveToWorker(pChunk); + // kLogger.debug() << "Requesting read of chunk" << current << "into" << pChunk; + // kLogger.debug() << "Requesting read into " << request.chunk->data; + if (m_chunkReadRequestFIFO.write(&request, 1) != 1) { +diff --git a/src/engine/cachingreaderworker.cpp b/src/engine/cachingreaderworker.cpp +index 600389f86f..34f9a9ac83 100644 +--- a/src/engine/cachingreaderworker.cpp ++++ b/src/engine/cachingreaderworker.cpp +@@ -42,7 +42,9 @@ ReaderStatusUpdate CachingReaderWorker::processReadRequest( + // actually available. + const auto chunkFrameIndexRange = pChunk->frameIndexRange(m_pAudioSource); + if (intersect(chunkFrameIndexRange, m_readableFrameIndexRange).empty()) { +- return ReaderStatusUpdate(CHUNK_READ_INVALID, pChunk, m_readableFrameIndexRange); ++ ReaderStatusUpdate result; ++ result.init(CHUNK_READ_INVALID, pChunk, m_readableFrameIndexRange); ++ return result; + } + + // Try to read the data required for the chunk from the audio source +@@ -77,7 +79,9 @@ ReaderStatusUpdate CachingReaderWorker::processReadRequest( + << "from originally" + << m_pAudioSource->frameIndexRange(); + } +- return ReaderStatusUpdate(status, pChunk, m_readableFrameIndexRange); ++ ReaderStatusUpdate result; ++ result.init(status, pChunk, m_readableFrameIndexRange); ++ return result; + } + + // WARNING: Always called from a different thread (GUI) +@@ -91,10 +95,10 @@ void CachingReaderWorker::run() { + unsigned static id = 0; //the id of this thread, for debugging purposes + QThread::currentThread()->setObjectName(QString("CachingReaderWorker %1").arg(++id)); + +- CachingReaderChunkReadRequest request; +- + Event::start(m_tag); + while (!load_atomic(m_stop)) { ++ // Request is initialized by reading from FIFO ++ CachingReaderChunkReadRequest request; + if (m_newTrackAvailable) { + TrackPointer pLoadTrack; + { // locking scope +@@ -130,7 +134,7 @@ mixxx::AudioSourcePointer openAudioSourceForReading(const TrackPointer& pTrack, + + void CachingReaderWorker::loadTrack(const TrackPointer& pTrack) { + ReaderStatusUpdate status; +- status.status = TRACK_NOT_LOADED; ++ status.init(TRACK_NOT_LOADED); + + if (!pTrack) { + // Unload track +@@ -179,8 +183,9 @@ void CachingReaderWorker::loadTrack(const TrackPointer& pTrack) { + // be decreased to avoid repeated reading of corrupt audio data. + m_readableFrameIndexRange = m_pAudioSource->frameIndexRange(); + +- status.readableFrameIndexRange = m_readableFrameIndexRange; + status.status = TRACK_LOADED; ++ status.readableFrameIndexRangeStart = m_readableFrameIndexRange.start(); ++ status.readableFrameIndexRangeEnd = m_readableFrameIndexRange.end(); + m_pReaderStatusFIFO->writeBlocking(&status, 1); + + // Clear the chunks to read list. +diff --git a/src/engine/cachingreaderworker.h b/src/engine/cachingreaderworker.h +index 4d60e7c3ed..54c5a4c77e 100644 +--- a/src/engine/cachingreaderworker.h ++++ b/src/engine/cachingreaderworker.h +@@ -14,12 +14,14 @@ + #include "util/fifo.h" + + ++// POD with trivial ctor/dtor/copy for passing through FIFO + typedef struct CachingReaderChunkReadRequest { + CachingReaderChunk* chunk; + +- explicit CachingReaderChunkReadRequest( +- CachingReaderChunk* chunkArg = nullptr) +- : chunk(chunkArg) { ++ void giveToWorker(CachingReaderChunkForOwner* chunkForOwner) { ++ DEBUG_ASSERT(chunkForOwner); ++ chunk = chunkForOwner; ++ chunkForOwner->giveToWorker(); + } + } CachingReaderChunkReadRequest; + +@@ -32,21 +34,27 @@ enum ReaderStatus { + CHUNK_READ_INVALID + }; + ++// POD with trivial ctor/dtor/copy for passing through FIFO + typedef struct ReaderStatusUpdate { + ReaderStatus status; + CachingReaderChunk* chunk; +- mixxx::IndexRange readableFrameIndexRange; +- ReaderStatusUpdate() +- : status(INVALID) +- , chunk(nullptr) { ++ SINT readableFrameIndexRangeStart; ++ SINT readableFrameIndexRangeEnd; ++ ++ void init( ++ ReaderStatus statusArg = INVALID, ++ CachingReaderChunk* chunkArg = nullptr, ++ const mixxx::IndexRange& readableFrameIndexRangeArg = mixxx::IndexRange()) { ++ status = statusArg; ++ chunk = chunkArg; ++ readableFrameIndexRangeStart = readableFrameIndexRangeArg.start(); ++ readableFrameIndexRangeEnd = readableFrameIndexRangeArg.end(); + } +- ReaderStatusUpdate( +- ReaderStatus statusArg, +- CachingReaderChunk* chunkArg, +- const mixxx::IndexRange& readableFrameIndexRangeArg) +- : status(statusArg) +- , chunk(chunkArg) +- , readableFrameIndexRange(readableFrameIndexRangeArg) { ++ ++ mixxx::IndexRange readableFrameIndexRange() const { ++ return mixxx::IndexRange::between( ++ readableFrameIndexRangeStart, ++ readableFrameIndexRangeEnd); + } + } ReaderStatusUpdate; + diff --git a/media-sound/mixxx/files/mixxx-2.1.0-optimize-flac-decoding.patch b/media-sound/mixxx/files/mixxx-2.1.0-optimize-flac-decoding.patch new file mode 100644 index 0000000..5006e8b --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-optimize-flac-decoding.patch @@ -0,0 +1,208 @@ +From 497e9672dfd1079e28cadc9a413a0b8be00ed59d Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Wed, 9 May 2018 12:08:59 +0200 +Subject: [PATCH 1/4] Optimize FLAC decoding + +--- + src/sources/soundsourceflac.cpp | 51 ++++++++++++++++++++--------------------- + src/sources/soundsourceflac.h | 2 -- + 2 files changed, 25 insertions(+), 28 deletions(-) + +diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp +index 3d68e05ce7..50cb0955e6 100644 +--- a/src/sources/soundsourceflac.cpp ++++ b/src/sources/soundsourceflac.cpp +@@ -71,7 +71,6 @@ SoundSourceFLAC::SoundSourceFLAC(const QUrl& url) + m_decoder(nullptr), + m_maxBlocksize(0), + m_bitsPerSample(kBitsPerSampleDefault), +- m_sampleScaleFactor(CSAMPLE_ZERO), + m_curFrameIndex(0) { + } + +@@ -345,25 +344,30 @@ FLAC__bool SoundSourceFLAC::flacEOF() { + return m_file.atEnd(); + } + ++namespace { ++ ++// Workaround for improperly encoded FLAC files that may contain ++// garbage in the most significant, unused bits of decoded samples. ++// Required at least for libFLAC 1.3.2. This workaround might become ++// obsolete once libFLAC is taking care of these issues internally. ++// https://bugs.launchpad.net/mixxx/+bug/1769717 ++// https://hydrogenaud.io/index.php/topic,61792.msg559045.html#msg559045 ++// ++// We will shift decoded samples left by (32 - m_bitsPerSample) to ++// get rid of the garbage in the most significant bits before scaling. ++// The range of decoded integer sample values then becomes ++// [-2 ^ 31, 2 ^ 31 - 1]. Afterwards this integer range needs to be ++// scaled to [-CSAMPLE_PEAK, CSAMPLE_PEAK). ++ ++const CSAMPLE kSampleScaleFactor = CSAMPLE_PEAK / (static_cast(1) << 31); ++ + inline +-FLAC__int32 adjustDecodedSample(FLAC__int32 decodedSample, SINT bitsPerSample) { +- // Workaround for improperly encoded FLAC files that may contain +- // garbage in the most significant, unused bits of decoded samples. +- // Required at least for libFLAC 1.3.2. This workaround might become +- // obsolete once libFLAC is taking care of these issues internally. +- // https://bugs.launchpad.net/mixxx/+bug/1769717 +- // https://hydrogenaud.io/index.php/topic,61792.msg559045.html#msg559045 +- FLAC__int32 signBit = static_cast(1) << (bitsPerSample - 1); +- FLAC__int32 bitMask = (static_cast(1) << bitsPerSample) - 1; // == (signBit << 1) - 1 +- FLAC__int32 maskedSample = decodedSample & bitMask; +- if (maskedSample & signBit) { +- // Sign extension for negative values +- return maskedSample | ~bitMask; +- } else { +- return maskedSample; +- } ++CSAMPLE convertDecodedSample(FLAC__int32 decodedSample, int bitsPerSample) { ++ return (decodedSample << (32 - bitsPerSample)) * kSampleScaleFactor; + } + ++} // anonymous namespace ++ + FLAC__StreamDecoderWriteStatus SoundSourceFLAC::flacWrite( + const FLAC__Frame* frame, const FLAC__int32* const buffer[]) { + const SINT numChannels = frame->header.channels; +@@ -410,15 +414,15 @@ FLAC__StreamDecoderWriteStatus SoundSourceFLAC::flacWrite( + case 1: { + // optimized code for 1 channel (mono) + for (SINT i = 0; i < numWritableFrames; ++i) { +- *pSampleBuffer++ = adjustDecodedSample(buffer[0][i], m_bitsPerSample) * m_sampleScaleFactor; ++ *pSampleBuffer++ = convertDecodedSample(buffer[0][i], m_bitsPerSample); + } + break; + } + case 2: { + // optimized code for 2 channels (stereo) + for (SINT i = 0; i < numWritableFrames; ++i) { +- *pSampleBuffer++ = adjustDecodedSample(buffer[0][i], m_bitsPerSample) * m_sampleScaleFactor; +- *pSampleBuffer++ = adjustDecodedSample(buffer[1][i], m_bitsPerSample) * m_sampleScaleFactor; ++ *pSampleBuffer++ = convertDecodedSample(buffer[0][i], m_bitsPerSample); ++ *pSampleBuffer++ = convertDecodedSample(buffer[1][i], m_bitsPerSample); + } + break; + } +@@ -426,7 +430,7 @@ FLAC__StreamDecoderWriteStatus SoundSourceFLAC::flacWrite( + // generic code for multiple channels + for (SINT i = 0; i < numWritableFrames; ++i) { + for (SINT j = 0; j < channelCount(); ++j) { +- *pSampleBuffer++ = adjustDecodedSample(buffer[j][i], m_bitsPerSample) * m_sampleScaleFactor; ++ *pSampleBuffer++ = convertDecodedSample(buffer[j][i], m_bitsPerSample); + } + } + } +@@ -456,11 +460,6 @@ void SoundSourceFLAC::flacMetadata(const FLAC__StreamMetadata* metadata) { + // not set before + if ((bitsPerSample >= 4) && (bitsPerSample <= 32)) { + m_bitsPerSample = bitsPerSample; +- // Range of signed) sample values: [-2 ^ (bitsPerSample - 1), 2 ^ (bitsPerSample - 1) - 1] +- const uint32_t absSamplePeak = 1u << (bitsPerSample - 1); +- DEBUG_ASSERT(absSamplePeak > 0); +- // Scaled range of samples values: [-CSAMPLE_PEAK, CSAMPLE_PEAK) +- m_sampleScaleFactor = CSAMPLE_PEAK / absSamplePeak; + } else { + kLogger.warning() + << "Invalid bits per sample:" +diff --git a/src/sources/soundsourceflac.h b/src/sources/soundsourceflac.h +index 05c74f7b5e..f4b3c1cb3c 100644 +--- a/src/sources/soundsourceflac.h ++++ b/src/sources/soundsourceflac.h +@@ -49,8 +49,6 @@ class SoundSourceFLAC: public SoundSource { + SINT m_maxBlocksize; // in time samples (audio samples = time samples * chanCount) + SINT m_bitsPerSample; + +- CSAMPLE m_sampleScaleFactor; +- + ReadAheadSampleBuffer m_sampleBuffer; + + void invalidateCurFrameIndex() { + +From 24c206f60278b8e9576ae661643162512ff1d19b Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Wed, 9 May 2018 12:14:31 +0200 +Subject: [PATCH 2/4] Add an assertion (just in case) + +--- + src/sources/soundsourceflac.cpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp +index 50cb0955e6..c01ab8455d 100644 +--- a/src/sources/soundsourceflac.cpp ++++ b/src/sources/soundsourceflac.cpp +@@ -363,6 +363,7 @@ const CSAMPLE kSampleScaleFactor = CSAMPLE_PEAK / (static_cast(1) < + + inline + CSAMPLE convertDecodedSample(FLAC__int32 decodedSample, int bitsPerSample) { ++ DEBUG_ASSERT(sizeof(FLAC__int32) == 32); // exactly 32-bits required! + return (decodedSample << (32 - bitsPerSample)) * kSampleScaleFactor; + } + + +From 6dc1d5f1a7e291c36d5828fdaecc82a62845b758 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Wed, 9 May 2018 12:25:00 +0200 +Subject: [PATCH 3/4] Get rid of (most) implicit assumptions + +--- + src/sources/soundsourceflac.cpp | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp +index c01ab8455d..478bac870e 100644 +--- a/src/sources/soundsourceflac.cpp ++++ b/src/sources/soundsourceflac.cpp +@@ -359,12 +359,12 @@ namespace { + // [-2 ^ 31, 2 ^ 31 - 1]. Afterwards this integer range needs to be + // scaled to [-CSAMPLE_PEAK, CSAMPLE_PEAK). + +-const CSAMPLE kSampleScaleFactor = CSAMPLE_PEAK / (static_cast(1) << 31); ++const CSAMPLE kSampleScaleFactor = CSAMPLE_PEAK / (static_cast(1) << std::numeric_limits::digits); + + inline + CSAMPLE convertDecodedSample(FLAC__int32 decodedSample, int bitsPerSample) { +- DEBUG_ASSERT(sizeof(FLAC__int32) == 32); // exactly 32-bits required! +- return (decodedSample << (32 - bitsPerSample)) * kSampleScaleFactor; ++ DEBUG_ASSERT(std::numeric_limits::is_signed); ++ return (decodedSample << ((std::numeric_limits::digits + 1) - bitsPerSample)) * kSampleScaleFactor; + } + + } // anonymous namespace + +From a0430875f6c4ad89c0fb09300ed19a64c60bbfb4 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Wed, 9 May 2018 15:16:58 +0200 +Subject: [PATCH 4/4] Use constexpr and reword comments + +--- + src/sources/soundsourceflac.cpp | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp +index 478bac870e..1a95ac168c 100644 +--- a/src/sources/soundsourceflac.cpp ++++ b/src/sources/soundsourceflac.cpp +@@ -352,14 +352,12 @@ namespace { + // obsolete once libFLAC is taking care of these issues internally. + // https://bugs.launchpad.net/mixxx/+bug/1769717 + // https://hydrogenaud.io/index.php/topic,61792.msg559045.html#msg559045 +-// +-// We will shift decoded samples left by (32 - m_bitsPerSample) to +-// get rid of the garbage in the most significant bits before scaling. +-// The range of decoded integer sample values then becomes +-// [-2 ^ 31, 2 ^ 31 - 1]. Afterwards this integer range needs to be +-// scaled to [-CSAMPLE_PEAK, CSAMPLE_PEAK). + +-const CSAMPLE kSampleScaleFactor = CSAMPLE_PEAK / (static_cast(1) << std::numeric_limits::digits); ++// We will shift decoded samples left by (32 - m_bitsPerSample) to ++// get rid of the garbage in the most significant bits before scaling ++// to the range [-CSAMPLE_PEAK, CSAMPLE_PEAK - epsilon] with ++// epsilon = 1 / 2 ^ bitsPerSample. ++constexpr CSAMPLE kSampleScaleFactor = CSAMPLE_PEAK / (static_cast(1) << std::numeric_limits::digits); + + inline + CSAMPLE convertDecodedSample(FLAC__int32 decodedSample, int bitsPerSample) { diff --git a/media-sound/mixxx/mixxx-2.1.0.ebuild b/media-sound/mixxx/mixxx-2.1.0.ebuild index b8f6a18..1e1fd21 100644 --- a/media-sound/mixxx/mixxx-2.1.0.ebuild +++ b/media-sound/mixxx/mixxx-2.1.0.ebuild @@ -82,6 +82,10 @@ PATCHES=( "${FILESDIR}"/${P}-fix-decoding-of-improperly-encoded-flac-files.patch "${FILESDIR}"/${P}-fix-spinback-inertia-effect-partial-revert-of-2b612c2.patch "${FILESDIR}"/${P}-denon-mc6000mk2-use-ramping-for-back-spins.patch + "${FILESDIR}"/${P}-optimize-flac-decoding.patch + "${FILESDIR}"/${P}-detect-m4a-decoding-errors-on-windows.patch + "${FILESDIR}"/${P}-fix-cachingreader-compiler-warnings-about-non-trivial-types.patch + ) S="${WORKDIR}/${PN}-release-${PV}"