From 7bf8165092af8dacbc58d74c10ee2f5d80041cbc Mon Sep 17 00:00:00 2001 From: David Guglielmi Date: Sat, 28 Apr 2018 14:35:35 +0200 Subject: [PATCH] media-sound/mixxx: re-keyword, backport fixes from upcoming 2.1.1 --- media-sound/mixxx/Manifest | 16 +- ...d-fix-false-poisitiv-restart-request.patch | 127 ++ ...-and-reentrant-generation-of-filters.patch | 1209 +++++++++++++++++ ...f-replaygain-gain-ratio-in-file-tags.patch | 152 +++ ...fix-crash-when-removing-a-quick-link.patch | 69 + ...-flac-decoding-and-upgrade-db-schema.patch | 373 +++++ ...egration-of-external-track-libraries.patch | 388 ++++++ ...0-fix-invocation-args-of-pasuspender.patch | 58 + ...x-latenight-group-fx-buttons-in-deck.patch | 197 +++ ...x-memory-leak-when-loading-cover-art.patch | 38 + ...ion-usability-issues-in-sidebar-tree.patch | 395 ++++++ .../mixxx-2.1.0-fix-s4-mk2-for-windows.patch | 51 + ...h-crates-and-playlists-using-encoder.patch | 281 ++++ ...ult-values-for-temp-perm-ratechanges.patch | 31 + ...y-database-to-speed-up-library-tests.patch | 79 ++ media-sound/mixxx/mixxx-2.1.0.ebuild | 19 +- 16 files changed, 3478 insertions(+), 5 deletions(-) create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-debug-assert-and-fix-false-poisitiv-restart-request.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-fidlib-thread-safe-and-reentrant-generation-of-filters.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-fix-clearing-of-replaygain-gain-ratio-in-file-tags.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-fix-crash-when-removing-a-quick-link.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-fix-flac-decoding-and-upgrade-db-schema.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-fix-integration-of-external-track-libraries.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-fix-invocation-args-of-pasuspender.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-fix-latenight-group-fx-buttons-in-deck.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-fix-memory-leak-when-loading-cover-art.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-fix-navigation-usability-issues-in-sidebar-tree.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-fix-s4-mk2-for-windows.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-fix-unresponsive-scrolling-through-crates-and-playlists-using-encoder.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-swap-default-values-for-temp-perm-ratechanges.patch create mode 100644 media-sound/mixxx/files/mixxx-2.1.0-use-an-in-memory-database-to-speed-up-library-tests.patch diff --git a/media-sound/mixxx/Manifest b/media-sound/mixxx/Manifest index 940d03d..40d4c32 100644 --- a/media-sound/mixxx/Manifest +++ b/media-sound/mixxx/Manifest @@ -1,3 +1,17 @@ AUX mixxx-2.0.0-docs.patch 435 BLAKE2B c2e9b09abb293e59b2af49527eccf07c9488ae5e30e29e6c4d6330cc298a568ee7dd7014af6b9c1f1c4d98b8c11c96da7f74660eb4b3b522f449e7a6a431addc SHA512 01ab76466f782f538c894e460f7694553ae12804651f68aabb6aaa0dbdc89e2ff7e2b51529b0f112cee42c8053b75fc64241a9c8898def8cf1c76231b1ec5d59 +AUX mixxx-2.1.0-debug-assert-and-fix-false-poisitiv-restart-request.patch 5694 BLAKE2B 7732252cf6438df9d52e6de8ceaaf6b2e1c30e35d8154eb7af5d94641346117d4ab0b5501686909d35c81a5fd5aa9442831f11b66faaec782c11a55e14a11363 SHA512 ee35ea84db8bf91cd2f14dd779faa91857df7bcc376525d533e65c778e241a5e66c829ab208e2da5d4afb3a48571042c13e5092c4974a07a9ea11146df68d326 +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-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-flac-decoding-and-upgrade-db-schema.patch 15891 BLAKE2B fd032363b07357c1fa16c2376b5f2f5b9580cb9c4534238336fca014f5432e460ba081c20608f22055c4e0799c17fba0f96b7d65a131d193d398ee5ffdda8e95 SHA512 99d3feb6761b8bd58acd7e1e4a8f0d2660b1bc1fb7f1885fb0211ad09dec3b1ab77c4ff0b8054e04313170bc050b0e655e8c90aa3d8301c39189ca6c2e2e4bdd +AUX mixxx-2.1.0-fix-integration-of-external-track-libraries.patch 16616 BLAKE2B 018fa65eae522ae9fe1d42816614353e7c31c30cfa8685257f72296c115fb5f0e3bab9482ada681200dfacf15c80599f6ecb46868849c1fc412abab2c51a56c6 SHA512 6355e065e29fe433580d685275667681c3c5f10b7153dc4d798db4265593fbf07118ff2e6e6f819919fab11cbb873615ca199289e5a311bd4e4fd9883d5cf66d +AUX mixxx-2.1.0-fix-invocation-args-of-pasuspender.patch 1879 BLAKE2B cc24dcfc530a85c673a26a4794e64d6c71d89785f8550b0d9162aa714221af6a1ceabcbb65340f3c48fb79e6b145f98ef2ef0608f66b75fd06683b3cb8062126 SHA512 42ad3d54cb3450a37ecd36546b0abd5f71481168b25b384f04831555e806dd50dc185e327a923060fe4144209baadb10ee4dda4baad49c6941d26d3a03ca17e8 +AUX mixxx-2.1.0-fix-latenight-group-fx-buttons-in-deck.patch 7213 BLAKE2B 363c23bca079219acbc36b0ccfee8629b12eae797afa4ba76d33ef2f68e7719298a231a5a4a678e37047eefc6cbe1f1fdbd7ae382327aeac64b2caaab9abd87c SHA512 f82b91897512f188d01d65c6f4b38ad77fdf003b5343e9e4a5b9b9bac92f603f8b54f3760286ef8f69476afb1a50e89f6a721a76a7c3e10d77608298e07d9cb4 +AUX mixxx-2.1.0-fix-memory-leak-when-loading-cover-art.patch 1473 BLAKE2B 4f7e59a8f97e36ecc073a2e6755dd44560a96f5f72217034a8ba2cd14f6790ab5d136ed54e2d4c87a2d039143c5804a9f8a9e476045433ab70367e973abdf145 SHA512 555d86b6793dbd4fb09c0c36bb69e31dd7cdceb99b1cdf9362349c6f25a93e3c0a078c4958a2bb3ad9d6329573d84e3ed913a5826a42444b0ec0902310e5cf3e +AUX mixxx-2.1.0-fix-navigation-usability-issues-in-sidebar-tree.patch 15383 BLAKE2B 484df59087aaa09ca4cdfd61bb9236e1d07e9d7bb0d7be0e1bf576e1e546b3a8b10e9aadacb81336d01681612d920cfa28d809ceafc6f2d85a9cde724427b724 SHA512 4a817e0002d99812a092a808587f35adc849b8da8238e420ea7290e1900813374402d526bdabe0d260bf04b39c06051c64db2a41d0b7114c2381955cfb3abf57 +AUX mixxx-2.1.0-fix-s4-mk2-for-windows.patch 2065 BLAKE2B aa36275f3e0fdb08c73408941f7374f5818890d0de119a6992a811f58c5da76ad45d47c5a2e5668eca47131eca12f565b4016c7b8510fb35f6ad03cd429cc0c8 SHA512 196ff5a3769a31b8b1fb264b8a3de1eccdd10c3764a4dd2c4c411ab3d886cd232601b86b119b375c0a08141f86afd8551a4315610cfd39459c3b0cb806246f6e +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-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 2820 BLAKE2B 12603a690707255246a3e9d32882ccdb7a2dc569044f3d5c843a608d43d039af5fd9860cffdd6c5983ff36fa7052826a2f7ddb93ea43a71d9b5aeafd6aaf28ae SHA512 20628c52aaebccedfe343f6502c7c939f16e472b63e95ebb0949e19ecc67164f59675691510ba154d1aecf1eefdd99b81b4d5f2e982d21cb51aee6ac93694e4a +EBUILD mixxx-2.1.0.ebuild 3672 BLAKE2B f9e81050a6ca0cce5ef6c1489f4edd7b519f264a47d093955c5cc56a0cb76816d94637e6cc9be268dbe4e2d8757451dddaa04d0795f5d2e0f2695fe595fdf68f SHA512 c4e1e8366edb994e0a2002f1a83a7e0b6bea7d778ea993f2c0eb85ec07caf4cd95a40dc1597c1f715254722e85f0da52f5844ced4b1fed8b6f6c59bcaf4fdf47 diff --git a/media-sound/mixxx/files/mixxx-2.1.0-debug-assert-and-fix-false-poisitiv-restart-request.patch b/media-sound/mixxx/files/mixxx-2.1.0-debug-assert-and-fix-false-poisitiv-restart-request.patch new file mode 100644 index 0000000..2e1fb6a --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-debug-assert-and-fix-false-poisitiv-restart-request.patch @@ -0,0 +1,127 @@ +From cc34144fbad992f0502db66a7ada7ae16683a81e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= +Date: Mon, 16 Apr 2018 23:41:14 +0200 +Subject: [PATCH 1/2] fix debug assert using empty pixmap source + +--- + src/widget/wpixmapstore.cpp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/widget/wpixmapstore.cpp b/src/widget/wpixmapstore.cpp +index b2648337c0..36d2418d9e 100644 +--- a/src/widget/wpixmapstore.cpp ++++ b/src/widget/wpixmapstore.cpp +@@ -16,6 +16,9 @@ QSharedPointer WPixmapStore::m_loader + PaintablePointer WPixmapStore::getPaintable(PixmapSource source, + Paintable::DrawMode mode, + double scaleFactor) { ++ if (source.isEmpty()) { ++ return PaintablePointer(); ++ } + QString key = source.getId() + QString::number(mode) + QString::number(scaleFactor); + + // See if we have a cached value for the pixmap. + +From 920a00b59b90c36f949d04e8dbbbdf16e3d4364a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= +Date: Tue, 17 Apr 2018 00:10:21 +0200 +Subject: [PATCH 2/2] Fix false postive restart request when changing skin. + +--- + src/preferences/dialog/dlgprefinterface.cpp | 24 +++++------------------- + src/preferences/dialog/dlgprefinterface.h | 2 -- + 2 files changed, 5 insertions(+), 21 deletions(-) + +diff --git a/src/preferences/dialog/dlgprefinterface.cpp b/src/preferences/dialog/dlgprefinterface.cpp +index 02dc8b5b01..95d33da72b 100644 +--- a/src/preferences/dialog/dlgprefinterface.cpp ++++ b/src/preferences/dialog/dlgprefinterface.cpp +@@ -39,13 +39,11 @@ DlgPrefInterface::DlgPrefInterface(QWidget * parent, MixxxMainWindow * mixxx, + // Iterate through the available locales and add them to the combobox + // Borrowed following snippet from http://qt-project.org/wiki/How_to_create_a_multi_language_application + QString translationsFolder = m_pConfig->getResourcePath() + "translations/"; +- QString currentLocale = pConfig->getValueString(ConfigKey("[Config]", "Locale")); + + QDir translationsDir(translationsFolder); + QStringList fileNames = translationsDir.entryList(QStringList("mixxx_*.qm")); + fileNames.push_back("mixxx_en_US.qm"); // add source language as a fake value + +- bool indexFlag = false; // it'll indicate if the selected index changed. + for (int i = 0; i < fileNames.size(); ++i) { + // Extract locale from filename + QString locale = fileNames[i]; +@@ -60,19 +58,9 @@ DlgPrefInterface::DlgPrefInterface(QWidget * parent, MixxxMainWindow * mixxx, + } + lang = QString("%1 (%2)").arg(lang).arg(country); + ComboBoxLocale->addItem(lang, locale); // locale as userdata (for storing to config) +- if (locale == currentLocale) { // Set the currently selected locale +- ComboBoxLocale->setCurrentIndex(ComboBoxLocale->count() - 1); +- indexFlag = true; +- } + } + ComboBoxLocale->model()->sort(0); // Sort languages list +- + ComboBoxLocale->insertItem(0, "System", ""); // System default locale - insert at the top +- if (!indexFlag) { // if selectedIndex didn't change - select system default +- ComboBoxLocale->setCurrentIndex(0); +- } +- connect(ComboBoxLocale, SIGNAL(activated(int)), +- this, SLOT(slotSetLocale(int))); + + // + // Skin configurations +@@ -278,10 +266,6 @@ void DlgPrefInterface::slotResetToDefaults() { + radioButtonKeepMetaknobPosition->setChecked(true); + } + +-void DlgPrefInterface::slotSetLocale(int pos) { +- m_locale = ComboBoxLocale->itemData(pos).toString(); +-} +- + void DlgPrefInterface::slotSetScaleFactor(double newValue) { + // The spinbox shows a percentage, but Mixxx stores a multiplication factor + // with 1.00 as no change. +@@ -345,7 +329,9 @@ void DlgPrefInterface::slotApply() { + m_pConfig->set(ConfigKey("[Config]", "ResizableSkin"), m_skin); + m_pConfig->set(ConfigKey("[Config]", "Scheme"), m_colorScheme); + +- m_pConfig->set(ConfigKey("[Config]", "Locale"), m_locale); ++ QString locale = ComboBoxLocale->itemData( ++ ComboBoxLocale->currentIndex()).toString(); ++ m_pConfig->set(ConfigKey("[Config]", "Locale"), locale); + + m_pConfig->setValue( + ConfigKey("[Config]", "ScaleFactorAuto"), m_bUseAutoScaleFactor); +@@ -373,10 +359,10 @@ void DlgPrefInterface::slotApply() { + static_cast(screensaverComboBoxState)); + } + +- if (m_locale != m_localeOnUpdate) { ++ if (locale != m_localeOnUpdate) { + notifyRebootNecessary(); + // hack to prevent showing the notification when pressing "Okay" after "Apply" +- m_localeOnUpdate = m_locale; ++ m_localeOnUpdate = locale; + } + + if (m_bRebootMixxxView) { +diff --git a/src/preferences/dialog/dlgprefinterface.h b/src/preferences/dialog/dlgprefinterface.h +index 6496d8c148..86a896c940 100644 +--- a/src/preferences/dialog/dlgprefinterface.h ++++ b/src/preferences/dialog/dlgprefinterface.h +@@ -52,7 +52,6 @@ class DlgPrefInterface : public DlgPreferencePage, public Ui::DlgPrefControlsDlg + void slotSetSkin(int); + void slotSetScheme(int); + void slotUpdateSchemes(); +- void slotSetLocale(int); + void slotSetScaleFactor(double newValue); + void slotSetScaleFactorAuto(bool checked); + +@@ -76,7 +75,6 @@ class DlgPrefInterface : public DlgPreferencePage, public Ui::DlgPrefControlsDlg + QString m_skin; + QString m_skinOnUpdate; + QString m_colorScheme; +- QString m_locale; + QString m_localeOnUpdate; + mixxx::TooltipsPreference m_tooltipMode; + double m_dScaleFactorAuto; diff --git a/media-sound/mixxx/files/mixxx-2.1.0-fidlib-thread-safe-and-reentrant-generation-of-filters.patch b/media-sound/mixxx/files/mixxx-2.1.0-fidlib-thread-safe-and-reentrant-generation-of-filters.patch new file mode 100644 index 0000000..1175b2f --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-fidlib-thread-safe-and-reentrant-generation-of-filters.patch @@ -0,0 +1,1209 @@ +From bd7c3322783a69937907ce592fad8f7087ffee05 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Thu, 19 Apr 2018 10:25:25 +0200 +Subject: [PATCH 1/3] Fork Fidlib + +--- + lib/fidlib-0.9.10/CHANGELOG | 4 ++++ + +diff --git a/lib/fidlib-0.9.10/CHANGELOG b/lib/fidlib-0.9.10/CHANGELOG +new file mode 100644 +index 0000000000..103393fe63 +--- /dev/null ++++ b/lib/fidlib-0.9.10/CHANGELOG +@@ -0,0 +1,4 @@ ++************************************************************* ++*** This is a forked and patched version of Fidlib 0.9.10 *** ++************************************************************* ++ + +From 54e0656f00b23802b5a89c9a561e208c9cfcba80 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Thu, 19 Apr 2018 10:29:10 +0200 +Subject: [PATCH 2/3] Thread-safe invocation of code for generating filters + +--- + lib/fidlib-0.9.10/CHANGELOG | 2 + + lib/fidlib-0.9.10/fidlib.c | 192 +++++++++++++++----------- + lib/fidlib-0.9.10/fidmkf.h | 375 ++++++++++++++++++++++++++------------------------- + 3 files changed, 301 insertions(+), 268 deletions(-) + +diff --git a/lib/fidlib-0.9.10/CHANGELOG b/lib/fidlib-0.9.10/CHANGELOG +index 103393fe63..34c84a6905 100644 +--- a/lib/fidlib-0.9.10/CHANGELOG ++++ b/lib/fidlib-0.9.10/CHANGELOG +@@ -2,3 +2,5 @@ + *** This is a forked and patched version of Fidlib 0.9.10 *** + ************************************************************* + ++* Thu Apr 19 2018 Uwe Klotz ++- Thread-safe invocation of code for generating filters +diff --git a/lib/fidlib-0.9.10/fidlib.c b/lib/fidlib-0.9.10/fidlib.c +index f5c46a011b..8dcef23b01 100644 +--- a/lib/fidlib-0.9.10/fidlib.c ++++ b/lib/fidlib-0.9.10/fidlib.c +@@ -758,41 +758,41 @@ search_peak(FidFilter *ff, double f0, double f3) { + #define MZ 1 + + static FidFilter* +-do_lowpass(int mz, double freq) { ++do_lowpass(struct mk_filter_context* ctx, int mz, double freq) { + FidFilter *rv; +- lowpass(prewarp(freq)); +- if (mz) s2z_matchedZ(); else s2z_bilinear(); +- rv= z2fidfilter(1.0, ~0); // FIR is constant ++ lowpass(ctx, prewarp(freq)); ++ if (mz) s2z_matchedZ(ctx); else s2z_bilinear(ctx); ++ rv= z2fidfilter(ctx, 1.0, ~0); // FIR is constant + rv->val[0]= 1.0 / fid_response(rv, 0.0); + return rv; + } + + static FidFilter* +-do_highpass(int mz, double freq) { ++do_highpass(struct mk_filter_context* ctx, int mz, double freq) { + FidFilter *rv; +- highpass(prewarp(freq)); +- if (mz) s2z_matchedZ(); else s2z_bilinear(); +- rv= z2fidfilter(1.0, ~0); // FIR is constant ++ highpass(ctx, prewarp(freq)); ++ if (mz) s2z_matchedZ(ctx); else s2z_bilinear(ctx); ++ rv= z2fidfilter(ctx, 1.0, ~0); // FIR is constant + rv->val[0]= 1.0 / fid_response(rv, 0.5); + return rv; + } + + static FidFilter* +-do_bandpass(int mz, double f0, double f1) { ++do_bandpass(struct mk_filter_context* ctx, int mz, double f0, double f1) { + FidFilter *rv; +- bandpass(prewarp(f0), prewarp(f1)); +- if (mz) s2z_matchedZ(); else s2z_bilinear(); +- rv= z2fidfilter(1.0, ~0); // FIR is constant ++ bandpass(ctx, prewarp(f0), prewarp(f1)); ++ if (mz) s2z_matchedZ(ctx); else s2z_bilinear(ctx); ++ rv= z2fidfilter(ctx, 1.0, ~0); // FIR is constant + rv->val[0]= 1.0 / fid_response(rv, search_peak(rv, f0, f1)); + return rv; + } + + static FidFilter* +-do_bandstop(int mz, double f0, double f1) { ++do_bandstop(struct mk_filter_context* ctx, int mz, double f0, double f1) { + FidFilter *rv; +- bandstop(prewarp(f0), prewarp(f1)); +- if (mz) s2z_matchedZ(); else s2z_bilinear(); +- rv= z2fidfilter(1.0, 5); // FIR second coefficient is *non-const* for bandstop ++ bandstop(ctx, prewarp(f0), prewarp(f1)); ++ if (mz) s2z_matchedZ(ctx); else s2z_bilinear(ctx); ++ rv= z2fidfilter(ctx, 1.0, 5); // FIR second coefficient is *non-const* for bandstop + rv->val[0]= 1.0 / fid_response(rv, 0.0); // Use 0Hz response as reference + return rv; + } +@@ -829,8 +829,9 @@ des_bpre(double rate, double f0, double f1, int order, int n_arg, double *arg) { + (void)f1; + (void)order; + (void)n_arg; +- bandpass_res(f0, arg[0]); +- return z2fidfilter(1.0, ~0); // FIR constant ++ struct mk_filter_context ctx; ++ bandpass_res(&ctx, f0, arg[0]); ++ return z2fidfilter(&ctx, 1.0, ~0); // FIR constant + } + + static FidFilter* +@@ -839,8 +840,9 @@ des_bsre(double rate, double f0, double f1, int order, int n_arg, double *arg) { + (void)f1; + (void)order; + (void)n_arg; +- bandstop_res(f0, arg[0]); +- return z2fidfilter(1.0, 0); // FIR not constant, depends on freq ++ struct mk_filter_context ctx; ++ bandstop_res(&ctx, f0, arg[0]); ++ return z2fidfilter(&ctx, 1.0, 0); // FIR not constant, depends on freq + } + + static FidFilter* +@@ -849,8 +851,9 @@ des_apre(double rate, double f0, double f1, int order, int n_arg, double *arg) { + (void)f1; + (void)order; + (void)n_arg; +- allpass_res(f0, arg[0]); +- return z2fidfilter(1.0, 0); // FIR not constant, depends on freq ++ struct mk_filter_context ctx; ++ allpass_res(&ctx, f0, arg[0]); ++ return z2fidfilter(&ctx, 1.0, 0); // FIR not constant, depends on freq + } + + static FidFilter* +@@ -860,9 +863,10 @@ des_pi(double rate, double f0, double f1, int order, int n_arg, double *arg) { + (void)order; + (void)n_arg; + (void)arg; +- prop_integral(prewarp(f0)); +- s2z_bilinear(); +- return z2fidfilter(1.0, 0); // FIR not constant, depends on freq ++ struct mk_filter_context ctx; ++ prop_integral(&ctx, prewarp(f0)); ++ s2z_bilinear(&ctx); ++ return z2fidfilter(&ctx, 1.0, 0); // FIR not constant, depends on freq + } + + static FidFilter* +@@ -872,9 +876,10 @@ des_piz(double rate, double f0, double f1, int order, int n_arg, double *arg) { + (void)order; + (void)n_arg; + (void)arg; +- prop_integral(prewarp(f0)); +- s2z_matchedZ(); +- return z2fidfilter(1.0, 0); // FIR not constant, depends on freq ++ struct mk_filter_context ctx; ++ prop_integral(&ctx, prewarp(f0)); ++ s2z_matchedZ(&ctx); ++ return z2fidfilter(&ctx, 1.0, 0); // FIR not constant, depends on freq + } + + static FidFilter* +@@ -883,8 +888,9 @@ des_lpbe(double rate, double f0, double f1, int order, int n_arg, double *arg) { + (void)f1; + (void)n_arg; + (void)arg; +- bessel(order); +- return do_lowpass(BL, f0); ++ struct mk_filter_context ctx; ++ bessel(&ctx, order); ++ return do_lowpass(&ctx, BL, f0); + } + + static FidFilter* +@@ -893,8 +899,9 @@ des_hpbe(double rate, double f0, double f1, int order, int n_arg, double *arg) { + (void)f1; + (void)n_arg; + (void)arg; +- bessel(order); +- return do_highpass(BL, f0); ++ struct mk_filter_context ctx; ++ bessel(&ctx, order); ++ return do_highpass(&ctx, BL, f0); + } + + static FidFilter* +@@ -902,8 +909,9 @@ des_bpbe(double rate, double f0, double f1, int order, int n_arg, double *arg) { + (void)rate; + (void)n_arg; + (void)arg; +- bessel(order); +- return do_bandpass(BL, f0, f1); ++ struct mk_filter_context ctx; ++ bessel(&ctx, order); ++ return do_bandpass(&ctx, BL, f0, f1); + } + + static FidFilter* +@@ -911,8 +919,9 @@ des_bsbe(double rate, double f0, double f1, int order, int n_arg, double *arg) { + (void)rate; + (void)n_arg; + (void)arg; +- bessel(order); +- return do_bandstop(BL, f0, f1); ++ struct mk_filter_context ctx; ++ bessel(&ctx, order); ++ return do_bandstop(&ctx, BL, f0, f1); + } + + static FidFilter* +@@ -921,8 +930,9 @@ des_lpbez(double rate, double f0, double f1, int order, int n_arg, double *arg) + (void)f1; + (void)n_arg; + (void)arg; +- bessel(order); +- return do_lowpass(MZ, f0); ++ struct mk_filter_context ctx; ++ bessel(&ctx, order); ++ return do_lowpass(&ctx, MZ, f0); + } + + static FidFilter* +@@ -931,8 +941,9 @@ des_hpbez(double rate, double f0, double f1, int order, int n_arg, double *arg) + (void)f1; + (void)n_arg; + (void)arg; +- bessel(order); +- return do_highpass(MZ, f0); ++ struct mk_filter_context ctx; ++ bessel(&ctx, order); ++ return do_highpass(&ctx, MZ, f0); + } + + static FidFilter* +@@ -940,8 +951,9 @@ des_bpbez(double rate, double f0, double f1, int order, int n_arg, double *arg) + (void)rate; + (void)n_arg; + (void)arg; +- bessel(order); +- return do_bandpass(MZ, f0, f1); ++ struct mk_filter_context ctx; ++ bessel(&ctx, order); ++ return do_bandpass(&ctx, MZ, f0, f1); + } + + static FidFilter* +@@ -949,8 +961,9 @@ des_bsbez(double rate, double f0, double f1, int order, int n_arg, double *arg) + (void)rate; + (void)n_arg; + (void)arg; +- bessel(order); +- return do_bandstop(MZ, f0, f1); ++ struct mk_filter_context ctx; ++ bessel(&ctx, order); ++ return do_bandstop(&ctx, MZ, f0, f1); + } + + static FidFilter* // Butterworth-Bessel cross +@@ -960,11 +973,12 @@ des_lpbube(double rate, double f0, double f1, int order, int n_arg, double *arg) + (void)n_arg; + double tmp[MAXPZ]; + int a; +- bessel(order); memcpy(tmp, pol, order * sizeof(double)); +- butterworth(order); +- for (a= 0; a 10) error("Maximum Bessel order is 10"); +- n_pol= order; +- memcpy(pol, bessel_poles[order-1], n_pol * sizeof(double)); ++ ctx->n_pol= order; ++ memcpy(ctx->pol, bessel_poles[order-1], ctx->n_pol * sizeof(double)); + + for (a= 0; apoltyp[a++]= 2; ++ ctx->poltyp[a++]= 0; + } + if (a < order) +- poltyp[a++]= 1; ++ ctx->poltyp[a++]= 1; + } + + // +@@ -325,19 +326,19 @@ bessel(int order) { + // + + static void +-butterworth(int order) { ++butterworth(struct mk_filter_context* ctx, int order) { + int a; + if (order > MAXPZ) + error("Maximum butterworth/chebyshev order is %d", MAXPZ); +- n_pol= order; ++ ctx->n_pol= order; + for (a= 0; apoltyp[a]= 2; ++ ctx->poltyp[a+1]= 0; ++ cexpj(ctx->pol+a, M_PI - (order-a-1) * 0.5 * M_PI / order); + } + if (a < order) { +- poltyp[a]= 1; +- pol[a]= -1.0; ++ ctx->poltyp[a]= 1; ++ ctx->pol[a]= -1.0; + } + } + +@@ -346,12 +347,12 @@ butterworth(int order) { + // + + static void +-chebyshev(int order, double ripple) { ++chebyshev(struct mk_filter_context* ctx, int order, double ripple) { + double eps, y; + double sh, ch; + int a; + +- butterworth(order); ++ butterworth(ctx, order); + if (ripple >= 0.0) error("Chebyshev ripple in dB should be -ve"); + + eps= sqrt(-1.0 + pow(10.0, -0.1 * ripple)); +@@ -360,12 +361,12 @@ chebyshev(int order, double ripple) { + sh= sinh(y); + ch= cosh(y); + +- for (a= 0; an_pol; ) { ++ if (ctx->poltyp[a] == 1) ++ ctx->pol[a++] *= sh; + else { +- pol[a++] *= sh; +- pol[a++] *= ch; ++ ctx->pol[a++] *= sh; ++ ctx->pol[a++] *= ch; + } + } + } +@@ -376,19 +377,19 @@ chebyshev(int order, double ripple) { + // + + static void +-lowpass(double freq) { ++lowpass(struct mk_filter_context* ctx, double freq) { + int a; + + // Adjust poles + freq *= TWOPI; +- for (a= 0; an_pol; a++) ++ ctx->pol[a] *= freq; + + // Add zeros +- n_zer= n_pol; +- for (a= 0; an_zer= ctx->n_pol; ++ for (a= 0; an_zer; a++) { ++ ctx->zer[a]= -INF; ++ ctx->zertyp[a]= 1; + } + } + +@@ -397,27 +398,27 @@ lowpass(double freq) { + // + + static void +-highpass(double freq) { ++highpass(struct mk_filter_context* ctx, double freq) { + int a; + + // Adjust poles + freq *= TWOPI; +- for (a= 0; an_pol; ) { ++ if (ctx->poltyp[a] == 1) { ++ ctx->pol[a]= freq / ctx->pol[a]; + a++; + } else { +- crecip(pol + a); +- pol[a++] *= freq; +- pol[a++] *= freq; ++ crecip(ctx->pol + a); ++ ctx->pol[a++] *= freq; ++ ctx->pol[a++] *= freq; + } + } + + // Add zeros +- n_zer= n_pol; +- for (a= 0; an_zer= ctx->n_pol; ++ for (a= 0; an_zer; a++) { ++ ctx->zer[a]= 0.0; ++ ctx->zertyp[a]= 1; + } + } + +@@ -427,58 +428,58 @@ highpass(double freq) { + // + + static void +-bandpass(double freq1, double freq2) { ++bandpass(struct mk_filter_context* ctx, double freq1, double freq2) { + double w0= TWOPI * sqrt(freq1*freq2); + double bw= 0.5 * TWOPI * (freq2-freq1); + int a, b; + +- if (n_pol * 2 > MAXPZ) ++ if (ctx->n_pol * 2 > MAXPZ) + error("Maximum order for bandpass filters is %d", MAXPZ/2); + + // Run through the list backwards, expanding as we go +- for (a= n_pol, b= n_pol*2; a>0; ) { ++ for (a= ctx->n_pol, b= ctx->n_pol*2; a>0; ) { + // hba= pole * bw; + // temp= c_sqrt(1.0 - square(w0 / hba)); + // pole1= hba * (1.0 + temp); + // pole2= hba * (1.0 - temp); + +- if (poltyp[a-1] == 1) { ++ if (ctx->poltyp[a-1] == 1) { + double hba; + a--; b -= 2; +- poltyp[b]= 2; poltyp[b+1]= 0; +- hba= pol[a] * bw; +- cassz(pol+b, 1.0 - (w0 / hba) * (w0 / hba), 0.0); +- c_sqrt(pol+b); +- caddz(pol+b, 1.0, 0.0); +- cmulr(pol+b, hba); ++ ctx->poltyp[b]= 2; ctx->poltyp[b+1]= 0; ++ hba= ctx->pol[a] * bw; ++ cassz(ctx->pol+b, 1.0 - (w0 / hba) * (w0 / hba), 0.0); ++ c_sqrt(ctx->pol+b); ++ caddz(ctx->pol+b, 1.0, 0.0); ++ cmulr(ctx->pol+b, hba); + } else { // Assume poltyp[] data is valid + double hba[2]; + a -= 2; b -= 4; +- poltyp[b]= 2; poltyp[b+1]= 0; +- poltyp[b+2]= 2; poltyp[b+3]= 0; +- cass(hba, pol+a); ++ ctx->poltyp[b]= 2; ctx->poltyp[b+1]= 0; ++ ctx->poltyp[b+2]= 2; ctx->poltyp[b+3]= 0; ++ cass(hba, ctx->pol+a); + cmulr(hba, bw); +- cass(pol+b, hba); +- crecip(pol+b); +- cmulr(pol+b, w0); +- csqu(pol+b); +- cneg(pol+b); +- caddz(pol+b, 1.0, 0.0); +- c_sqrt(pol+b); +- cmul(pol+b, hba); +- cass(pol+b+2, pol+b); +- cneg(pol+b+2); +- cadd(pol+b, hba); +- cadd(pol+b+2, hba); ++ cass(ctx->pol+b, hba); ++ crecip(ctx->pol+b); ++ cmulr(ctx->pol+b, w0); ++ csqu(ctx->pol+b); ++ cneg(ctx->pol+b); ++ caddz(ctx->pol+b, 1.0, 0.0); ++ c_sqrt(ctx->pol+b); ++ cmul(ctx->pol+b, hba); ++ cass(ctx->pol+b+2, ctx->pol+b); ++ cneg(ctx->pol+b+2); ++ cadd(ctx->pol+b, hba); ++ cadd(ctx->pol+b+2, hba); + } + } +- n_pol *= 2; ++ ctx->n_pol *= 2; + + // Add zeros +- n_zer= n_pol; +- for (a= 0; an_zer= ctx->n_pol; ++ for (a= 0; an_zer; a++) { ++ ctx->zertyp[a]= 1; ++ ctx->zer[a]= (an_zer/2) ? 0.0 : -INF; + } + } + +@@ -488,59 +489,59 @@ bandpass(double freq1, double freq2) { + // + + static void +-bandstop(double freq1, double freq2) { ++bandstop(struct mk_filter_context* ctx, double freq1, double freq2) { + double w0= TWOPI * sqrt(freq1*freq2); + double bw= 0.5 * TWOPI * (freq2-freq1); + int a, b; + +- if (n_pol * 2 > MAXPZ) ++ if (ctx->n_pol * 2 > MAXPZ) + error("Maximum order for bandstop filters is %d", MAXPZ/2); + + // Run through the list backwards, expanding as we go +- for (a= n_pol, b= n_pol*2; a>0; ) { ++ for (a= ctx->n_pol, b= ctx->n_pol*2; a>0; ) { + // hba= bw / pole; + // temp= c_sqrt(1.0 - square(w0 / hba)); + // pole1= hba * (1.0 + temp); + // pole2= hba * (1.0 - temp); + +- if (poltyp[a-1] == 1) { ++ if (ctx->poltyp[a-1] == 1) { + double hba; + a--; b -= 2; +- poltyp[b]= 2; poltyp[b+1]= 0; +- hba= bw / pol[a]; +- cassz(pol+b, 1.0 - (w0 / hba) * (w0 / hba), 0.0); +- c_sqrt(pol+b); +- caddz(pol+b, 1.0, 0.0); +- cmulr(pol+b, hba); ++ ctx->poltyp[b]= 2; ctx->poltyp[b+1]= 0; ++ hba= bw / ctx->pol[a]; ++ cassz(ctx->pol+b, 1.0 - (w0 / hba) * (w0 / hba), 0.0); ++ c_sqrt(ctx->pol+b); ++ caddz(ctx->pol+b, 1.0, 0.0); ++ cmulr(ctx->pol+b, hba); + } else { // Assume poltyp[] data is valid + double hba[2]; + a -= 2; b -= 4; +- poltyp[b]= 2; poltyp[b+1]= 0; +- poltyp[b+2]= 2; poltyp[b+3]= 0; +- cass(hba, pol+a); ++ ctx->poltyp[b]= 2; ctx->poltyp[b+1]= 0; ++ ctx->poltyp[b+2]= 2; ctx->poltyp[b+3]= 0; ++ cass(hba, ctx->pol+a); + crecip(hba); + cmulr(hba, bw); +- cass(pol+b, hba); +- crecip(pol+b); +- cmulr(pol+b, w0); +- csqu(pol+b); +- cneg(pol+b); +- caddz(pol+b, 1.0, 0.0); +- c_sqrt(pol+b); +- cmul(pol+b, hba); +- cass(pol+b+2, pol+b); +- cneg(pol+b+2); +- cadd(pol+b, hba); +- cadd(pol+b+2, hba); ++ cass(ctx->pol+b, hba); ++ crecip(ctx->pol+b); ++ cmulr(ctx->pol+b, w0); ++ csqu(ctx->pol+b); ++ cneg(ctx->pol+b); ++ caddz(ctx->pol+b, 1.0, 0.0); ++ c_sqrt(ctx->pol+b); ++ cmul(ctx->pol+b, hba); ++ cass(ctx->pol+b+2, ctx->pol+b); ++ cneg(ctx->pol+b+2); ++ cadd(ctx->pol+b, hba); ++ cadd(ctx->pol+b+2, hba); + } + } +- n_pol *= 2; ++ ctx->n_pol *= 2; + + // Add zeros +- n_zer= n_pol; +- for (a= 0; an_zer= ctx->n_pol; ++ for (a= 0; an_zer; a+=2) { ++ ctx->zertyp[a]= 2; ctx->zertyp[a+1]= 0; ++ ctx->zer[a]= 0.0; ctx->zer[a+1]= w0; + } + } + +@@ -550,41 +551,41 @@ bandstop(double freq1, double freq2) { + // + + static void +-s2z_bilinear() { ++s2z_bilinear(struct mk_filter_context* ctx) { + int a; +- for (a= 0; an_pol; ) { + // Calculate (2 + val) / (2 - val) +- if (poltyp[a] == 1) { +- if (pol[a] == -INF) +- pol[a]= -1.0; ++ if (ctx->poltyp[a] == 1) { ++ if (ctx->pol[a] == -INF) ++ ctx->pol[a]= -1.0; + else +- pol[a]= (2 + pol[a]) / (2 - pol[a]); ++ ctx->pol[a]= (2 + ctx->pol[a]) / (2 - ctx->pol[a]); + a++; + } else { + double val[2]; +- cass(val, pol+a); ++ cass(val, ctx->pol+a); + cneg(val); + caddz(val, 2, 0); +- caddz(pol+a, 2, 0); +- cdiv(pol+a, val); ++ caddz(ctx->pol+a, 2, 0); ++ cdiv(ctx->pol+a, val); + a += 2; + } + } +- for (a= 0; an_zer; ) { + // Calculate (2 + val) / (2 - val) +- if (zertyp[a] == 1) { +- if (zer[a] == -INF) +- zer[a]= -1.0; ++ if (ctx->zertyp[a] == 1) { ++ if (ctx->zer[a] == -INF) ++ ctx->zer[a]= -1.0; + else +- zer[a]= (2 + zer[a]) / (2 - zer[a]); ++ ctx->zer[a]= (2 + ctx->zer[a]) / (2 - ctx->zer[a]); + a++; + } else { + double val[2]; +- cass(val, zer+a); ++ cass(val, ctx->zer+a); + cneg(val); + caddz(val, 2, 0); +- caddz(zer+a, 2, 0); +- cdiv(zer+a, val); ++ caddz(ctx->zer+a, 2, 0); ++ cdiv(ctx->zer+a, val); + a += 2; + } + } +@@ -595,33 +596,33 @@ s2z_bilinear() { + // + + static void +-s2z_matchedZ() { ++s2z_matchedZ(struct mk_filter_context* ctx) { + int a; + +- for (a= 0; an_pol; ) { + // Calculate cexp(val) +- if (poltyp[a] == 1) { +- if (pol[a] == -INF) +- pol[a]= 0.0; ++ if (ctx->poltyp[a] == 1) { ++ if (ctx->pol[a] == -INF) ++ ctx->pol[a]= 0.0; + else +- pol[a]= exp(pol[a]); ++ ctx->pol[a]= exp(ctx->pol[a]); + a++; + } else { +- c_exp(pol+a); ++ c_exp(ctx->pol+a); + a += 2; + } + } + +- for (a= 0; an_zer; ) { + // Calculate cexp(val) +- if (zertyp[a] == 1) { +- if (zer[a] == -INF) +- zer[a]= 0.0; ++ if (ctx->zertyp[a] == 1) { ++ if (ctx->zer[a] == -INF) ++ ctx->zer[a]= 0.0; + else +- zer[a]= exp(zer[a]); ++ ctx->zer[a]= exp(ctx->zer[a]); + a++; + } else { +- c_exp(zer+a); ++ c_exp(ctx->zer+a); + a += 2; + } + } +@@ -645,14 +646,14 @@ s2z_matchedZ() { + // + + static FidFilter* +-z2fidfilter(double gain, int cbm) { ++z2fidfilter(struct mk_filter_context* ctx, double gain, int cbm) { + int n_head, n_val; + int a; + FidFilter *rv; + FidFilter *ff; + +- n_head= 1 + n_pol + n_zer; // Worst case: gain + 2-element IIR/FIR +- n_val= 1 + 2 * (n_pol+n_zer); // for each pole/zero ++ n_head= 1 + ctx->n_pol + ctx->n_zer; // Worst case: gain + 2-element IIR/FIR ++ n_val= 1 + 2 * (ctx->n_pol+ctx->n_zer); // for each pole/zero + + rv= ff= FFALLOC(n_head, n_val); + +@@ -662,49 +663,49 @@ z2fidfilter(double gain, int cbm) { + ff= FFNEXT(ff); + + // Output as much as possible as 2x2 IIR/FIR filters +- for (a= 0; a <= n_pol-2 && a <= n_zer-2; a += 2) { ++ for (a= 0; a <= ctx->n_pol-2 && a <= ctx->n_zer-2; a += 2) { + // Look for a pair of values for an IIR +- if (poltyp[a] == 1 && poltyp[a+1] == 1) { ++ if (ctx->poltyp[a] == 1 && ctx->poltyp[a+1] == 1) { + // Two real values + ff->typ= 'I'; + ff->len= 3; + ff->val[0]= 1; +- ff->val[1]= -(pol[a] + pol[a+1]); +- ff->val[2]= pol[a] * pol[a+1]; ++ ff->val[1]= -(ctx->pol[a] + ctx->pol[a+1]); ++ ff->val[2]= ctx->pol[a] * ctx->pol[a+1]; + ff= FFNEXT(ff); +- } else if (poltyp[a] == 2) { ++ } else if (ctx->poltyp[a] == 2) { + // A complex value and its conjugate pair + ff->typ= 'I'; + ff->len= 3; + ff->val[0]= 1; +- ff->val[1]= -2 * pol[a]; +- ff->val[2]= pol[a] * pol[a] + pol[a+1] * pol[a+1]; ++ ff->val[1]= -2 * ctx->pol[a]; ++ ff->val[2]= ctx->pol[a] * ctx->pol[a] + ctx->pol[a+1] * ctx->pol[a+1]; + ff= FFNEXT(ff); + } else error("Internal error -- bad poltyp[] values for z2fidfilter()"); + + // Look for a pair of values for an FIR +- if (zertyp[a] == 1 && zertyp[a+1] == 1) { ++ if (ctx->zertyp[a] == 1 && ctx->zertyp[a+1] == 1) { + // Two real values + // Skip if constant and 0/0 +- if (!cbm || zer[a] != 0.0 || zer[a+1] != 0.0) { ++ if (!cbm || ctx->zer[a] != 0.0 || ctx->zer[a+1] != 0.0) { + ff->typ= 'F'; + ff->cbm= cbm; + ff->len= 3; + ff->val[0]= 1; +- ff->val[1]= -(zer[a] + zer[a+1]); +- ff->val[2]= zer[a] * zer[a+1]; ++ ff->val[1]= -(ctx->zer[a] + ctx->zer[a+1]); ++ ff->val[2]= ctx->zer[a] * ctx->zer[a+1]; + ff= FFNEXT(ff); + } +- } else if (zertyp[a] == 2) { ++ } else if (ctx->zertyp[a] == 2) { + // A complex value and its conjugate pair + // Skip if constant and 0/0 +- if (!cbm || zer[a] != 0.0 || zer[a+1] != 0.0) { ++ if (!cbm || ctx->zer[a] != 0.0 || ctx->zer[a+1] != 0.0) { + ff->typ= 'F'; + ff->cbm= cbm; + ff->len= 3; + ff->val[0]= 1; +- ff->val[1]= -2 * zer[a]; +- ff->val[2]= zer[a] * zer[a] + zer[a+1] * zer[a+1]; ++ ff->val[1]= -2 * ctx->zer[a]; ++ ff->val[2]= ctx->zer[a] * ctx->zer[a] + ctx->zer[a+1] * ctx->zer[a+1]; + ff= FFNEXT(ff); + } + } else error("Internal error -- bad zertyp[] values"); +@@ -712,24 +713,24 @@ z2fidfilter(double gain, int cbm) { + + // Clear up any remaining bits and pieces. Should only be a 1x1 + // IIR/FIR. +- if (n_pol-a == 0 && n_zer-a == 0) ++ if (ctx->n_pol-a == 0 && ctx->n_zer-a == 0) + ; +- else if (n_pol-a == 1 && n_zer-a == 1) { +- if (poltyp[a] != 1 || zertyp[a] != 1) ++ else if (ctx->n_pol-a == 1 && ctx->n_zer-a == 1) { ++ if (ctx->poltyp[a] != 1 || ctx->zertyp[a] != 1) + error("Internal error; bad poltyp or zertyp for final pole/zero"); + ff->typ= 'I'; + ff->len= 2; + ff->val[0]= 1; +- ff->val[1]= -pol[a]; ++ ff->val[1]= -ctx->pol[a]; + ff= FFNEXT(ff); + + // Skip FIR if it is constant and zero +- if (!cbm || zer[a] != 0.0) { ++ if (!cbm || ctx->zer[a] != 0.0) { + ff->typ= 'F'; + ff->cbm= cbm; + ff->len= 2; + ff->val[0]= 1; +- ff->val[1]= -zer[a]; ++ ff->val[1]= -ctx->zer[a]; + ff= FFNEXT(ff); + } + } else +@@ -752,7 +753,7 @@ z2fidfilter(double gain, int cbm) { + // + + static void +-bandpass_res(double freq, double qfact) { ++bandpass_res(struct mk_filter_context* ctx, double freq, double qfact) { + double mag; + double th0, th1, th2; + double theta= freq * TWOPI; +@@ -760,14 +761,14 @@ bandpass_res(double freq, double qfact) { + double tmp1[2], tmp2[2], tmp3[2], tmp4[2]; + int cnt; + +- n_pol= 2; +- poltyp[0]= 2; poltyp[1]= 0; +- n_zer= 2; +- zertyp[0]= 1; zertyp[1]= 1; +- zer[0]= 1; zer[1]= -1; ++ ctx->n_pol= 2; ++ ctx->poltyp[0]= 2; ctx->poltyp[1]= 0; ++ ctx->n_zer= 2; ++ ctx->zertyp[0]= 1; ctx->zertyp[1]= 1; ++ ctx->zer[0]= 1; ctx->zer[1]= -1; + + if (qfact == 0.0) { +- cexpj(pol, theta); ++ cexpj(ctx->pol, theta); + return; + } + +@@ -777,8 +778,8 @@ bandpass_res(double freq, double qfact) { + th0= 0; th2= M_PI; + for (cnt= 60; cnt > 0; cnt--) { + th1= 0.5 * (th0 + th2); +- cexpj(pol, th1); +- cmulr(pol, mag); ++ cexpj(ctx->pol, th1); ++ cmulr(ctx->pol, mag); + + // Evaluate response of filter for Z= val + memcpy(tmp1, val, 2*sizeof(double)); +@@ -788,8 +789,8 @@ bandpass_res(double freq, double qfact) { + csubz(tmp1, 1, 0); + csubz(tmp2, -1, 0); + cmul(tmp1, tmp2); +- csub(tmp3, pol); cconj(pol); +- csub(tmp4, pol); cconj(pol); ++ csub(tmp3, ctx->pol); cconj(ctx->pol); ++ csub(tmp4, ctx->pol); cconj(ctx->pol); + cmul(tmp3, tmp4); + cdiv(tmp1, tmp3); + +@@ -809,10 +810,10 @@ bandpass_res(double freq, double qfact) { + // + + static void +-bandstop_res(double freq, double qfact) { +- bandpass_res(freq, qfact); +- zertyp[0]= 2; zertyp[1]= 0; +- cexpj(zer, TWOPI * freq); ++bandstop_res(struct mk_filter_context* ctx, double freq, double qfact) { ++ bandpass_res(ctx, freq, qfact); ++ ctx->zertyp[0]= 2; ctx->zertyp[1]= 0; ++ cexpj(ctx->zer, TWOPI * freq); + } + + // +@@ -820,11 +821,11 @@ bandstop_res(double freq, double qfact) { + // + + static void +-allpass_res(double freq, double qfact) { +- bandpass_res(freq, qfact); +- zertyp[0]= 2; zertyp[1]= 0; +- memcpy(zer, pol, 2*sizeof(double)); +- cmulr(zer, 1.0 / (zer[0]*zer[0] + zer[1]*zer[1])); ++allpass_res(struct mk_filter_context* ctx, double freq, double qfact) { ++ bandpass_res(ctx, freq, qfact); ++ ctx->zertyp[0]= 2; ctx->zertyp[1]= 0; ++ memcpy(ctx->zer, ctx->pol, 2*sizeof(double)); ++ cmulr(ctx->zer, 1.0 / (ctx->zer[0]*ctx->zer[0] + ctx->zer[1]*ctx->zer[1])); + } + + // +@@ -832,13 +833,13 @@ allpass_res(double freq, double qfact) { + // + + static void +-prop_integral(double freq) { +- n_pol= 1; +- poltyp[0]= 1; +- pol[0]= 0.0; +- n_zer= 1; +- zertyp[0]= 1; +- zer[0]= -TWOPI * freq; ++prop_integral(struct mk_filter_context* ctx, double freq) { ++ ctx->n_pol= 1; ++ ctx->poltyp[0]= 1; ++ ctx->pol[0]= 0.0; ++ ctx->n_zer= 1; ++ ctx->zertyp[0]= 1; ++ ctx->zer[0]= -TWOPI * freq; + } + + // END // + +From 470bbff17674bceab7244b118fd1c3d30b1b8bdc Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Thu, 19 Apr 2018 10:34:10 +0200 +Subject: [PATCH 3/3] Fix compiler warnings + +--- + lib/fidlib-0.9.10/CHANGELOG | 1 + + lib/fidlib-0.9.10/fidrf_cmdlist.h | 8 +++++--- + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/lib/fidlib-0.9.10/CHANGELOG b/lib/fidlib-0.9.10/CHANGELOG +index 34c84a6905..831de46ee3 100644 +--- a/lib/fidlib-0.9.10/CHANGELOG ++++ b/lib/fidlib-0.9.10/CHANGELOG +@@ -4,3 +4,4 @@ + + * Thu Apr 19 2018 Uwe Klotz + - Thread-safe invocation of code for generating filters ++- Fix compiler warnings +diff --git a/lib/fidlib-0.9.10/fidrf_cmdlist.h b/lib/fidlib-0.9.10/fidrf_cmdlist.h +index f45ee296e8..d0721d3c9f 100644 +--- a/lib/fidlib-0.9.10/fidrf_cmdlist.h ++++ b/lib/fidlib-0.9.10/fidrf_cmdlist.h +@@ -235,7 +235,9 @@ fid_run_new(FidFilter *filt, double (**funcpp)(void *,double)) { + + // Generate command and coefficient lists + while (filt->len) { +- int n_iir, n_fir, cnt; ++ int n_fir = 0; ++ int n_iir = 0; ++ int cnt; + double *iir, *fir; + double adj; + if (filt->typ == 'F' && filt->len == 1) { +@@ -244,12 +246,12 @@ fid_run_new(FidFilter *filt, double (**funcpp)(void *,double)) { + continue; + } + if (filt->typ == 'F') { +- iir= 0; n_iir= 0; ++ iir= 0; + fir= filt->val; n_fir= filt->len; + filt= FFNEXT(filt); + } else if (filt->typ == 'I') { + iir= filt->val; n_iir= filt->len; +- fir= 0; n_fir= 0; ++ fir= 0; + filt= FFNEXT(filt); + while (filt->typ == 'F' && filt->len == 1) { + gain *= filt->val[0]; diff --git a/media-sound/mixxx/files/mixxx-2.1.0-fix-clearing-of-replaygain-gain-ratio-in-file-tags.patch b/media-sound/mixxx/files/mixxx-2.1.0-fix-clearing-of-replaygain-gain-ratio-in-file-tags.patch new file mode 100644 index 0000000..30a5aa7 --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-fix-clearing-of-replaygain-gain-ratio-in-file-tags.patch @@ -0,0 +1,152 @@ +From 0a0e41dd330e34f155c455c2c938a484aeb465f5 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Sun, 22 Apr 2018 21:58:24 +0200 +Subject: [PATCH 1/2] Remove unused parameter + +...but keep in in the innermost function with a default value for +readability and documentation purposes. +--- + src/track/trackmetadatataglib.cpp | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/src/track/trackmetadatataglib.cpp b/src/track/trackmetadatataglib.cpp +index 17e34b5196..f54724eab5 100644 +--- a/src/track/trackmetadatataglib.cpp ++++ b/src/track/trackmetadatataglib.cpp +@@ -492,9 +492,8 @@ TagLib::ID3v2::CommentsFrame* findFirstCommentsFrame( + } + + TagLib::ID3v2::CommentsFrame* findFirstCommentsFrameWithoutDescription( +- const TagLib::ID3v2::Tag& tag, +- bool preferNotEmpty = true) { +- return findFirstCommentsFrame(tag, QString(), preferNotEmpty); ++ const TagLib::ID3v2::Tag& tag) { ++ return findFirstCommentsFrame(tag, QString()); + } + + // Finds the first text frame that with a matching description (case-insensitive). +@@ -538,10 +537,9 @@ TagLib::ID3v2::UserTextIdentificationFrame* findFirstUserTextIdentificationFrame + inline + QString readFirstUserTextIdentificationFrame( + const TagLib::ID3v2::Tag& tag, +- const QString& description, +- bool preferNotEmpty = true) { ++ const QString& description) { + const TagLib::ID3v2::UserTextIdentificationFrame* pTextFrame = +- findFirstUserTextIdentificationFrame(tag, description, preferNotEmpty); ++ findFirstUserTextIdentificationFrame(tag, description); + if (pTextFrame && (pTextFrame->fieldList().size() > 1)) { + // The actual value is stored in the 2nd field + return toQString(pTextFrame->fieldList()[1]); +@@ -628,7 +626,7 @@ void writeID3v2CommentsFrame( + const QString& description, + bool isNumericOrURL = false) { + TagLib::ID3v2::CommentsFrame* pFrame = +- findFirstCommentsFrame(*pTag, description); ++ findFirstCommentsFrame(*pTag, description, true); + if (pFrame) { + // Modify existing frame + if (text.isEmpty()) { + +From 1ccbca0b86fc31cdea900f1f9dc7008b205ffb67 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Sun, 22 Apr 2018 22:22:09 +0200 +Subject: [PATCH 2/2] Either update or remove replaygain ratio/gain values + +--- + src/track/trackmetadatataglib.cpp | 54 ++++++++++++++++++++------------------- + 1 file changed, 28 insertions(+), 26 deletions(-) + +diff --git a/src/track/trackmetadatataglib.cpp b/src/track/trackmetadatataglib.cpp +index f54724eab5..2615ae5bb6 100644 +--- a/src/track/trackmetadatataglib.cpp ++++ b/src/track/trackmetadatataglib.cpp +@@ -227,13 +227,7 @@ bool parseBpm(TrackMetadata* pTrackMetadata, QString sBpm) { + + inline + QString formatReplayGainGain(const ReplayGain& replayGain) { +- const double gainRatio(replayGain.getRatio()); +- return ReplayGain::ratioToString(gainRatio); +-} +- +-inline +-bool hasTrackGain(const TrackMetadata& trackMetadata) { +- return trackMetadata.getTrackInfo().getReplayGain().hasRatio(); ++ return ReplayGain::ratioToString(replayGain.getRatio()); + } + + inline +@@ -1860,13 +1854,15 @@ bool exportTrackMetadataIntoID3v2Tag(TagLib::ID3v2::Tag* pTag, + + writeID3v2TextIdentificationFrame(pTag, "TKEY", trackMetadata.getTrackInfo().getKey()); + +- if (hasTrackGain(trackMetadata)) { +- writeID3v2UserTextIdentificationFrame( +- pTag, +- "REPLAYGAIN_TRACK_GAIN", +- formatTrackGain(trackMetadata), +- true); +- } ++ writeID3v2UserTextIdentificationFrame( ++ pTag, ++ "REPLAYGAIN_TRACK_GAIN", ++ formatTrackGain(trackMetadata), ++ true); ++ // NOTE(uklotzde, 2018-04-22): The analyzers currently doesn't ++ // calculate a peak value, so leave it untouched in the file if ++ // the value is invalid/absent. Otherwise the ID3 frame would ++ // be deleted. + if (hasTrackPeak(trackMetadata)) { + writeID3v2UserTextIdentificationFrame( + pTag, +@@ -2000,10 +1996,12 @@ bool exportTrackMetadataIntoAPETag(TagLib::APE::Tag* pTag, const TrackMetadata& + writeAPEItem(pTag, "INITIALKEY", + toTagLibString(trackMetadata.getTrackInfo().getKey())); + +- if (hasTrackGain(trackMetadata)) { +- writeAPEItem(pTag, "REPLAYGAIN_TRACK_GAIN", +- toTagLibString(formatTrackGain(trackMetadata))); +- } ++ writeAPEItem(pTag, "REPLAYGAIN_TRACK_GAIN", ++ toTagLibString(formatTrackGain(trackMetadata))); ++ // NOTE(uklotzde, 2018-04-22): The analyzers currently doesn't ++ // calculate a peak value, so leave it untouched in the file if ++ // the value is invalid/absent. Otherwise the APE item would be ++ // deleted. + if (hasTrackPeak(trackMetadata)) { + writeAPEItem(pTag, "REPLAYGAIN_TRACK_PEAK", + toTagLibString(formatTrackPeak(trackMetadata))); +@@ -2149,10 +2147,12 @@ bool exportTrackMetadataIntoXiphComment(TagLib::Ogg::XiphComment* pTag, + writeXiphCommentField(pTag, "INITIALKEY", key); // recommended field + updateXiphCommentField(pTag, "KEY", key); // alternative field + +- if (hasTrackGain(trackMetadata)) { +- writeXiphCommentField(pTag, "REPLAYGAIN_TRACK_GAIN", +- toTagLibString(formatTrackGain(trackMetadata))); +- } ++ writeXiphCommentField(pTag, "REPLAYGAIN_TRACK_GAIN", ++ toTagLibString(formatTrackGain(trackMetadata))); ++ // NOTE(uklotzde, 2018-04-22): The analyzers currently doesn't ++ // calculate a peak value, so leave it untouched in the file if ++ // the value is invalid/absent. Otherwise the comment field would ++ // be deleted. + if (hasTrackPeak(trackMetadata)) { + writeXiphCommentField(pTag, "REPLAYGAIN_TRACK_PEAK", + toTagLibString(formatTrackPeak(trackMetadata))); +@@ -2282,10 +2282,12 @@ bool exportTrackMetadataIntoMP4Tag(TagLib::MP4::Tag* pTag, const TrackMetadata& + writeMP4Atom(pTag, "----:com.apple.iTunes:initialkey", key); // preferred + updateMP4Atom(pTag, "----:com.apple.iTunes:KEY", key); // alternative + +- if (hasTrackGain(trackMetadata)) { +- writeMP4Atom(pTag, "----:com.apple.iTunes:replaygain_track_gain", +- toTagLibString(formatTrackGain(trackMetadata))); +- } ++ writeMP4Atom(pTag, "----:com.apple.iTunes:replaygain_track_gain", ++ toTagLibString(formatTrackGain(trackMetadata))); ++ // NOTE(uklotzde, 2018-04-22): The analyzers currently doesn't ++ // calculate a peak value, so leave it untouched in the file if ++ // the value is invalid/absent. Otherwise the MP4 atom would be ++ // deleted. + if (hasTrackPeak(trackMetadata)) { + writeMP4Atom(pTag, "----:com.apple.iTunes:replaygain_track_peak", + toTagLibString(formatTrackPeak(trackMetadata))); diff --git a/media-sound/mixxx/files/mixxx-2.1.0-fix-crash-when-removing-a-quick-link.patch b/media-sound/mixxx/files/mixxx-2.1.0-fix-crash-when-removing-a-quick-link.patch new file mode 100644 index 0000000..8ca9c4f --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-fix-crash-when-removing-a-quick-link.patch @@ -0,0 +1,69 @@ +From f54dbc552a0fb9c13c7247faea5c2ffd0013c801 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Sat, 21 Apr 2018 12:21:36 +0200 +Subject: [PATCH 1/2] Fix crash when removing a quick link + +--- + src/library/browse/browsefeature.cpp | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp +index feb53b39d3..18a34d08fe 100644 +--- a/src/library/browse/browsefeature.cpp ++++ b/src/library/browse/browsefeature.cpp +@@ -286,8 +286,15 @@ void BrowseFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index + // This is called whenever you double click or use the triangle symbol to expand + // the subtree. The method will read the subfolders. + void BrowseFeature::onLazyChildExpandation(const QModelIndex& index) { ++ if (!index.isValid()) { ++ return; ++ } + TreeItem *item = static_cast(index.internalPointer()); +- if (!item) { ++ if (!(item && item->getData().isValid())) { ++ // Them tem might have been removed just before ++ // NOTE(2018-04-21, uklotzde): When not checking if the QVariant ++ // stored in the item is valid Mixxx will crash. ++ // See also: https://bugs.launchpad.net/mixxx/+bug/1510068 + return; + } + + +From 8a87ad5a176026b92bce2e7c696b619a573f1de1 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Sun, 22 Apr 2018 12:16:42 +0200 +Subject: [PATCH 2/2] Fix typo and clarify comments + +--- + src/library/browse/browsefeature.cpp | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp +index 18a34d08fe..ee72493b43 100644 +--- a/src/library/browse/browsefeature.cpp ++++ b/src/library/browse/browsefeature.cpp +@@ -286,15 +286,20 @@ void BrowseFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index + // This is called whenever you double click or use the triangle symbol to expand + // the subtree. The method will read the subfolders. + void BrowseFeature::onLazyChildExpandation(const QModelIndex& index) { ++ // The selected item might have been removed just before this function ++ // is invoked! ++ // NOTE(2018-04-21, uklotzde): The following checks prevent a crash ++ // that would otherwise occur after a quick link has been removed. ++ // Especially the check of QVariant::isValid() seems to be essential. ++ // See also: https://bugs.launchpad.net/mixxx/+bug/1510068 ++ // After migration to Qt5 the implementation of all LibraryFeatures ++ // should be revisited, because I consider these checks only as a ++ // temporary workaround. + if (!index.isValid()) { + return; + } + TreeItem *item = static_cast(index.internalPointer()); + if (!(item && item->getData().isValid())) { +- // Them tem might have been removed just before +- // NOTE(2018-04-21, uklotzde): When not checking if the QVariant +- // stored in the item is valid Mixxx will crash. +- // See also: https://bugs.launchpad.net/mixxx/+bug/1510068 + return; + } + diff --git a/media-sound/mixxx/files/mixxx-2.1.0-fix-flac-decoding-and-upgrade-db-schema.patch b/media-sound/mixxx/files/mixxx-2.1.0-fix-flac-decoding-and-upgrade-db-schema.patch new file mode 100644 index 0000000..427ea8e --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-fix-flac-decoding-and-upgrade-db-schema.patch @@ -0,0 +1,373 @@ +From d68a5997c745320555bab6860198d00d3e6b0edf Mon Sep 17 00:00:00 2001 +From: Jamie Gifford +Date: Sun, 22 Apr 2018 11:53:44 +1000 +Subject: [PATCH 01/10] Fix -6dB gain in FLAC + +--- + src/sources/soundsourceflac.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp +index 8a496d2289..e6a356922b 100644 +--- a/src/sources/soundsourceflac.cpp ++++ b/src/sources/soundsourceflac.cpp +@@ -437,7 +437,7 @@ void SoundSourceFLAC::flacMetadata(const FLAC__StreamMetadata* metadata) { + // not set before + m_bitsPerSample = bitsPerSample; + m_sampleScaleFactor = CSAMPLE_PEAK +- / CSAMPLE(FLAC__int32(1) << bitsPerSample); ++ / CSAMPLE(FLAC__int32(1) << (bitsPerSample - 1)); + } else { + // already set before -> check for consistency + if (bitsPerSample != m_bitsPerSample) { + +From 82d7b96b2a976b1f74eef61816bd1bfc64fa30ac Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Sun, 22 Apr 2018 14:21:32 +0200 +Subject: [PATCH 02/10] Clarify conversion of fixed-point integer to floating + point samples + +--- + src/sources/soundsourceflac.cpp | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp +index e6a356922b..ecccab61dd 100644 +--- a/src/sources/soundsourceflac.cpp ++++ b/src/sources/soundsourceflac.cpp +@@ -436,8 +436,11 @@ void SoundSourceFLAC::flacMetadata(const FLAC__StreamMetadata* metadata) { + if (kBitsPerSampleDefault == m_bitsPerSample) { + // not set before + m_bitsPerSample = bitsPerSample; +- m_sampleScaleFactor = CSAMPLE_PEAK +- / CSAMPLE(FLAC__int32(1) << (bitsPerSample - 1)); ++ // Range of signed(!) sample values: [2 ^ (bitsPerSample - 1), 2 ^ (bitsPerSample - 1) - 1] ++ // See also: https://bugs.launchpad.net/mixxx/+bug/1766042 ++ const auto maxAbsSampleValue = FLAC__int32(1) << (bitsPerSample - 1); ++ // Scaled range of samples values: [-1.0, 1.0) ++ m_sampleScaleFactor = CSAMPLE_PEAK / CSAMPLE(maxAbsSampleValue); + } else { + // already set before -> check for consistency + if (bitsPerSample != m_bitsPerSample) { + +From e4516a3c82f8b4dd016d712ca3e82017e76c3ffa Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Sun, 22 Apr 2018 14:26:36 +0200 +Subject: [PATCH 03/10] Check for valid bits per sample + +--- + plugins/soundsourcewv/soundsourcewv.cpp | 13 ++++++++++--- + src/sources/soundsourceflac.cpp | 18 ++++++++++++------ + 2 files changed, 22 insertions(+), 9 deletions(-) + +diff --git a/plugins/soundsourcewv/soundsourcewv.cpp b/plugins/soundsourcewv/soundsourcewv.cpp +index 915a66fc03..732b5c0154 100644 +--- a/plugins/soundsourcewv/soundsourcewv.cpp ++++ b/plugins/soundsourcewv/soundsourcewv.cpp +@@ -77,9 +77,16 @@ SoundSource::OpenResult SoundSourceWV::tryOpen( + m_sampleScaleFactor = CSAMPLE_PEAK; + } else { + const int bitsPerSample = WavpackGetBitsPerSample(m_wpc); +- const uint32_t wavpackPeakSampleValue = 1u +- << (bitsPerSample - 1); +- m_sampleScaleFactor = CSAMPLE_PEAK / wavpackPeakSampleValue; ++ if (bitsPerSample > 0) { ++ const uint32_t wavpackPeakSampleValue = 1u ++ << (bitsPerSample - 1); ++ m_sampleScaleFactor = CSAMPLE_PEAK / wavpackPeakSampleValue; ++ } else { ++ kLogger.warning() ++ << "Invalid bits per sample:" ++ << bitsPerSample; ++ return OpenResult::Aborted; ++ } + } + + m_curFrameIndex = frameIndexMin(); +diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp +index ecccab61dd..be79d2a88c 100644 +--- a/src/sources/soundsourceflac.cpp ++++ b/src/sources/soundsourceflac.cpp +@@ -435,12 +435,18 @@ void SoundSourceFLAC::flacMetadata(const FLAC__StreamMetadata* metadata) { + DEBUG_ASSERT(kBitsPerSampleDefault != bitsPerSample); + if (kBitsPerSampleDefault == m_bitsPerSample) { + // not set before +- m_bitsPerSample = bitsPerSample; +- // Range of signed(!) sample values: [2 ^ (bitsPerSample - 1), 2 ^ (bitsPerSample - 1) - 1] +- // See also: https://bugs.launchpad.net/mixxx/+bug/1766042 +- const auto maxAbsSampleValue = FLAC__int32(1) << (bitsPerSample - 1); +- // Scaled range of samples values: [-1.0, 1.0) +- m_sampleScaleFactor = CSAMPLE_PEAK / CSAMPLE(maxAbsSampleValue); ++ if (bitsPerSample > 0) { ++ m_bitsPerSample = bitsPerSample; ++ // Range of signed(!) sample values: [2 ^ (bitsPerSample - 1), 2 ^ (bitsPerSample - 1) - 1] ++ // See also: https://bugs.launchpad.net/mixxx/+bug/1766042 ++ const auto maxAbsSampleValue = FLAC__int32(1) << (bitsPerSample - 1); ++ // Scaled range of samples values: [-1.0, 1.0) ++ m_sampleScaleFactor = CSAMPLE_PEAK / CSAMPLE(maxAbsSampleValue); ++ } else { ++ kLogger.warning() ++ << "Invalid bits per sample:" ++ << bitsPerSample; ++ } + } else { + // already set before -> check for consistency + if (bitsPerSample != m_bitsPerSample) { + +From 1940455fabbb0ed605c8d9345ade016b9be3347b Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Sun, 22 Apr 2018 15:07:27 +0200 +Subject: [PATCH 04/10] Reset wrong replay gain info for all FLAC files + +--- + res/schema.xml | 10 ++++++++++ + src/database/mixxxdb.cpp | 2 +- + 2 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/res/schema.xml b/res/schema.xml +index e58c8033f6..a3ad73a99d 100644 +--- a/res/schema.xml ++++ b/res/schema.xml +@@ -426,4 +426,14 @@ METADATA + ALTER TABLE cues ADD COLUMN color INTEGER DEFAULT 4294901760 NOT NULL; + + ++ ++ ++ Reset replay gain info for all FLAC files after fixing a decoding bug in version 2.1.0. ++ See also: https://bugs.launchpad.net/mixxx/+bug/1766042 ++ ++ ++ ++ UPDATE library SET (replaygain,replaygain_peak)=(0.0,-1.0) WHERE filetype='flac'; ++ ++ + +diff --git a/src/database/mixxxdb.cpp b/src/database/mixxxdb.cpp +index 2046129b44..a831d35b94 100644 +--- a/src/database/mixxxdb.cpp ++++ b/src/database/mixxxdb.cpp +@@ -11,7 +11,7 @@ + const QString MixxxDb::kDefaultSchemaFile(":/schema.xml"); + + //static +-const int MixxxDb::kRequiredSchemaVersion = 27; ++const int MixxxDb::kRequiredSchemaVersion = 28; + + namespace { + + +From 73bc371b2b3913ed39a480a485dd193814b655be Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Sun, 22 Apr 2018 15:20:40 +0200 +Subject: [PATCH 05/10] Use case-insensitive string compare for file type + +--- + res/schema.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/res/schema.xml b/res/schema.xml +index a3ad73a99d..849be6ed73 100644 +--- a/res/schema.xml ++++ b/res/schema.xml +@@ -433,7 +433,7 @@ METADATA + + + +- UPDATE library SET (replaygain,replaygain_peak)=(0.0,-1.0) WHERE filetype='flac'; ++ UPDATE library SET (replaygain,replaygain_peak)=(0.0,-1.0) WHERE filetype='flac' COLLATE NOCASE; + + + + +From a5294bd7031e5663c5b320dbd8cea84ef8e1d9aa Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Mon, 23 Apr 2018 08:40:09 +0200 +Subject: [PATCH 06/10] FLAC/WavPack: Improve validation, align implementation, + fix comments + +--- + plugins/soundsourcewv/soundsourcewv.cpp | 10 ++++++---- + src/sources/soundsourceflac.cpp | 12 ++++++------ + 2 files changed, 12 insertions(+), 10 deletions(-) + +diff --git a/plugins/soundsourcewv/soundsourcewv.cpp b/plugins/soundsourcewv/soundsourcewv.cpp +index 732b5c0154..5d5c5b1c08 100644 +--- a/plugins/soundsourcewv/soundsourcewv.cpp ++++ b/plugins/soundsourcewv/soundsourcewv.cpp +@@ -77,10 +77,12 @@ SoundSource::OpenResult SoundSourceWV::tryOpen( + m_sampleScaleFactor = CSAMPLE_PEAK; + } else { + const int bitsPerSample = WavpackGetBitsPerSample(m_wpc); +- if (bitsPerSample > 0) { +- const uint32_t wavpackPeakSampleValue = 1u +- << (bitsPerSample - 1); +- m_sampleScaleFactor = CSAMPLE_PEAK / wavpackPeakSampleValue; ++ if ((bitsPerSample >= 8) && (bitsPerSample <= 32)) { ++ // 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 sample values: [-CSAMPLE_PEAK, CSAMPLE_PEAK) ++ m_sampleScaleFactor = CSAMPLE_PEAK / absSamplePeak; + } else { + kLogger.warning() + << "Invalid bits per sample:" +diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp +index be79d2a88c..aae897164a 100644 +--- a/src/sources/soundsourceflac.cpp ++++ b/src/sources/soundsourceflac.cpp +@@ -435,13 +435,13 @@ void SoundSourceFLAC::flacMetadata(const FLAC__StreamMetadata* metadata) { + DEBUG_ASSERT(kBitsPerSampleDefault != bitsPerSample); + if (kBitsPerSampleDefault == m_bitsPerSample) { + // not set before +- if (bitsPerSample > 0) { ++ if ((bitsPerSample >= 8) && (bitsPerSample <= 32)) { + m_bitsPerSample = bitsPerSample; +- // Range of signed(!) sample values: [2 ^ (bitsPerSample - 1), 2 ^ (bitsPerSample - 1) - 1] +- // See also: https://bugs.launchpad.net/mixxx/+bug/1766042 +- const auto maxAbsSampleValue = FLAC__int32(1) << (bitsPerSample - 1); +- // Scaled range of samples values: [-1.0, 1.0) +- m_sampleScaleFactor = CSAMPLE_PEAK / CSAMPLE(maxAbsSampleValue); ++ // 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:" + +From a75ff1362d5338973ba9bf257b58838643f16852 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Mon, 23 Apr 2018 09:17:20 +0200 +Subject: [PATCH 07/10] Add Jamie Gifford to the list of contributors + +...and fix some tab/space formatting issues +--- + src/dialog/dlgabout.cpp | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/src/dialog/dlgabout.cpp b/src/dialog/dlgabout.cpp +index 95d833d02d..165254fb01 100644 +--- a/src/dialog/dlgabout.cpp ++++ b/src/dialog/dlgabout.cpp +@@ -83,17 +83,18 @@ DlgAbout::DlgAbout(QWidget* parent) : QDialog(parent), Ui::DlgAboutDlg() { + << "Devananda van der Veen" + << "Tatsuyuki Ishi" + << "Kilian Feess" +- << "Conner Phillips" +- << "Daniel Poelzleithner" ++ << "Conner Phillips" ++ << "Daniel Poelzleithner" + << "Artyom Lyan" + << "Johan Lasperas" + << "Olaf Hering" + << "Stefan Weber" + << "Eduardo Acero" +- << "Kshitij Gupta" +- << "Thomas Jarosch" +- << "Matthew Nicholson" +- << "ronso0"; ++ << "Kshitij Gupta" ++ << "Thomas Jarosch" ++ << "Matthew Nicholson" ++ << "ronso0" ++ << "Jamie Gifford"; + + QStringList specialThanks; + specialThanks + +From a9b001279993668a521cb794901597b1f55bb4ce Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Mon, 23 Apr 2018 09:22:49 +0200 +Subject: [PATCH 08/10] FLAC: Accept files with 4 to 32 bits per sample + +--- + src/sources/soundsourceflac.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp +index aae897164a..01dfc00149 100644 +--- a/src/sources/soundsourceflac.cpp ++++ b/src/sources/soundsourceflac.cpp +@@ -435,7 +435,7 @@ void SoundSourceFLAC::flacMetadata(const FLAC__StreamMetadata* metadata) { + DEBUG_ASSERT(kBitsPerSampleDefault != bitsPerSample); + if (kBitsPerSampleDefault == m_bitsPerSample) { + // not set before +- if ((bitsPerSample >= 8) && (bitsPerSample <= 32)) { ++ 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); + +From 65541c54b86428dbf20d752d1b36b3e1691c5e0d Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Mon, 23 Apr 2018 15:17:30 +0200 +Subject: [PATCH 09/10] Hide developer comments during db schema upgrade + +--- + res/schema.xml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/res/schema.xml b/res/schema.xml +index 849be6ed73..38a20dbfe1 100644 +--- a/res/schema.xml ++++ b/res/schema.xml +@@ -386,7 +386,7 @@ METADATA + + + Add cover art support. Default source is UNKNOWN and default type is NONE. +- See library/coverart.h. ++ + + + ALTER TABLE library ADD COLUMN coverart_source INTEGER DEFAULT 0; +@@ -419,7 +419,7 @@ METADATA + + + Add cue color support. Default color is #FF0000. +- See library/dao/cue.h. ++ + + + +@@ -429,7 +429,7 @@ METADATA + + + Reset replay gain info for all FLAC files after fixing a decoding bug in version 2.1.0. +- See also: https://bugs.launchpad.net/mixxx/+bug/1766042 ++ + + + + +From add395ae54ebb3c4729469cd994fa602cc7738b3 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Mon, 23 Apr 2018 15:18:12 +0200 +Subject: [PATCH 10/10] Don't reset and preserve 'replaygain_peak' of FLAC + files + +--- + res/schema.xml | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/res/schema.xml b/res/schema.xml +index 38a20dbfe1..a51599ed11 100644 +--- a/res/schema.xml ++++ b/res/schema.xml +@@ -429,11 +429,13 @@ METADATA + + + Reset replay gain info for all FLAC files after fixing a decoding bug in version 2.1.0. ++ ++ + + + +- +- UPDATE library SET (replaygain,replaygain_peak)=(0.0,-1.0) WHERE filetype='flac' COLLATE NOCASE; ++ ++ UPDATE library SET replaygain=0.0 WHERE filetype='flac' COLLATE NOCASE; + + + diff --git a/media-sound/mixxx/files/mixxx-2.1.0-fix-integration-of-external-track-libraries.patch b/media-sound/mixxx/files/mixxx-2.1.0-fix-integration-of-external-track-libraries.patch new file mode 100644 index 0000000..29e3700 --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-fix-integration-of-external-track-libraries.patch @@ -0,0 +1,388 @@ +From fbd70f2205d60e85a99630095dde7c535131c53b Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Tue, 24 Apr 2018 22:03:40 +0200 +Subject: [PATCH 1/6] Fix integration of external track libraries + +Add a missing override to BaseExternalTrackModel. I wonder if there are +more of these "gems" hidden inside the code?! This was a tough one, even +though it looks like an easy fix. Implementation inheritance is evil!! +--- + src/library/baseexternaltrackmodel.cpp | 33 +++++++++++++++++++++++---------- + src/library/baseexternaltrackmodel.h | 2 +- + 2 files changed, 24 insertions(+), 11 deletions(-) + +diff --git a/src/library/baseexternaltrackmodel.cpp b/src/library/baseexternaltrackmodel.cpp +index 0713790eff..7f4c00a241 100644 +--- a/src/library/baseexternaltrackmodel.cpp ++++ b/src/library/baseexternaltrackmodel.cpp +@@ -58,20 +58,33 @@ TrackPointer BaseExternalTrackModel::getTrack(const QModelIndex& index) const { + TrackPointer pTrack = m_pTrackCollection->getTrackDAO() + .getOrAddTrack(location, true, &track_already_in_library); + +- // If this track was not in the Mixxx library it is now added and will be +- // saved with the metadata from iTunes. If it was already in the library +- // then we do not touch it so that we do not over-write the user's metadata. +- if (pTrack && !track_already_in_library) { +- pTrack->setArtist(artist); +- pTrack->setTitle(title); +- pTrack->setAlbum(album); +- pTrack->setYear(year); +- pTrack->setGenre(genre); +- pTrack->setBpm(bpm); ++ if (pTrack) { ++ // If this track was not in the Mixxx library it is now added and will be ++ // saved with the metadata from iTunes. If it was already in the library ++ // then we do not touch it so that we do not over-write the user's metadata. ++ if (!track_already_in_library) { ++ pTrack->setArtist(artist); ++ pTrack->setTitle(title); ++ pTrack->setAlbum(album); ++ pTrack->setYear(year); ++ pTrack->setGenre(genre); ++ pTrack->setBpm(bpm); ++ } ++ } else { ++ qWarning() << "Failed to load external track" << location; + } + return pTrack; + } + ++TrackId BaseExternalTrackModel::getTrackId(const QModelIndex& index) const { ++ const auto track = getTrack(index); ++ if (track) { ++ return track->getId(); ++ } else { ++ return TrackId(); ++ } ++} ++ + void BaseExternalTrackModel::trackLoaded(QString group, TrackPointer pTrack) { + if (group == m_previewDeckGroup) { + // If there was a previously loaded track, refresh its rows so the +diff --git a/src/library/baseexternaltrackmodel.h b/src/library/baseexternaltrackmodel.h +index eb4900a63a..7558f960e6 100644 +--- a/src/library/baseexternaltrackmodel.h ++++ b/src/library/baseexternaltrackmodel.h +@@ -7,7 +7,6 @@ + + #include "library/trackmodel.h" + #include "library/basesqltablemodel.h" +-#include "track/track.h" + + class TrackCollection; + +@@ -22,6 +21,7 @@ class BaseExternalTrackModel : public BaseSqlTableModel { + ~BaseExternalTrackModel() override; + + CapabilitiesFlags getCapabilities() const override; ++ TrackId getTrackId(const QModelIndex& index) const override; + TrackPointer getTrack(const QModelIndex& index) const override; + void trackLoaded(QString group, TrackPointer pTrack) override; + bool isColumnInternal(int column) override; + +From 0f635b6ca904b0bde0afa86ddc54fd73cde0ec58 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Tue, 24 Apr 2018 22:36:02 +0200 +Subject: [PATCH 2/6] Reword comment + +--- + src/library/baseexternaltrackmodel.cpp | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/library/baseexternaltrackmodel.cpp b/src/library/baseexternaltrackmodel.cpp +index 7f4c00a241..53a66f0c51 100644 +--- a/src/library/baseexternaltrackmodel.cpp ++++ b/src/library/baseexternaltrackmodel.cpp +@@ -60,8 +60,9 @@ TrackPointer BaseExternalTrackModel::getTrack(const QModelIndex& index) const { + + if (pTrack) { + // If this track was not in the Mixxx library it is now added and will be +- // saved with the metadata from iTunes. If it was already in the library +- // then we do not touch it so that we do not over-write the user's metadata. ++ // saved with the metadata from external library. If it was already in the ++ // Mixxx library then we do not touch it so that we do not over-write the ++ // user's metadata. + if (!track_already_in_library) { + pTrack->setArtist(artist); + pTrack->setTitle(title); + +From 1dc6401178d912ee9bdbab2fa1cae735b3f4ad16 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Tue, 24 Apr 2018 15:31:44 +0200 +Subject: [PATCH 3/6] Delete unused member function + +--- + src/library/dao/trackdao.cpp | 8 -------- + src/library/dao/trackdao.h | 2 -- + 2 files changed, 10 deletions(-) + +diff --git a/src/library/dao/trackdao.cpp b/src/library/dao/trackdao.cpp +index 4ecadc0eb5..5316da2e40 100644 +--- a/src/library/dao/trackdao.cpp ++++ b/src/library/dao/trackdao.cpp +@@ -179,14 +179,6 @@ QString TrackDAO::getTrackLocation(TrackId trackId) { + return trackLocation; + } + +-/** Check if a track exists in the library table already. +- @param file_location The full path to the track on disk, including the filename. +- @return true if the track is found in the library table, false otherwise. +-*/ +-bool TrackDAO::trackExistsInDatabase(const QString& absoluteFilePath) { +- return getTrackId(absoluteFilePath).isValid(); +-} +- + void TrackDAO::saveTrack(Track* pTrack) { + DEBUG_ASSERT(pTrack); + if (pTrack->isDirty()) { +diff --git a/src/library/dao/trackdao.h b/src/library/dao/trackdao.h +index 7c33fe269c..9a911f889e 100644 +--- a/src/library/dao/trackdao.h ++++ b/src/library/dao/trackdao.h +@@ -43,8 +43,6 @@ class TrackDAO : public QObject, public virtual DAO, public virtual GlobalTrackC + QList getTrackIds(const QList& files); + QList getTrackIds(const QDir& dir); + +- bool trackExistsInDatabase(const QString& absoluteFilePath); +- + // WARNING: Only call this from the main thread instance of TrackDAO. + TrackPointer getTrack(TrackId trackId) const; + + +From d6b7e12d72516152d7f01758331304ba075f2eeb Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Tue, 24 Apr 2018 15:38:56 +0200 +Subject: [PATCH 4/6] Hide internal utility function + +--- + src/library/dao/trackdao.cpp | 33 +++++++++++++++++++-------------- + src/library/dao/trackdao.h | 1 - + 2 files changed, 19 insertions(+), 15 deletions(-) + +diff --git a/src/library/dao/trackdao.cpp b/src/library/dao/trackdao.cpp +index 5316da2e40..161eed8c28 100644 +--- a/src/library/dao/trackdao.cpp ++++ b/src/library/dao/trackdao.cpp +@@ -36,8 +36,26 @@ + #include "util/timer.h" + #include "util/math.h" + ++ ++namespace { ++ + enum { UndefinedRecordIndex = -2 }; + ++void markTrackLocationsAsDeleted(QSqlDatabase database, const QString& directory) { ++ //qDebug() << "TrackDAO::markTrackLocationsAsDeleted" << QThread::currentThread() << m_database.connectionName(); ++ QSqlQuery query(database); ++ query.prepare("UPDATE track_locations " ++ "SET fs_deleted=1 " ++ "WHERE directory=:directory"); ++ query.bindValue(":directory", directory); ++ if (!query.exec()) { ++ LOG_FAILED_QUERY(query) ++ << "Couldn't mark tracks in" << directory << "as deleted."; ++ } ++} ++ ++} // anonymous namespace ++ + TrackDAO::TrackDAO(CueDAO& cueDao, + PlaylistDAO& playlistDao, + AnalysisDao& analysisDao, +@@ -84,7 +102,7 @@ void TrackDAO::finish() { + // directories as deleted. + // TODO(XXX) This doesn't handle sub-directories of deleted directories. + for (const auto& dir: deletedHashDirs) { +- markTrackLocationsAsDeleted(dir); ++ markTrackLocationsAsDeleted(m_database, dir); + } + transaction.commit(); + } +@@ -1502,19 +1520,6 @@ void TrackDAO::markUnverifiedTracksAsDeleted() { + } + } + +-void TrackDAO::markTrackLocationsAsDeleted(const QString& directory) { +- //qDebug() << "TrackDAO::markTrackLocationsAsDeleted" << QThread::currentThread() << m_database.connectionName(); +- QSqlQuery query(m_database); +- query.prepare("UPDATE track_locations " +- "SET fs_deleted=1 " +- "WHERE directory=:directory"); +- query.bindValue(":directory", directory); +- if (!query.exec()) { +- LOG_FAILED_QUERY(query) +- << "Couldn't mark tracks in" << directory << "as deleted."; +- } +-} +- + // Look for moved files. Look for files that have been marked as + // "deleted on disk" and see if another "file" with the same name and + // files size exists in the track_locations table. That means the file has +diff --git a/src/library/dao/trackdao.h b/src/library/dao/trackdao.h +index 9a911f889e..f3ce490cca 100644 +--- a/src/library/dao/trackdao.h ++++ b/src/library/dao/trackdao.h +@@ -90,7 +90,6 @@ class TrackDAO : public QObject, public virtual DAO, public virtual GlobalTrackC + void markTracksInDirectoriesAsVerified(const QStringList& directories); + void invalidateTrackLocationsInLibrary(); + void markUnverifiedTracksAsDeleted(); +- void markTrackLocationsAsDeleted(const QString& directory); + bool detectMovedTracks(QSet* pTracksMovedSetOld, + QSet* pTracksMovedSetNew, + const QStringList& addedTracks, + +From e7ee1e507f9010a869c60e7e706094e6458fd5d7 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Wed, 25 Apr 2018 00:56:19 +0200 +Subject: [PATCH 5/6] Improve error handling and logging when loading/adding + tracks + +--- + src/library/dao/trackdao.cpp | 50 +++++++++++++++++++++++++------------------- + 1 file changed, 29 insertions(+), 21 deletions(-) + +diff --git a/src/library/dao/trackdao.cpp b/src/library/dao/trackdao.cpp +index 161eed8c28..06f1cae3cf 100644 +--- a/src/library/dao/trackdao.cpp ++++ b/src/library/dao/trackdao.cpp +@@ -121,6 +121,8 @@ TrackId TrackDAO::getTrackId(const QString& absoluteFilePath) { + if (query.exec()) { + if (query.next()) { + trackId = TrackId(query.value(query.record().indexOf("id"))); ++ } else { ++ qDebug() << "TrackDAO::getTrackId(): Track location not found in library:" << absoluteFilePath; + } + } else { + LOG_FAILED_QUERY(query); +@@ -151,6 +153,10 @@ QList TrackDAO::getTrackIds(const QList& files) { + while (query.next()) { + trackIds.append(TrackId(query.value(idColumn))); + } ++ DEBUG_ASSERT(trackIds.size() <= files.size()); ++ if (trackIds.size() < files.size()) { ++ qDebug() << "TrackDAO::getTrackIds(): Found only" << trackIds.size() << "of" << files.size() << "tracks in library"; ++ } + } else { + LOG_FAILED_QUERY(query); + } +@@ -1904,36 +1910,38 @@ void TrackDAO::detectCoverArtForTracksWithoutCover(volatile const bool* pCancel, + TrackPointer TrackDAO::getOrAddTrack(const QString& trackLocation, + bool processCoverArt, + bool* pAlreadyInLibrary) { +- const TrackId trackId(getTrackId(trackLocation)); ++ const TrackId trackId = getTrackId(trackLocation); + const bool trackAlreadyInLibrary = trackId.isValid(); ++ if (pAlreadyInLibrary) { ++ *pAlreadyInLibrary = trackAlreadyInLibrary; ++ } + + TrackPointer pTrack; + if (trackAlreadyInLibrary) { + pTrack = getTrack(trackId); ++ if (!pTrack) { ++ qWarning() << "Failed to load track" ++ << trackLocation; ++ return pTrack; ++ } + } else { + // Add Track to library -- unremove if it was previously removed. + pTrack = addSingleTrack(trackLocation, true); +- } +- +- // addTrack or getTrack may fail. +- if (!pTrack) { +- qWarning() << "Failed to load track" +- << trackLocation; +- return pTrack; +- } +- +- // If the track wasn't in the library already then it has not yet been +- // checked for cover art. If processCoverArt is true then we should request +- // cover processing via CoverArtCache asynchronously. +- if (processCoverArt && !trackAlreadyInLibrary) { +- CoverArtCache* pCache = CoverArtCache::instance(); +- if (pCache != nullptr) { +- pCache->requestGuessCover(pTrack); ++ if (!pTrack) { ++ qWarning() << "Failed to add track" ++ << trackLocation; ++ return pTrack; ++ } ++ DEBUG_ASSERT(pTrack); ++ // If the track wasn't in the library already then it has not yet been ++ // checked for cover art. If processCoverArt is true then we should request ++ // cover processing via CoverArtCache asynchronously. ++ if (processCoverArt) { ++ CoverArtCache* pCache = CoverArtCache::instance(); ++ if (pCache != nullptr) { ++ pCache->requestGuessCover(pTrack); ++ } + } +- } +- +- if (pAlreadyInLibrary != nullptr) { +- *pAlreadyInLibrary = trackAlreadyInLibrary; + } + + return pTrack; + +From 5f8659db2c1ecb1661577ea16c9c316bbaf670ff Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Thu, 26 Apr 2018 00:26:32 +0200 +Subject: [PATCH 6/6] Extenals libraries: Convert native to canonical location + +--- + src/library/baseexternalplaylistmodel.cpp | 6 ++++-- + src/library/baseexternaltrackmodel.cpp | 6 ++++-- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/library/baseexternalplaylistmodel.cpp b/src/library/baseexternalplaylistmodel.cpp +index 731c742368..7529523896 100644 +--- a/src/library/baseexternalplaylistmodel.cpp ++++ b/src/library/baseexternalplaylistmodel.cpp +@@ -21,8 +21,9 @@ BaseExternalPlaylistModel::~BaseExternalPlaylistModel() { + } + + TrackPointer BaseExternalPlaylistModel::getTrack(const QModelIndex& index) const { +- QString location = index.sibling( ++ QString nativeLocation = index.sibling( + index.row(), fieldIndex("location")).data().toString(); ++ QString location = QDir::fromNativeSeparators(nativeLocation); + + if (location.isEmpty()) { + // Track is lost +@@ -150,7 +151,8 @@ void BaseExternalPlaylistModel::trackLoaded(QString group, TrackPointer pTrack) + // The external table has foreign Track IDs, so we need to compare + // by location + for (int row = 0; row < rowCount(); ++row) { +- QString location = index(row, fieldIndex("location")).data().toString(); ++ QString nativeLocation = index(row, fieldIndex("location")).data().toString(); ++ QString location = QDir::fromNativeSeparators(nativeLocation); + if (location == pTrack->getLocation()) { + m_previewDeckTrackId = TrackId(index(row, 0).data()); + //Debug() << "foreign track id" << m_previewDeckTrackId; +diff --git a/src/library/baseexternaltrackmodel.cpp b/src/library/baseexternaltrackmodel.cpp +index 53a66f0c51..3dfd3df083 100644 +--- a/src/library/baseexternaltrackmodel.cpp ++++ b/src/library/baseexternaltrackmodel.cpp +@@ -47,7 +47,8 @@ TrackPointer BaseExternalTrackModel::getTrack(const QModelIndex& index) const { + QString genre = index.sibling(index.row(), fieldIndex("genre")).data().toString(); + float bpm = index.sibling(index.row(), fieldIndex("bpm")).data().toString().toFloat(); + +- QString location = index.sibling(index.row(), fieldIndex("location")).data().toString(); ++ QString nativeLocation = index.sibling(index.row(), fieldIndex("location")).data().toString(); ++ QString location = QDir::fromNativeSeparators(nativeLocation); + + if (location.isEmpty()) { + // Track is lost +@@ -104,7 +105,8 @@ void BaseExternalTrackModel::trackLoaded(QString group, TrackPointer pTrack) { + // The external table has foreign Track IDs, so we need to compare + // by location + for (int row = 0; row < rowCount(); ++row) { +- QString location = index(row, fieldIndex("location")).data().toString(); ++ QString nativeLocation = index(row, fieldIndex("location")).data().toString(); ++ QString location = QDir::fromNativeSeparators(nativeLocation); + if (location == pTrack->getLocation()) { + m_previewDeckTrackId = TrackId(index(row, 0).data()); + //qDebug() << "foreign track id" << m_previewDeckTrackId; diff --git a/media-sound/mixxx/files/mixxx-2.1.0-fix-invocation-args-of-pasuspender.patch b/media-sound/mixxx/files/mixxx-2.1.0-fix-invocation-args-of-pasuspender.patch new file mode 100644 index 0000000..c7c7525 --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-fix-invocation-args-of-pasuspender.patch @@ -0,0 +1,58 @@ +From 17f3ef6bea533b4d6e90419bf0346607c73db353 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Mon, 16 Apr 2018 07:23:37 +0200 +Subject: [PATCH 1/2] Fix invocation args of pasuspender + +--- + res/linux/mixxx.desktop | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/res/linux/mixxx.desktop b/res/linux/mixxx.desktop +index 14c967c286..5e1ff650b0 100644 +--- a/res/linux/mixxx.desktop ++++ b/res/linux/mixxx.desktop +@@ -8,7 +8,7 @@ GenericName[fr]=Interface numérique pour DJ + Comment=A digital DJ interface + Comment[de]=Ein digitales DJ-System + Comment[fr]=Une interface numérique pour DJ +-Exec=sh -c "pasuspender mixxx || mixxx" ++Exec=sh -c "pasuspender -- mixxx || mixxx" + Terminal=false + Icon=mixxx-icon + Type=Application + +From 271432773dae5e8d860106ba3dbe5b1757797471 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Mon, 16 Apr 2018 12:03:38 +0200 +Subject: [PATCH 2/2] Fix remaining invocations with of pasuspender + +--- + build/debian/menu | 2 +- + build/debian/mixxx.desktop | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/build/debian/menu b/build/debian/menu +index c945aa3d19..b1ff680748 100644 +--- a/build/debian/menu ++++ b/build/debian/menu +@@ -2,6 +2,6 @@ + needs="X11" \ + section="Apps/Sound" \ + title="Mixxx" \ +- command="/usr/bin/pasuspender /usr/bin/mixxx" \ ++ command="/usr/bin/pasuspender -- /usr/bin/mixxx" \ + icon="/usr/share/pixmaps/mixxx.xpm" \ + icon16x16="/usr/share/pixmaps/mixxx-16.xpm" +diff --git a/build/debian/mixxx.desktop b/build/debian/mixxx.desktop +index 45323b5c15..947ef82a20 100644 +--- a/build/debian/mixxx.desktop ++++ b/build/debian/mixxx.desktop +@@ -3,7 +3,7 @@ Version=1.0 + Name=Mixxx + GenericName=Digital DJ interface + Comment=A digital DJ interface +-Exec=pasuspender mixxx ++Exec=pasuspender -- mixxx + Terminal=false + Icon=mixxx-icon + Type=Application diff --git a/media-sound/mixxx/files/mixxx-2.1.0-fix-latenight-group-fx-buttons-in-deck.patch b/media-sound/mixxx/files/mixxx-2.1.0-fix-latenight-group-fx-buttons-in-deck.patch new file mode 100644 index 0000000..a3acf23 --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-fix-latenight-group-fx-buttons-in-deck.patch @@ -0,0 +1,197 @@ +From b20028cd25e0934cf1b5e03f38ff7b82ee1762de Mon Sep 17 00:00:00 2001 +From: Stefan +Date: Sun, 22 Apr 2018 10:27:36 +0200 +Subject: [PATCH] Latenight: group FX Buttons + +--- + res/skins/LateNight/deck_row_1_keyVinylFx.xml | 173 +++++++++++++------------- + 1 file changed, 89 insertions(+), 84 deletions(-) + +diff --git a/res/skins/LateNight/deck_row_1_keyVinylFx.xml b/res/skins/LateNight/deck_row_1_keyVinylFx.xml +index 52694d05c6..fe6d76de11 100644 +--- a/res/skins/LateNight/deck_row_1_keyVinylFx.xml ++++ b/res/skins/LateNight/deck_row_1_keyVinylFx.xml +@@ -99,94 +99,99 @@ + min,min + + +- +- +- +- 30f,22f +- EffectUnit_deck_enabled +- FxAssignButton +- 2 +- +- 0 +- FX 1 +- +- +- 1 +- FX 1 +- +- +- [EffectRack1_EffectUnit1],group__enable +- LeftButton +- +- +- +- +- 30f,22f +- EffectUnit_deck_enabled +- FxAssignButton +- 2 +- +- 0 +- FX 2 +- +- +- 1 +- FX 2 +- +- +- [EffectRack1_EffectUnit2],group__enable +- LeftButton +- +- +- ++ + + horizontal +- +- [Master],show_4effectunits +- visible +- +- +- +- 30f,22f +- EffectUnit_deck_enabled +- FxAssignButton +- 2 +- +- 0 +- FX 3 +- +- +- 1 +- FX 3 +- +- +- [EffectRack1_EffectUnit3],group__enable +- LeftButton +- +- ++ AlignRightTop ++ ++ ++ ++ 30f,22f ++ EffectUnit_deck_enabled ++ FxAssignButton ++ 2 ++ ++ 0 ++ FX 1 ++ ++ ++ 1 ++ FX 1 ++ ++ ++ [EffectRack1_EffectUnit1],group__enable ++ LeftButton ++ ++ + +- +- 30f,22f +- EffectUnit_deck_enabled +- FxAssignButton +- 2 +- +- 0 +- FX 4 +- +- +- 1 +- FX 4 +- +- +- [EffectRack1_EffectUnit4],group__enable +- LeftButton +- +- +- +- +- ++ ++ 30f,22f ++ EffectUnit_deck_enabled ++ FxAssignButton ++ 2 ++ ++ 0 ++ FX 2 ++ ++ ++ 1 ++ FX 2 ++ ++ ++ [EffectRack1_EffectUnit2],group__enable ++ LeftButton ++ ++ ++ ++ ++ horizontal ++ ++ [Master],show_4effectunits ++ visible ++ ++ ++ ++ 30f,22f ++ EffectUnit_deck_enabled ++ FxAssignButton ++ 2 ++ ++ 0 ++ FX 3 ++ ++ ++ 1 ++ FX 3 ++ ++ ++ [EffectRack1_EffectUnit3],group__enable ++ LeftButton ++ ++ + ++ ++ 30f,22f ++ EffectUnit_deck_enabled ++ FxAssignButton ++ 2 ++ ++ 0 ++ FX 4 ++ ++ ++ 1 ++ FX 4 ++ ++ ++ [EffectRack1_EffectUnit4],group__enable ++ LeftButton ++ ++ ++ ++ ++ ++ ++ + + + diff --git a/media-sound/mixxx/files/mixxx-2.1.0-fix-memory-leak-when-loading-cover-art.patch b/media-sound/mixxx/files/mixxx-2.1.0-fix-memory-leak-when-loading-cover-art.patch new file mode 100644 index 0000000..d00969a --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-fix-memory-leak-when-loading-cover-art.patch @@ -0,0 +1,38 @@ +From 770220835757f677990c31f4bd95861ca8ef5853 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Thu, 26 Apr 2018 14:43:32 +0200 +Subject: [PATCH] Fix memory leak when loading cover art + +--- + src/library/coverartcache.cpp | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/src/library/coverartcache.cpp b/src/library/coverartcache.cpp +index eb91411473..e76168422d 100644 +--- a/src/library/coverartcache.cpp ++++ b/src/library/coverartcache.cpp +@@ -94,6 +94,7 @@ QPixmap CoverArtCache::requestCover(const CoverInfo& requestInfo, + } + + m_runningRequests.insert(requestId); ++ // The watcher will be deleted in coverLoaded() + QFutureWatcher* watcher = new QFutureWatcher(this); + QFuture future = QtConcurrent::run( + this, &CoverArtCache::loadCover, requestInfo, pRequestor, +@@ -146,9 +147,13 @@ CoverArtCache::FutureResult CoverArtCache::loadCover( + + // watcher + void CoverArtCache::coverLoaded() { +- QFutureWatcher* watcher; +- watcher = reinterpret_cast*>(sender()); +- FutureResult res = watcher->result(); ++ FutureResult res; ++ { ++ QFutureWatcher* watcher = ++ static_cast*>(sender()); ++ res = watcher->result(); ++ watcher->deleteLater(); ++ } + + if (sDebug) { + kLogger.debug() << "coverLoaded" << res.cover; diff --git a/media-sound/mixxx/files/mixxx-2.1.0-fix-navigation-usability-issues-in-sidebar-tree.patch b/media-sound/mixxx/files/mixxx-2.1.0-fix-navigation-usability-issues-in-sidebar-tree.patch new file mode 100644 index 0000000..75dca34 --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-fix-navigation-usability-issues-in-sidebar-tree.patch @@ -0,0 +1,395 @@ +From 9bf67d08cf32398b05c6bb24dc52c3b9e4cded81 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Tue, 17 Apr 2018 15:51:50 +0200 +Subject: [PATCH 1/2] Use a default timeout of 250 ms between selection and + activation + +--- + src/library/baseplaylistfeature.cpp | 8 +------- + src/library/crate/cratefeature.cpp | 4 +--- + src/library/libraryfeature.cpp | 13 +++++++++++-- + 3 files changed, 13 insertions(+), 12 deletions(-) + +diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp +index c0506e458d..2cfd68e974 100644 +--- a/src/library/baseplaylistfeature.cpp ++++ b/src/library/baseplaylistfeature.cpp +@@ -19,17 +19,11 @@ + #include "widget/wlibrarytextbrowser.h" + #include "util/assert.h" + +-namespace { +- +-const int kClickedChildActivationTimeoutMillis = 100; +- +-} // anonymous namespace +- + BasePlaylistFeature::BasePlaylistFeature(QObject* parent, + UserSettingsPointer pConfig, + TrackCollection* pTrackCollection, + QString rootViewName) +- : LibraryFeature(pConfig, kClickedChildActivationTimeoutMillis, parent), ++ : LibraryFeature(pConfig, parent), + m_pTrackCollection(pTrackCollection), + m_playlistDao(pTrackCollection->getPlaylistDAO()), + m_trackDao(pTrackCollection->getTrackDAO()), +diff --git a/src/library/crate/cratefeature.cpp b/src/library/crate/cratefeature.cpp +index da75522e39..38c09b0eb8 100644 +--- a/src/library/crate/cratefeature.cpp ++++ b/src/library/crate/cratefeature.cpp +@@ -29,8 +29,6 @@ + + namespace { + +-const int kClickedChildActivationTimeoutMillis = 100; +- + QString formatLabel( + const CrateSummary& crateSummary) { + return QString("%1 (%2) %3").arg( +@@ -44,7 +42,7 @@ QString formatLabel( + CrateFeature::CrateFeature(Library* pLibrary, + TrackCollection* pTrackCollection, + UserSettingsPointer pConfig) +- : LibraryFeature(pConfig, kClickedChildActivationTimeoutMillis), ++ : LibraryFeature(pConfig), + m_cratesIcon(":/images/library/ic_library_crates.png"), + m_lockedCrateIcon(":/images/library/ic_library_locked.png"), + m_pTrackCollection(pTrackCollection), +diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp +index e582557370..701e17a513 100644 +--- a/src/library/libraryfeature.cpp ++++ b/src/library/libraryfeature.cpp +@@ -7,10 +7,19 @@ + // The reason for this is that LibraryFeature uses slots/signals and for this + // to work the code has to be precompiles by moc + ++namespace { ++ ++// The time between selecting and activating a feature item in the left ++// pane. This is required to allow smooth and responsive scrolling through ++// a list of items with an encoder! ++const int kDefaultClickedChildActivationTimeoutMillis = 250; ++ ++} // anonymous namespace ++ + LibraryFeature::LibraryFeature( + QObject *parent) + : QObject(parent), +- m_clickedChildActivationTimeoutMillis(0) { ++ m_clickedChildActivationTimeoutMillis(kDefaultClickedChildActivationTimeoutMillis) { + } + + LibraryFeature::LibraryFeature( +@@ -26,7 +35,7 @@ LibraryFeature::LibraryFeature( + QObject* parent) + : QObject(parent), + m_pConfig(pConfig), +- m_clickedChildActivationTimeoutMillis(0) { ++ m_clickedChildActivationTimeoutMillis(kDefaultClickedChildActivationTimeoutMillis) { + } + + LibraryFeature::LibraryFeature( + +From c10c7be2890d0ede449ca32f25f6614e63db63af Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Tue, 17 Apr 2018 20:29:16 +0200 +Subject: [PATCH 2/2] Distinguish between mouse and keyboard/encoder events in + sidebar tree + +--- + src/library/library.cpp | 2 + + src/library/libraryfeature.cpp | 33 +--------------- + src/library/libraryfeature.h | 15 +------ + src/library/sidebarmodel.cpp | 90 +++++++++++++++++++++++++----------------- + src/library/sidebarmodel.h | 13 +++--- + 5 files changed, 65 insertions(+), 88 deletions(-) + +diff --git a/src/library/library.cpp b/src/library/library.cpp +index 5a22fe9f84..20d447656c 100644 +--- a/src/library/library.cpp ++++ b/src/library/library.cpp +@@ -210,6 +210,8 @@ void Library::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { + connect(m_pSidebarModel, SIGNAL(selectIndex(const QModelIndex&)), + pSidebarWidget, SLOT(selectIndex(const QModelIndex&))); + connect(pSidebarWidget, SIGNAL(pressed(const QModelIndex&)), ++ m_pSidebarModel, SLOT(pressed(const QModelIndex&))); ++ connect(pSidebarWidget, SIGNAL(clicked(const QModelIndex&)), + m_pSidebarModel, SLOT(clicked(const QModelIndex&))); + // Lazy model: Let triangle symbol increment the model + connect(pSidebarWidget, SIGNAL(expanded(const QModelIndex&)), +diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp +index 701e17a513..eb54b28ce7 100644 +--- a/src/library/libraryfeature.cpp ++++ b/src/library/libraryfeature.cpp +@@ -7,45 +7,16 @@ + // The reason for this is that LibraryFeature uses slots/signals and for this + // to work the code has to be precompiles by moc + +-namespace { +- +-// The time between selecting and activating a feature item in the left +-// pane. This is required to allow smooth and responsive scrolling through +-// a list of items with an encoder! +-const int kDefaultClickedChildActivationTimeoutMillis = 250; +- +-} // anonymous namespace +- +-LibraryFeature::LibraryFeature( +- QObject *parent) +- : QObject(parent), +- m_clickedChildActivationTimeoutMillis(kDefaultClickedChildActivationTimeoutMillis) { +-} +- + LibraryFeature::LibraryFeature( +- int clickedChildActivationTimeoutMillis, + QObject *parent) +- : QObject(parent), +- m_clickedChildActivationTimeoutMillis(clickedChildActivationTimeoutMillis) { +- DEBUG_ASSERT(m_clickedChildActivationTimeoutMillis >= 0); +-} +- +-LibraryFeature::LibraryFeature( +- UserSettingsPointer pConfig, +- QObject* parent) +- : QObject(parent), +- m_pConfig(pConfig), +- m_clickedChildActivationTimeoutMillis(kDefaultClickedChildActivationTimeoutMillis) { ++ : QObject(parent) { + } + + LibraryFeature::LibraryFeature( + UserSettingsPointer pConfig, +- int clickedChildActivationTimeoutMillis, + QObject* parent) + : QObject(parent), +- m_pConfig(pConfig), +- m_clickedChildActivationTimeoutMillis(clickedChildActivationTimeoutMillis) { +- DEBUG_ASSERT(m_clickedChildActivationTimeoutMillis >= 0); ++ m_pConfig(pConfig) { + } + + QStringList LibraryFeature::getPlaylistFiles(QFileDialog::FileMode mode) const { +diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h +index 7639e03557..0fe348c89c 100644 +--- a/src/library/libraryfeature.h ++++ b/src/library/libraryfeature.h +@@ -30,23 +30,12 @@ class LibraryFeature : public QObject { + Q_OBJECT + public: + explicit LibraryFeature( +- QObject* parent); +- explicit LibraryFeature( +- int clickedChildActivationTimeoutMillis, +- QObject* parent = nullptr); +- explicit LibraryFeature( +- UserSettingsPointer pConfig, +- QObject* parent = nullptr); ++ QObject* parent = nullptr); + explicit LibraryFeature( + UserSettingsPointer pConfig, +- int clickedChildActivationTimeoutMillis, + QObject* parent = nullptr); + ~LibraryFeature() override = default; + +- int clickedChildActivationTimeoutMillis() const { +- return m_clickedChildActivationTimeoutMillis; +- } +- + virtual QVariant title() = 0; + virtual QIcon getIcon() = 0; + +@@ -135,8 +124,6 @@ class LibraryFeature : public QObject { + + private: + QStringList getPlaylistFiles(QFileDialog::FileMode mode) const; +- +- const int m_clickedChildActivationTimeoutMillis; + }; + + #endif /* LIBRARYFEATURE_H */ +diff --git a/src/library/sidebarmodel.cpp b/src/library/sidebarmodel.cpp +index c2bb5d198b..22a93e2165 100644 +--- a/src/library/sidebarmodel.cpp ++++ b/src/library/sidebarmodel.cpp +@@ -8,14 +8,23 @@ + #include "library/browse/browsefeature.h" + #include "util/assert.h" + ++namespace { ++ ++// The time between selecting and activating (= clicking) a feature item ++// in the sidebar tree. This is essential to allow smooth scrolling through ++// a list of items with an encoder or the keyboard! A value of 300 ms has ++// been chosen as a compromise between usability and responsiveness. ++const int kPressedUntilClickedTimeoutMillis = 300; ++ ++} // anonymous namespace ++ + SidebarModel::SidebarModel( + QObject* parent) + : QAbstractItemModel(parent), + m_iDefaultSelectedIndex(0), +- m_clickedChildActivationTimer(new QTimer(this)), +- m_clickedFeature(nullptr) { +- m_clickedChildActivationTimer->setSingleShot(true); +- connect(m_clickedChildActivationTimer, SIGNAL(timeout()), this, SLOT(slotActivateChildAtClickedFeatureIndex())); ++ m_pressedUntilClickedTimer(new QTimer(this)) { ++ m_pressedUntilClickedTimer->setSingleShot(true); ++ connect(m_pressedUntilClickedTimer, SIGNAL(timeout()), this, SLOT(slotPressedUntilClickedTimeout())); + } + + void SidebarModel::addLibraryFeature(LibraryFeature* feature) { +@@ -222,62 +231,72 @@ QVariant SidebarModel::data(const QModelIndex& index, int role) const { + return QVariant(); + } + +-void SidebarModel::onFeatureIndexClicked( +- LibraryFeature* feature, +- QModelIndex index) { +- m_clickedChildActivationTimer->stop(); +- m_clickedFeature = feature; +- m_clickedIndex = index; ++void SidebarModel::startPressedUntilClickedTimer(QModelIndex pressedIndex) { ++ m_pressedIndex = pressedIndex; ++ m_pressedUntilClickedTimer->start(kPressedUntilClickedTimeoutMillis); + } + +-void SidebarModel::slotActivateChildAtClickedFeatureIndex() { +- if (m_clickedFeature) { +- m_clickedFeature->activateChild(m_clickedIndex); +- } ++void SidebarModel::stopPressedUntilClickedTimer() { ++ m_pressedUntilClickedTimer->stop(); ++ m_pressedIndex = QModelIndex(); + } + +-void SidebarModel::clicked(const QModelIndex& index) { +- //qDebug() << "SidebarModel::clicked() index=" << index; ++void SidebarModel::slotPressedUntilClickedTimeout() { ++ if (m_pressedIndex.isValid()) { ++ QModelIndex clickedIndex = m_pressedIndex; ++ stopPressedUntilClickedTimer(); ++ clicked(clickedIndex); ++ } ++} + +- // We use clicked() for keyboard and mouse control, and the +- // following code breaks that for us: +- /*if (QApplication::mouseButtons() != Qt::LeftButton) { +- return; +- }*/ ++void SidebarModel::pressed(const QModelIndex& index) { ++ stopPressedUntilClickedTimer(); ++ if (index.isValid()) { ++ if (index.internalPointer() == this) { ++ m_sFeatures[index.row()]->activate(); ++ } else { ++ startPressedUntilClickedTimer(index); ++ } ++ } ++} + ++void SidebarModel::clicked(const QModelIndex& index) { ++ // When triggered by a mouse event pressed() has been ++ // invoked immediately before. That doesn't matter, ++ // because we stop any running timer before handling ++ // this event. ++ stopPressedUntilClickedTimer(); + if (index.isValid()) { + if (index.internalPointer() == this) { + m_sFeatures[index.row()]->activate(); + } else { +- TreeItem* tree_item = (TreeItem*)index.internalPointer(); ++ TreeItem* tree_item = static_cast(index.internalPointer()); + if (tree_item) { +- onFeatureIndexClicked(tree_item->feature(), index); +- DEBUG_ASSERT(m_clickedFeature); +- // Deferred activation is required for smooth scrolling when using +- // encoder knobs +- m_clickedChildActivationTimer->start( +- m_clickedFeature->clickedChildActivationTimeoutMillis()); ++ LibraryFeature* feature = tree_item->feature(); ++ DEBUG_ASSERT(feature); ++ feature->activateChild(index); + } + } + } + } ++ + void SidebarModel::doubleClicked(const QModelIndex& index) { ++ stopPressedUntilClickedTimer(); + if (index.isValid()) { + if (index.internalPointer() == this) { + return; + } else { + TreeItem* tree_item = (TreeItem*)index.internalPointer(); + if (tree_item) { +- onFeatureIndexClicked(tree_item->feature(), index); +- DEBUG_ASSERT(m_clickedFeature); +- m_clickedFeature->onLazyChildExpandation(m_clickedIndex); ++ LibraryFeature* feature = tree_item->feature(); ++ feature->onLazyChildExpandation(index); + } + } + } + } + + void SidebarModel::rightClicked(const QPoint& globalPos, const QModelIndex& index) { +- //qDebug() << "SidebarModel::rightClicked() index=" << index; ++ stopPressedUntilClickedTimer(); + if (index.isValid()) { + if (index.internalPointer() == this) { + m_sFeatures[index.row()]->activate(); +@@ -287,10 +306,9 @@ void SidebarModel::rightClicked(const QPoint& globalPos, const QModelIndex& inde + { + TreeItem* tree_item = (TreeItem*)index.internalPointer(); + if (tree_item) { +- onFeatureIndexClicked(tree_item->feature(), index); +- DEBUG_ASSERT(m_clickedFeature); +- m_clickedFeature->activateChild(m_clickedIndex); +- m_clickedFeature->onRightClickChild(globalPos, m_clickedIndex); ++ LibraryFeature* feature = tree_item->feature(); ++ feature->activateChild(index); ++ feature->onRightClickChild(globalPos, index); + } + } + } +diff --git a/src/library/sidebarmodel.h b/src/library/sidebarmodel.h +index 17c3bb8cae..3dc4891ed3 100644 +--- a/src/library/sidebarmodel.h ++++ b/src/library/sidebarmodel.h +@@ -38,6 +38,7 @@ class SidebarModel : public QAbstractItemModel { + bool hasTrackTable(const QModelIndex& index) const; + + public slots: ++ void pressed(const QModelIndex& index); + void clicked(const QModelIndex& index); + void doubleClicked(const QModelIndex& index); + void rightClicked(const QPoint& globalPos, const QModelIndex& index); +@@ -67,7 +68,7 @@ class SidebarModel : public QAbstractItemModel { + void selectIndex(const QModelIndex& index); + + private slots: +- void slotActivateChildAtClickedFeatureIndex(); ++ void slotPressedUntilClickedTimeout(); + + private: + QModelIndex translateSourceIndex(const QModelIndex& parent); +@@ -75,13 +76,11 @@ class SidebarModel : public QAbstractItemModel { + QList m_sFeatures; + unsigned int m_iDefaultSelectedIndex; /** Index of the item in the sidebar model to select at startup. */ + +- QTimer* const m_clickedChildActivationTimer; +- LibraryFeature* m_clickedFeature; +- QModelIndex m_clickedIndex; ++ QTimer* const m_pressedUntilClickedTimer; ++ QModelIndex m_pressedIndex; + +- void onFeatureIndexClicked( +- LibraryFeature* feature, +- QModelIndex index); ++ void startPressedUntilClickedTimer(QModelIndex pressedIndex); ++ void stopPressedUntilClickedTimer(); + }; + + #endif /* SIDEBARMODEL_H */ diff --git a/media-sound/mixxx/files/mixxx-2.1.0-fix-s4-mk2-for-windows.patch b/media-sound/mixxx/files/mixxx-2.1.0-fix-s4-mk2-for-windows.patch new file mode 100644 index 0000000..7764057 --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-fix-s4-mk2-for-windows.patch @@ -0,0 +1,51 @@ +From dcf6f17012d95c70df50446222e43772dac4dc52 Mon Sep 17 00:00:00 2001 +From: Fayaaz Ahmed +Date: Mon, 23 Apr 2018 23:31:47 +0100 +Subject: [PATCH 1/2] Fix Traktor S4 MK2 for windows + +--- + res/controllers/Traktor-Kontrol-S4-MK2-hid-scripts.js | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/res/controllers/Traktor-Kontrol-S4-MK2-hid-scripts.js b/res/controllers/Traktor-Kontrol-S4-MK2-hid-scripts.js +index f4689659f9..de05f5eeee 100644 +--- a/res/controllers/Traktor-Kontrol-S4-MK2-hid-scripts.js ++++ b/res/controllers/Traktor-Kontrol-S4-MK2-hid-scripts.js +@@ -790,7 +790,11 @@ TraktorS4MK2.incomingData = function(data, length) { + this.partial_packet = Object(); + return; + } +- ++ if (length == 79) { ++ // Windows seems to get the packet of length 79, so parse as one: ++ TraktorS4MK2.controller.parsePacket(data, data.length); ++ return; ++ } + HIDDebug("Traktor S4MK2: Unhandled packet size: " + length); + } + + +From e4161f90f37ad1bb2c5f23fa388c198c2bef733e Mon Sep 17 00:00:00 2001 +From: Fayaaz Ahmed +Date: Mon, 23 Apr 2018 23:34:59 +0100 +Subject: [PATCH 2/2] Update Traktor-Kontrol-S4-MK2-hid-scripts.js + +--- + res/controllers/Traktor-Kontrol-S4-MK2-hid-scripts.js | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/res/controllers/Traktor-Kontrol-S4-MK2-hid-scripts.js b/res/controllers/Traktor-Kontrol-S4-MK2-hid-scripts.js +index de05f5eeee..8cd0b85406 100644 +--- a/res/controllers/Traktor-Kontrol-S4-MK2-hid-scripts.js ++++ b/res/controllers/Traktor-Kontrol-S4-MK2-hid-scripts.js +@@ -791,8 +791,8 @@ TraktorS4MK2.incomingData = function(data, length) { + return; + } + if (length == 79) { +- // Windows seems to get the packet of length 79, so parse as one: +- TraktorS4MK2.controller.parsePacket(data, data.length); ++ // Windows seems to get the packet of length 79, so parse as one: ++ TraktorS4MK2.controller.parsePacket(data, data.length); + return; + } + HIDDebug("Traktor S4MK2: Unhandled packet size: " + length); diff --git a/media-sound/mixxx/files/mixxx-2.1.0-fix-unresponsive-scrolling-through-crates-and-playlists-using-encoder.patch b/media-sound/mixxx/files/mixxx-2.1.0-fix-unresponsive-scrolling-through-crates-and-playlists-using-encoder.patch new file mode 100644 index 0000000..1c74123 --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-fix-unresponsive-scrolling-through-crates-and-playlists-using-encoder.patch @@ -0,0 +1,281 @@ +From 360f9881848ebba244338101fdf3e47e45e9ece8 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Tue, 17 Apr 2018 00:31:42 +0200 +Subject: [PATCH] Fix unresponsive scrolling through crates & playlists with + encoder + +--- + src/library/baseplaylistfeature.cpp | 8 ++++++- + src/library/crate/cratefeature.cpp | 4 +++- + src/library/libraryfeature.cpp | 29 +++++++++++++++++++---- + src/library/libraryfeature.h | 21 +++++++++++++---- + src/library/sidebarmodel.cpp | 47 +++++++++++++++++++++++++++---------- + src/library/sidebarmodel.h | 17 ++++++++++++-- + 6 files changed, 100 insertions(+), 26 deletions(-) + +diff --git a/src/library/baseplaylistfeature.cpp b/src/library/baseplaylistfeature.cpp +index 2cfd68e974..c0506e458d 100644 +--- a/src/library/baseplaylistfeature.cpp ++++ b/src/library/baseplaylistfeature.cpp +@@ -19,11 +19,17 @@ + #include "widget/wlibrarytextbrowser.h" + #include "util/assert.h" + ++namespace { ++ ++const int kClickedChildActivationTimeoutMillis = 100; ++ ++} // anonymous namespace ++ + BasePlaylistFeature::BasePlaylistFeature(QObject* parent, + UserSettingsPointer pConfig, + TrackCollection* pTrackCollection, + QString rootViewName) +- : LibraryFeature(pConfig, parent), ++ : LibraryFeature(pConfig, kClickedChildActivationTimeoutMillis, parent), + m_pTrackCollection(pTrackCollection), + m_playlistDao(pTrackCollection->getPlaylistDAO()), + m_trackDao(pTrackCollection->getTrackDAO()), +diff --git a/src/library/crate/cratefeature.cpp b/src/library/crate/cratefeature.cpp +index 38c09b0eb8..da75522e39 100644 +--- a/src/library/crate/cratefeature.cpp ++++ b/src/library/crate/cratefeature.cpp +@@ -29,6 +29,8 @@ + + namespace { + ++const int kClickedChildActivationTimeoutMillis = 100; ++ + QString formatLabel( + const CrateSummary& crateSummary) { + return QString("%1 (%2) %3").arg( +@@ -42,7 +44,7 @@ QString formatLabel( + CrateFeature::CrateFeature(Library* pLibrary, + TrackCollection* pTrackCollection, + UserSettingsPointer pConfig) +- : LibraryFeature(pConfig), ++ : LibraryFeature(pConfig, kClickedChildActivationTimeoutMillis), + m_cratesIcon(":/images/library/ic_library_crates.png"), + m_lockedCrateIcon(":/images/library/ic_library_locked.png"), + m_pTrackCollection(pTrackCollection), +diff --git a/src/library/libraryfeature.cpp b/src/library/libraryfeature.cpp +index efe20d2e9d..e582557370 100644 +--- a/src/library/libraryfeature.cpp ++++ b/src/library/libraryfeature.cpp +@@ -6,18 +6,37 @@ + // KEEP THIS cpp file to tell scons that moc should be called on the class!!! + // The reason for this is that LibraryFeature uses slots/signals and for this + // to work the code has to be precompiles by moc +-LibraryFeature::LibraryFeature(QObject *parent) +- : QObject(parent) { + ++LibraryFeature::LibraryFeature( ++ QObject *parent) ++ : QObject(parent), ++ m_clickedChildActivationTimeoutMillis(0) { + } + +-LibraryFeature::LibraryFeature(UserSettingsPointer pConfig, QObject* parent) ++LibraryFeature::LibraryFeature( ++ int clickedChildActivationTimeoutMillis, ++ QObject *parent) + : QObject(parent), +- m_pConfig(pConfig) { ++ m_clickedChildActivationTimeoutMillis(clickedChildActivationTimeoutMillis) { ++ DEBUG_ASSERT(m_clickedChildActivationTimeoutMillis >= 0); + } + +-LibraryFeature::~LibraryFeature() { ++LibraryFeature::LibraryFeature( ++ UserSettingsPointer pConfig, ++ QObject* parent) ++ : QObject(parent), ++ m_pConfig(pConfig), ++ m_clickedChildActivationTimeoutMillis(0) { ++} + ++LibraryFeature::LibraryFeature( ++ UserSettingsPointer pConfig, ++ int clickedChildActivationTimeoutMillis, ++ QObject* parent) ++ : QObject(parent), ++ m_pConfig(pConfig), ++ m_clickedChildActivationTimeoutMillis(clickedChildActivationTimeoutMillis) { ++ DEBUG_ASSERT(m_clickedChildActivationTimeoutMillis >= 0); + } + + QStringList LibraryFeature::getPlaylistFiles(QFileDialog::FileMode mode) const { +diff --git a/src/library/libraryfeature.h b/src/library/libraryfeature.h +index 138d96c1aa..7639e03557 100644 +--- a/src/library/libraryfeature.h ++++ b/src/library/libraryfeature.h +@@ -29,11 +29,23 @@ class KeyboardEventFilter; + class LibraryFeature : public QObject { + Q_OBJECT + public: +- LibraryFeature(QObject* parent = NULL); ++ explicit LibraryFeature( ++ QObject* parent); ++ explicit LibraryFeature( ++ int clickedChildActivationTimeoutMillis, ++ QObject* parent = nullptr); ++ explicit LibraryFeature( ++ UserSettingsPointer pConfig, ++ QObject* parent = nullptr); ++ explicit LibraryFeature( ++ UserSettingsPointer pConfig, ++ int clickedChildActivationTimeoutMillis, ++ QObject* parent = nullptr); ++ ~LibraryFeature() override = default; + +- LibraryFeature(UserSettingsPointer pConfig, +- QObject* parent = NULL); +- virtual ~LibraryFeature(); ++ int clickedChildActivationTimeoutMillis() const { ++ return m_clickedChildActivationTimeoutMillis; ++ } + + virtual QVariant title() = 0; + virtual QIcon getIcon() = 0; +@@ -124,6 +136,7 @@ class LibraryFeature : public QObject { + private: + QStringList getPlaylistFiles(QFileDialog::FileMode mode) const; + ++ const int m_clickedChildActivationTimeoutMillis; + }; + + #endif /* LIBRARYFEATURE_H */ +diff --git a/src/library/sidebarmodel.cpp b/src/library/sidebarmodel.cpp +index e0943bb40f..c2bb5d198b 100644 +--- a/src/library/sidebarmodel.cpp ++++ b/src/library/sidebarmodel.cpp +@@ -8,13 +8,14 @@ + #include "library/browse/browsefeature.h" + #include "util/assert.h" + +-SidebarModel::SidebarModel(QObject* parent) ++SidebarModel::SidebarModel( ++ QObject* parent) + : QAbstractItemModel(parent), +- m_iDefaultSelectedIndex(0) { +-} +- +-SidebarModel::~SidebarModel() { +- ++ m_iDefaultSelectedIndex(0), ++ m_clickedChildActivationTimer(new QTimer(this)), ++ m_clickedFeature(nullptr) { ++ m_clickedChildActivationTimer->setSingleShot(true); ++ connect(m_clickedChildActivationTimer, SIGNAL(timeout()), this, SLOT(slotActivateChildAtClickedFeatureIndex())); + } + + void SidebarModel::addLibraryFeature(LibraryFeature* feature) { +@@ -221,6 +222,20 @@ QVariant SidebarModel::data(const QModelIndex& index, int role) const { + return QVariant(); + } + ++void SidebarModel::onFeatureIndexClicked( ++ LibraryFeature* feature, ++ QModelIndex index) { ++ m_clickedChildActivationTimer->stop(); ++ m_clickedFeature = feature; ++ m_clickedIndex = index; ++} ++ ++void SidebarModel::slotActivateChildAtClickedFeatureIndex() { ++ if (m_clickedFeature) { ++ m_clickedFeature->activateChild(m_clickedIndex); ++ } ++} ++ + void SidebarModel::clicked(const QModelIndex& index) { + //qDebug() << "SidebarModel::clicked() index=" << index; + +@@ -236,8 +251,12 @@ void SidebarModel::clicked(const QModelIndex& index) { + } else { + TreeItem* tree_item = (TreeItem*)index.internalPointer(); + if (tree_item) { +- LibraryFeature* feature = tree_item->feature(); +- feature->activateChild(index); ++ onFeatureIndexClicked(tree_item->feature(), index); ++ DEBUG_ASSERT(m_clickedFeature); ++ // Deferred activation is required for smooth scrolling when using ++ // encoder knobs ++ m_clickedChildActivationTimer->start( ++ m_clickedFeature->clickedChildActivationTimeoutMillis()); + } + } + } +@@ -249,8 +268,9 @@ void SidebarModel::doubleClicked(const QModelIndex& index) { + } else { + TreeItem* tree_item = (TreeItem*)index.internalPointer(); + if (tree_item) { +- LibraryFeature* feature = tree_item->feature(); +- feature->onLazyChildExpandation(index); ++ onFeatureIndexClicked(tree_item->feature(), index); ++ DEBUG_ASSERT(m_clickedFeature); ++ m_clickedFeature->onLazyChildExpandation(m_clickedIndex); + } + } + } +@@ -267,9 +287,10 @@ void SidebarModel::rightClicked(const QPoint& globalPos, const QModelIndex& inde + { + TreeItem* tree_item = (TreeItem*)index.internalPointer(); + if (tree_item) { +- LibraryFeature* feature = tree_item->feature(); +- feature->activateChild(index); +- feature->onRightClickChild(globalPos, index); ++ onFeatureIndexClicked(tree_item->feature(), index); ++ DEBUG_ASSERT(m_clickedFeature); ++ m_clickedFeature->activateChild(m_clickedIndex); ++ m_clickedFeature->onRightClickChild(globalPos, m_clickedIndex); + } + } + } +diff --git a/src/library/sidebarmodel.h b/src/library/sidebarmodel.h +index 0040d2119d..17c3bb8cae 100644 +--- a/src/library/sidebarmodel.h ++++ b/src/library/sidebarmodel.h +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + + class LibraryFeature; +@@ -14,8 +15,9 @@ class LibraryFeature; + class SidebarModel : public QAbstractItemModel { + Q_OBJECT + public: +- explicit SidebarModel(QObject* parent = 0); +- virtual ~SidebarModel(); ++ explicit SidebarModel( ++ QObject* parent = nullptr); ++ ~SidebarModel() override = default; + + void addLibraryFeature(LibraryFeature* feature); + QModelIndex getDefaultSelection(); +@@ -64,11 +66,22 @@ class SidebarModel : public QAbstractItemModel { + signals: + void selectIndex(const QModelIndex& index); + ++ private slots: ++ void slotActivateChildAtClickedFeatureIndex(); ++ + private: + QModelIndex translateSourceIndex(const QModelIndex& parent); + void featureRenamed(LibraryFeature*); + QList m_sFeatures; + unsigned int m_iDefaultSelectedIndex; /** Index of the item in the sidebar model to select at startup. */ ++ ++ QTimer* const m_clickedChildActivationTimer; ++ LibraryFeature* m_clickedFeature; ++ QModelIndex m_clickedIndex; ++ ++ void onFeatureIndexClicked( ++ LibraryFeature* feature, ++ QModelIndex index); + }; + + #endif /* SIDEBARMODEL_H */ diff --git a/media-sound/mixxx/files/mixxx-2.1.0-swap-default-values-for-temp-perm-ratechanges.patch b/media-sound/mixxx/files/mixxx-2.1.0-swap-default-values-for-temp-perm-ratechanges.patch new file mode 100644 index 0000000..8f2441a --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-swap-default-values-for-temp-perm-ratechanges.patch @@ -0,0 +1,31 @@ +From 4148349efe700106de3c347708d5d8429c1ffbeb Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Mon, 16 Apr 2018 07:26:51 +0200 +Subject: [PATCH] Swap default values for temp/perm rate changes + +--- + src/preferences/dialog/dlgprefdeck.cpp | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/preferences/dialog/dlgprefdeck.cpp b/src/preferences/dialog/dlgprefdeck.cpp +index 6cf2e0c327..0f73b68f3c 100644 +--- a/src/preferences/dialog/dlgprefdeck.cpp ++++ b/src/preferences/dialog/dlgprefdeck.cpp +@@ -198,13 +198,13 @@ DlgPrefDeck::DlgPrefDeck(QWidget * parent, MixxxMainWindow * mixxx, + this, SLOT(slotRatePermFineSpinbox(double))); + + m_dRateTempCoarse = m_pConfig->getValue(ConfigKey("[Controls]", "RateTempLeft"), +- kDefaultPermanentRateChangeCoarse); ++ kDefaultTemporaryRateChangeCoarse); + m_dRateTempFine = m_pConfig->getValue(ConfigKey("[Controls]", "RateTempRight"), +- kDefaultPermanentRateChangeFine); ++ kDefaultTemporaryRateChangeFine); + m_dRatePermCoarse = m_pConfig->getValue(ConfigKey("[Controls]", "RatePermLeft"), +- kDefaultTemporaryRateChangeCoarse); ++ kDefaultPermanentRateChangeCoarse); + m_dRatePermFine = m_pConfig->getValue(ConfigKey("[Controls]", "RatePermRight"), +- kDefaultTemporaryRateChangeFine); ++ kDefaultPermanentRateChangeFine); + + spinBoxTemporaryRateCoarse->setValue(m_dRateTempCoarse); + spinBoxTemporaryRateFine->setValue(m_dRateTempFine); diff --git a/media-sound/mixxx/files/mixxx-2.1.0-use-an-in-memory-database-to-speed-up-library-tests.patch b/media-sound/mixxx/files/mixxx-2.1.0-use-an-in-memory-database-to-speed-up-library-tests.patch new file mode 100644 index 0000000..f102ccd --- /dev/null +++ b/media-sound/mixxx/files/mixxx-2.1.0-use-an-in-memory-database-to-speed-up-library-tests.patch @@ -0,0 +1,79 @@ +From e41777469701d85069680984b6365fe7a22fd537 Mon Sep 17 00:00:00 2001 +From: Uwe Klotz +Date: Tue, 24 Apr 2018 00:56:02 +0200 +Subject: [PATCH] Use an in-memory database to speed up library tests + +--- + src/database/mixxxdb.cpp | 10 ++++++---- + src/database/mixxxdb.h | 3 ++- + src/test/librarytest.h | 5 ++++- + 3 files changed, 12 insertions(+), 6 deletions(-) + +diff --git a/src/database/mixxxdb.cpp b/src/database/mixxxdb.cpp +index 2046129b44..ef01bcc0f1 100644 +--- a/src/database/mixxxdb.cpp ++++ b/src/database/mixxxdb.cpp +@@ -19,11 +19,12 @@ const mixxx::Logger kLogger("MixxxDb"); + + // The connection parameters for the main Mixxx DB + mixxx::DbConnection::Params dbConnectionParams( +- const UserSettingsPointer& pConfig) { ++ const UserSettingsPointer& pConfig, ++ bool inMemoryConnection) { + mixxx::DbConnection::Params params; + params.type = "QSQLITE"; + params.hostName = "localhost"; +- params.filePath = QDir(pConfig->getSettingsPath()).filePath("mixxxdb.sqlite"); ++ params.filePath = inMemoryConnection ? QString(":memory:") : QDir(pConfig->getSettingsPath()).filePath("mixxxdb.sqlite"); + params.userName = "mixxx"; + params.password = "mixxx"; + return params; +@@ -32,8 +33,9 @@ mixxx::DbConnection::Params dbConnectionParams( + } // anonymous namespace + + MixxxDb::MixxxDb( +- const UserSettingsPointer& pConfig) +- : m_pDbConnectionPool(std::make_shared(dbConnectionParams(pConfig), "MIXXX")) { ++ const UserSettingsPointer& pConfig, ++ bool inMemoryConnection) ++ : m_pDbConnectionPool(std::make_shared(dbConnectionParams(pConfig, inMemoryConnection), "MIXXX")) { + } + + bool MixxxDb::initDatabaseSchema( +diff --git a/src/database/mixxxdb.h b/src/database/mixxxdb.h +index 4e5fe77182..0ca67631bc 100644 +--- a/src/database/mixxxdb.h ++++ b/src/database/mixxxdb.h +@@ -23,7 +23,8 @@ class MixxxDb : public QObject { + int schemaVersion = kRequiredSchemaVersion); + + explicit MixxxDb( +- const UserSettingsPointer& pConfig); ++ const UserSettingsPointer& pConfig, ++ bool inMemoryConnection = false); + + mixxx::DbConnectionPoolPtr connectionPool() const { + return m_pDbConnectionPool; +diff --git a/src/test/librarytest.h b/src/test/librarytest.h +index 1baae898cf..7cf4459a21 100644 +--- a/src/test/librarytest.h ++++ b/src/test/librarytest.h +@@ -9,6 +9,9 @@ + #include "util/db/dbconnectionpooled.h" + #include "track/globaltrackcache.h" + ++namespace { ++ const bool kInMemoryDbConnection = true; ++} // anonymous namespace + + class LibraryTest : public MixxxTest, + public virtual /*implements*/ GlobalTrackCacheSaver { +@@ -21,7 +24,7 @@ class LibraryTest : public MixxxTest, + + protected: + LibraryTest() +- : m_mixxxDb(config()), ++ : m_mixxxDb(config(), kInMemoryDbConnection), + m_dbConnectionPooler(m_mixxxDb.connectionPool()), + m_dbConnection(mixxx::DbConnectionPooled(m_mixxxDb.connectionPool())), + m_trackCollection(config()) { diff --git a/media-sound/mixxx/mixxx-2.1.0.ebuild b/media-sound/mixxx/mixxx-2.1.0.ebuild index b32c1b0..bb04a13 100644 --- a/media-sound/mixxx/mixxx-2.1.0.ebuild +++ b/media-sound/mixxx/mixxx-2.1.0.ebuild @@ -11,11 +11,9 @@ SRC_URI="https://github.com/mixxxdj/${PN}/archive/release-${PV}.tar.gz -> ${P}-s LICENSE="GPL-2" SLOT="0" -KEYWORDS="amd64 x86" +KEYWORDS="~amd64 ~x86" IUSE="aac doc ffmpeg hid mp3 mp4 shout wavpack" -# fails to compile system-fidlib. Add ">media-libs/fidlib-0.9.10-r1" once this -# got fixed RDEPEND=" dev-db/sqlite dev-libs/protobuf:0= @@ -56,7 +54,6 @@ RDEPEND=" wavpack? ( media-sound/wavpack ) ffmpeg? ( media-video/ffmpeg:0= ) " -# media-libs/rubberband RDEPENDs on sci-libs/fftw:3.0 DEPEND=" ${RDEPEND} virtual/pkgconfig @@ -66,6 +63,20 @@ DEPEND=" PATCHES=( "${FILESDIR}"/${PN}-2.0.0-docs.patch + "${FILESDIR}"/${P}-swap-default-values-for-temp-perm-ratechanges.patch + "${FILESDIR}"/${P}-fix-invocation-args-of-pasuspender.patch + "${FILESDIR}"/${P}-fix-unresponsive-scrolling-through-crates-and-playlists-using-encoder.patch + "${FILESDIR}"/${P}-debug-assert-and-fix-false-poisitiv-restart-request.patch + "${FILESDIR}"/${P}-fidlib-thread-safe-and-reentrant-generation-of-filters.patch + "${FILESDIR}"/${P}-fix-navigation-usability-issues-in-sidebar-tree.patch + "${FILESDIR}"/${P}-fix-latenight-group-fx-buttons-in-deck.patch + "${FILESDIR}"/${P}-fix-crash-when-removing-a-quick-link.patch + "${FILESDIR}"/${P}-fix-clearing-of-replaygain-gain-ratio-in-file-tags.patch + "${FILESDIR}"/${P}-fix-memory-leak-when-loading-cover-art.patch + "${FILESDIR}"/${P}-use-an-in-memory-database-to-speed-up-library-tests.patch + "${FILESDIR}"/${P}-fix-integration-of-external-track-libraries.patch + "${FILESDIR}"/${P}-fix-flac-decoding-and-upgrade-db-schema.patch + "${FILESDIR}"/${P}-fix-s4-mk2-for-windows.patch ) S="${WORKDIR}/${PN}-release-${PV}"