1
0
mirror of https://github.com/dguglielmi/sunny-overlay.git synced 2025-12-06 11:42:40 +01:00

- media-sound/mixxx: re-add mixxx to fix Qt5 issues

Mixxx is compiled with Qt5 in ~gx86 and some core features are broken
with Qt5, so we need to backport those following patches.

- https://github.com/mixxxdj/mixxx/pull/845/commits
- https://github.com/mixxxdj/mixxx/pull/848/commits
This commit is contained in:
2017-02-04 22:53:00 +01:00
parent 88a29c1c26
commit 09a17d9652
11 changed files with 1070 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
Backported chromaprint-1.4 API changes based on the fix suggested in:
https://github.com/mixxxdj/mixxx/pull/1073
and the work done by Charlie Gehlin in:
https://bugs.gentoo.org/604528
--- mixxx-2.0.0/src/musicbrainz/chromaprinter.cpp
+++ mixxx-2.0.0/src/musicbrainz/chromaprinter.cpp
@@ -25,6 +25,16 @@
QString ChromaPrinter::calcFingerPrint(const Mixxx::SoundSourcePointer& pSoundSource) {
+ // Type declarations of *fprint and *encoded pointers need to account for Chromaprint API version
+ // (void* -> uint32_t*) and (void* -> char*) changed in versions v1.4.0 or later -- alyptik 12/2016
+ #if (CHROMAPRINT_VERSION_MINOR > 3) || (CHROMAPRINT_VERSION_MAJOR > 1)
+ typedef uint32_t* uint32_p;
+ typedef char* char_p;
+ #else
+ typedef void* uint32_p;
+ typedef void* char_p;
+ #endif
+
// this is worth 2min of audio, multiply by 2 because we have 2 channels
// AcoustID only stores a fingerprint for the first two minutes of a song
// on their server so we need only a fingerprint of the first two minutes
@@ -57,12 +67,12 @@
}
chromaprint_finish(ctx);
- void* fprint = NULL;
+ uint32_p fprint = NULL;
int size = 0;
int ret = chromaprint_get_raw_fingerprint(ctx, &fprint, &size);
QByteArray fingerprint;
if (ret == 1) {
- void* encoded = NULL;
+ char_p encoded = NULL;
int encoded_size = 0;
chromaprint_encode_fingerprint(fprint, size,
CHROMAPRINT_ALGORITHM_DEFAULT,

View File

@@ -0,0 +1,10 @@
--- mixxx-9999/src/SConscript
+++ mixxx-9999/src/SConscript
@@ -290,7 +290,6 @@
env.Alias('install', controllermappings)
env.Alias('install', translations)
env.Alias('install', keyboardmappings)
- env.Alias('install', docs)
env.Alias('install', dotdesktop)
env.Alias('install', icon)
env.Alias('install', promotracks)

View File

@@ -0,0 +1,55 @@
diff -dNur a/src/analyserwaveform.cpp b/src/analyserwaveform.cpp
--- a/src/analyserwaveform.cpp 2015-12-29 17:10:41.000000000 +0100
+++ b/src/analyserwaveform.cpp 2017-02-04 21:12:30.127952910 +0100
@@ -1,6 +1,3 @@
-#include <QImage>
-#include <QtDebug>
-#include <QTime>
#include <QtDebug>
#include "analyserwaveform.h"
@@ -40,7 +37,6 @@
}
}
- m_timer = new QTime();
m_analysisDao = new AnalysisDao(m_database, pConfig);
}
@@ -48,14 +44,13 @@
qDebug() << "AnalyserWaveform::~AnalyserWaveform()";
destroyFilters();
m_database.close();
- delete m_timer;
delete m_analysisDao;
}
bool AnalyserWaveform::initialise(TrackPointer tio, int sampleRate, int totalSamples) {
m_skipProcessing = false;
- m_timer->start();
+ m_timer.start();
if (totalSamples == 0) {
qWarning() << "AnalyserWaveform::initialise - no waveform/waveform summary";
@@ -320,7 +315,7 @@
#endif
qDebug() << "Waveform generation for track" << tio->getId() << "done"
- << m_timer->elapsed()/1000.0 << "s";
+ << m_timer.elapsed()/1000.0 << "s";
}
void AnalyserWaveform::storeIfGreater(float* pDest, float source) {
diff -dNur a/src/analyserwaveform.h b/src/analyserwaveform.h
--- a/src/analyserwaveform.h 2015-12-29 17:10:41.000000000 +0100
+++ b/src/analyserwaveform.h 2017-02-04 21:12:45.367713395 +0100
@@ -171,7 +171,7 @@
EngineFilterIIRBase* m_filter[FilterCount];
std::vector<float> m_buffers[FilterCount];
- QTime* m_timer;
+ QTime m_timer;
QSqlDatabase m_database;
AnalysisDao* m_analysisDao;

View File

@@ -0,0 +1,24 @@
From 76c53b0f0a2be7b5cf85fa523f3521a5725affb2 Mon Sep 17 00:00:00 2001
From: Uwe Klotz <uwe_klotz@web.de>
Date: Fri, 8 Jan 2016 18:22:33 +0100
Subject: [PATCH] Fix formatting of time durations
---
src/util/time.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/util/time.h b/src/util/time.h
index 29187ad..7b38eb4 100644
--- a/src/util/time.h
+++ b/src/util/time.h
@@ -75,7 +75,9 @@ class Time {
const int days = static_cast<int>(dSeconds) / kSecondsPerDay;
dSeconds -= days * kSecondsPerDay;
- QTime t = QTime().addMSecs(dSeconds * kMillisPerSecond);
+ // NOTE(uklotzde): Time() constructs a 'null' object, but
+ // we need 'zero' here.
+ QTime t = QTime(0, 0).addMSecs(dSeconds * kMillisPerSecond);
QString formatString =
(days > 0 ? (QString::number(days) %

View File

@@ -0,0 +1,139 @@
diff -dNur a/src/library/basesqltablemodel.cpp b/src/library/basesqltablemodel.cpp
--- a/src/library/basesqltablemodel.cpp 2015-12-29 17:10:41.000000000 +0100
+++ b/src/library/basesqltablemodel.cpp 2017-02-04 21:33:39.403861857 +0100
@@ -559,7 +559,7 @@
if (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_DURATION)) {
int duration = value.toInt();
if (duration > 0) {
- value = Time::formatSeconds(duration, false);
+ value = Time::formatSeconds(duration);
} else {
value = QString();
}
diff -dNur a/src/library/browse/browsethread.cpp b/src/library/browse/browsethread.cpp
--- a/src/library/browse/browsethread.cpp 2015-12-29 17:10:41.000000000 +0100
+++ b/src/library/browse/browsethread.cpp 2017-02-04 21:32:23.605066421 +0100
@@ -185,8 +185,7 @@
item->setData(item->text(), Qt::UserRole);
row_data.insert(COLUMN_COMMENT, item);
- QString duration = Time::formatSeconds(qVariantValue<int>(
- tio.getDuration()), false);
+ QString duration = Time::formatSeconds(tio.getDuration());
item = new QStandardItem(duration);
item->setToolTip(item->text());
item->setData(item->text(), Qt::UserRole);
diff -dNur a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp
--- a/src/library/cratefeature.cpp 2015-12-29 17:10:41.000000000 +0100
+++ b/src/library/cratefeature.cpp 2017-02-04 21:30:54.962474898 +0100
@@ -493,7 +493,7 @@
crateListTableModel.index(row, durationColumn)).toInt();
m_crateList.append(qMakePair(id, QString("%1 (%2) %3")
.arg(name, QString::number(count),
- Time::formatSeconds(duration, false))));
+ Time::formatSeconds(duration))));
}
}
diff -dNur a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp
--- a/src/library/playlistfeature.cpp 2015-12-29 17:10:41.000000000 +0100
+++ b/src/library/playlistfeature.cpp 2017-02-04 21:33:06.920378091 +0100
@@ -168,7 +168,7 @@
playlistTableModel.index(row, durationColumn)).toInt();
m_playlistList.append(qMakePair(id, QString("%1 (%2) %3")
.arg(name, QString::number(count),
- Time::formatSeconds(duration, false))));
+ Time::formatSeconds(duration))));
}
}
diff -dNur a/src/trackinfoobject.cpp b/src/trackinfoobject.cpp
--- a/src/trackinfoobject.cpp 2015-12-29 17:10:41.000000000 +0100
+++ b/src/trackinfoobject.cpp 2017-02-04 21:42:36.423323807 +0100
@@ -293,7 +293,7 @@
int iDuration = m_iDuration;
lock.unlock();
- return Time::formatSeconds(iDuration, false);
+ return Time::formatSeconds(iDuration);
}
void TrackInfoObject::setLocation(const QString& location) {
diff -dNur a/src/util/time.cpp b/src/util/time.cpp
--- a/src/util/time.cpp 2017-02-04 21:29:44.439595305 +0100
+++ b/src/util/time.cpp 2017-02-04 21:37:54.739803100 +0100
@@ -1,5 +1,7 @@
#include "util/time.h"
+#include "util/assert.h"
+
// static
LLTIMER Time::s_timer;
// static
@@ -8,7 +10,7 @@
qint64 Time::s_testElapsed_nsecs = 0;
// static
-QString Time::formatSeconds(double dSeconds, bool showCentis) {
+QString Time::formatSeconds(double dSeconds, Precision precision) {
if (dSeconds < 0) {
return "?";
}
@@ -24,13 +26,14 @@
(days > 0 ? (QString::number(days) %
QLatin1String("'d', ")) : QString()) %
QLatin1String(days > 0 || t.hour() > 0 ? "hh:mm:ss" : "mm:ss") %
- QLatin1String(showCentis ? ".zzz" : "");
+ QLatin1String(Precision::SECONDS == precision ? "" : ".zzz");
QString timeString = t.toString(formatString);
// The format string gives us milliseconds but we want
// centiseconds. Slice one character off.
- if (showCentis) {
+ if (Precision::CENTISECONDS == precision) {
+ DEBUG_ASSERT(1 <= timeString.length());
timeString = timeString.left(timeString.length() - 1);
}
diff -dNur a/src/util/time.h b/src/util/time.h
--- a/src/util/time.h 2017-02-04 21:29:44.439595305 +0100
+++ b/src/util/time.h 2017-02-04 21:41:01.476833822 +0100
@@ -55,10 +55,17 @@
s_testElapsed_nsecs = elapsed * 1000000;
}
- // The standard way of formatting a time in seconds. Used for display of
- // track duration, etc. showCentis indicates whether to include
- // centisecond-precision or to round to the nearest second.
- static QString formatSeconds(double dSeconds, bool showCentis);
+ enum class Precision {
+ SECONDS,
+ CENTISECONDS,
+ MILLISECONDS
+ };
+
+ // The standard way of formatting a time in seconds. Used for display
+ // of track duration, etc.
+ static QString formatSeconds(
+ double dSeconds,
+ Precision precision = Time::Precision::SECONDS);
private:
static LLTIMER s_timer;
diff -dNur a/src/widget/wnumberpos.cpp b/src/widget/wnumberpos.cpp
--- a/src/widget/wnumberpos.cpp 2015-12-29 17:10:41.000000000 +0100
+++ b/src/widget/wnumberpos.cpp 2017-02-04 21:41:57.023950430 +0100
@@ -92,10 +92,10 @@
QString valueString;
if (valueMillis >= 0) {
valueString = m_skinText % Time::formatSeconds(
- valueMillis / Time::kMillisPerSecond, true);
+ valueMillis / Time::kMillisPerSecond, Time::Precision::MILLISECONDS);
} else {
valueString = m_skinText % QLatin1String("-") % Time::formatSeconds(
- -valueMillis / Time::kMillisPerSecond, true);
+ -valueMillis / Time::kMillisPerSecond, Time::Precision::CENTISECONDS);
}
setText(valueString);
}

View File

@@ -0,0 +1,271 @@
diff -dNur a/src/analyserwaveform.cpp b/src/analyserwaveform.cpp
--- a/src/analyserwaveform.cpp 2017-02-04 21:14:33.266016824 +0100
+++ b/src/analyserwaveform.cpp 2017-02-04 21:19:09.205671982 +0100
@@ -11,8 +11,8 @@
AnalyserWaveform::AnalyserWaveform(ConfigObject<ConfigValue>* pConfig) :
m_skipProcessing(false),
- m_waveformData(NULL),
- m_waveformSummaryData(NULL),
+ m_waveformData(nullptr),
+ m_waveformSummaryData(nullptr),
m_stride(0, 0),
m_currentStride(0),
m_currentSummaryStride(0) {
@@ -37,14 +37,13 @@
}
}
- m_analysisDao = new AnalysisDao(m_database, pConfig);
+ m_pAnalysisDao = std::make_unique<AnalysisDao>(m_database, pConfig);
}
AnalyserWaveform::~AnalyserWaveform() {
qDebug() << "AnalyserWaveform::~AnalyserWaveform()";
destroyFilters();
m_database.close();
- delete m_analysisDao;
}
bool AnalyserWaveform::initialise(TrackPointer tio, int sampleRate, int totalSamples) {
@@ -115,7 +114,7 @@
if (trackId != -1 && (missingWaveform || missingWavesummary)) {
QList<AnalysisDao::AnalysisInfo> analyses =
- m_analysisDao->getAnalysesForTrack(trackId);
+ m_pAnalysisDao->getAnalysesForTrack(trackId);
QListIterator<AnalysisDao::AnalysisInfo> it(analyses);
while (it.hasNext()) {
@@ -130,7 +129,7 @@
missingWaveform = false;
} else if (vc != WaveformFactory::VC_KEEP) {
// remove all other Analysis except that one we should keep
- m_analysisDao->deleteAnalysis(analysis.analysisId);
+ m_pAnalysisDao->deleteAnalysis(analysis.analysisId);
}
} if (analysis.type == AnalysisDao::TYPE_WAVESUMMARY) {
vc = WaveformFactory::waveformSummaryVersionToVersionClass(analysis.version);
@@ -140,7 +139,7 @@
missingWavesummary = false;
} else if (vc != WaveformFactory::VC_KEEP) {
// remove all other Analysis except that one we should keep
- m_analysisDao->deleteAnalysis(analysis.analysisId);
+ m_pAnalysisDao->deleteAnalysis(analysis.analysisId);
}
}
}
@@ -273,13 +272,13 @@
tio->setWaveform(ConstWaveformPointer());
// Since clear() could delete the waveform, clear our pointer to the
// waveform's vector data first.
- m_waveformData = NULL;
+ m_waveformData = nullptr;
m_waveform.clear();
tio->setWaveformSummary(ConstWaveformPointer());
// Since clear() could delete the waveform, clear our pointer to the
// waveform's vector data first.
- m_waveformSummaryData = NULL;
+ m_waveformSummaryData = nullptr;
m_waveformSummary.clear();
}
@@ -295,7 +294,7 @@
m_waveform->setDescription(WaveformFactory::currentWaveformDescription());
// Since clear() could delete the waveform, clear our pointer to the
// waveform's vector data first.
- m_waveformData = NULL;
+ m_waveformData = nullptr;
m_waveform.clear();
}
@@ -306,7 +305,7 @@
m_waveformSummary->setDescription(WaveformFactory::currentWaveformSummaryDescription());
// Since clear() could delete the waveform, clear our pointer to the
// waveform's vector data first.
- m_waveformSummaryData = NULL;
+ m_waveformSummaryData = nullptr;
m_waveformSummary.clear();
}
diff -dNur a/src/analyserwaveform.h b/src/analyserwaveform.h
--- a/src/analyserwaveform.h 2017-02-04 21:14:33.266016824 +0100
+++ b/src/analyserwaveform.h 2017-02-04 21:20:17.308598419 +0100
@@ -4,12 +4,14 @@
#include <QTime>
#include <QImage>
#include <QSqlDatabase>
+
#include <limits>
#include "configobject.h"
#include "analyser.h"
#include "waveform/waveform.h"
#include "util/math.h"
+#include "util/memory.h"
//NOTS vrince some test to segment sound, to apply color in the waveform
//#define TEST_HEAT_MAP
@@ -173,7 +175,7 @@
QTime m_timer;
QSqlDatabase m_database;
- AnalysisDao* m_analysisDao;
+ std::unique_ptr<AnalysisDao> m_pAnalysisDao;
#ifdef TEST_HEAT_MAP
QImage* test_heatMap;
diff -dNur a/src/util/memory.h b/src/util/memory.h
--- a/src/util/memory.h 1970-01-01 01:00:00.000000000 +0100
+++ b/src/util/memory.h 2017-02-04 22:19:41.846922929 +0100
@@ -0,0 +1,149 @@
+// Taken from https://github.com/bstreiff/cppbits
+// Thank you Brandon Streiff!
+
+// Implementation of C++14's make_unique for C++11 compilers.
+//
+// This has been tested with:
+// - MSVC 11.0 (Visual Studio 2012)
+// - gcc 4.6.3
+// - Xcode 4.4 (with clang "4.0")
+//
+// It is based off an implementation proposed by Stephan T. Lavavej for
+// inclusion in the C++14 standard:
+// http://isocpp.org/files/papers/N3656.txt
+// Where appropriate, it borrows the use of MSVC's _VARIADIC_EXPAND_0X macro
+// machinery to compensate for lack of variadic templates.
+//
+// This file injects make_unique into the std namespace, which I acknowledge is
+// technically forbidden ([C++11: 17.6.4.2.2.1/1]), but is necessary in order
+// to have syntax compatibility with C++14.
+//
+// I perform compiler version checking for MSVC, gcc, and clang to ensure that
+// we don't add make_unique if it is already there (instead, we include
+// <memory> to get the compiler-provided one). You can override the compiler
+// version checking by defining the symbol COMPILER_SUPPORTS_MAKE_UNIQUE.
+//
+//
+// ===============================================================================
+// This file is released into the public domain. See LICENCE for more information.
+// ===============================================================================
+
+#ifndef MIXXX_UTIL_MEMORY_H
+#define MIXXX_UTIL_MEMORY_H
+
+// If user hasn't specified COMPILER_SUPPORTS_MAKE_UNIQUE then try to figure out
+// based on compiler version if std::make_unique is provided.
+#if !defined(COMPILER_SUPPORTS_MAKE_UNIQUE)
+ // Compiling with -std=c++11 sets __cplusplus=201103L and disables
+ // std::make_unique() from C++14! We need to take this into account.
+ #define CPLUSPLUS_SUPPORTS_MAKE_UNIQUE (__cplusplus > 201103L)
+ #if defined(_MSC_VER)
+ // std::make_unique was added in MSVC 12.0
+ #if _MSC_VER >= 1800 // MSVC 12.0 (Visual Studio 2013)
+ #define COMPILER_SUPPORTS_MAKE_UNIQUE
+ #endif
+ #elif defined(__clang__)
+ // std::make_unique was added in clang 3.4, but not until Xcode 6.
+ // Annoyingly, Apple makes the clang version defines match the version
+ // of Xcode, not the version of clang.
+ #define CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
+ #if defined(__APPLE__) && CLANG_VERSION >= 60000 && CPLUSPLUS_SUPPORTS_MAKE_UNIQUE
+ #define COMPILER_SUPPORTS_MAKE_UNIQUE
+ #elif !defined(__APPLE__) && CLANG_VERSION >= 30400 && CPLUSPLUS_SUPPORTS_MAKE_UNIQUE
+ #define COMPILER_SUPPORTS_MAKE_UNIQUE
+ #endif
+ #elif defined(__GNUC__)
+ // std::make_unique was added in gcc 4.9
+ #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+ #if GCC_VERSION >= 40900 && CPLUSPLUS_SUPPORTS_MAKE_UNIQUE
+ #define COMPILER_SUPPORTS_MAKE_UNIQUE
+ #endif
+ #endif
+#endif
+
+#if defined(COMPILER_SUPPORTS_MAKE_UNIQUE)
+
+// If the compiler supports std::make_unique, then pull in <memory> to get it.
+#include <memory>
+
+#else
+
+// Otherwise, the compiler doesn't provide it, so implement it ourselves.
+
+#include <cstddef>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+namespace std {
+
+template<class _Ty> struct _Unique_if {
+ typedef unique_ptr<_Ty> _Single_object;
+};
+
+template<class _Ty> struct _Unique_if<_Ty[]> {
+ typedef unique_ptr<_Ty[]> _Unknown_bound;
+};
+
+template<class _Ty, size_t N> struct _Unique_if<_Ty[N]> {
+ typedef void _Known_bound;
+};
+
+//
+// template< class T, class... Args >
+// unique_ptr<T> make_unique( Args&&... args);
+//
+
+#if defined(_MSC_VER) && (_MSC_VER < 1800)
+
+// Macro machinery because MSVC 11.0 doesn't support variadic templates.
+// The _VARIADIC_EXPAND_0X stuff is defined in <xstddef>
+#define _MAKE_UNIQUE( \
+ TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
+ template<class _Ty COMMA LIST(_CLASS_TYPE)> inline \
+ typename _Unique_if<_Ty>::_Single_object make_unique(LIST(_TYPE_REFREF_ARG)) \
+ { \
+ return unique_ptr<_Ty>(new _Ty(LIST(_FORWARD_ARG))); \
+ } \
+
+_VARIADIC_EXPAND_0X(_MAKE_UNIQUE, , , , )
+#undef _MAKE_UNIQUE
+
+#else // not MSVC 11.0 or earlier
+
+template<class _Ty, class... Args>
+ typename _Unique_if<_Ty>::_Single_object
+ make_unique(Args&&... args) {
+ return unique_ptr<_Ty>(new _Ty(std::forward<Args>(args)...));
+ }
+
+#endif
+
+// template< class T >
+// unique_ptr<T> make_unique( std::size_t size );
+
+template<class _Ty>
+ typename _Unique_if<_Ty>::_Unknown_bound
+ make_unique(size_t n) {
+ typedef typename remove_extent<_Ty>::type U;
+ return unique_ptr<_Ty>(new U[n]());
+ }
+
+// template< class T, class... Args >
+// /* unspecified */ make_unique( Args&&... args ) = delete;
+
+// MSVC 11.0 doesn't support deleted functions, so the best we can do
+// is simply not define the function.
+#if !(defined(_MSC_VER) && (_MSC_VER < 1800))
+
+template<class T, class... Args>
+ typename _Unique_if<T>::_Known_bound
+ make_unique(Args&&...) = delete;
+
+#endif
+
+} // namespace std
+
+#endif // !COMPILER_SUPPORTS_MAKE_UNIQUE
+
+#endif /* MIXXX_UTIL_MEMORY_H */

View File

@@ -0,0 +1,88 @@
From c2af9e6eeb469718b9aa069b90a719fac80dd0d9 Mon Sep 17 00:00:00 2001
From: Uwe Klotz <uwe_klotz@web.de>
Date: Fri, 8 Jan 2016 19:25:58 +0100
Subject: [PATCH] Move definition of Time::formatSeconds() into .cpp file
---
src/util/time.cpp | 30 ++++++++++++++++++++++++++++++
src/util/time.h | 29 +----------------------------
2 files changed, 31 insertions(+), 28 deletions(-)
diff --git a/src/util/time.cpp b/src/util/time.cpp
index 998fa73..d8a122b 100644
--- a/src/util/time.cpp
+++ b/src/util/time.cpp
@@ -6,3 +6,33 @@ LLTIMER Time::s_timer;
bool Time::s_testMode = false;
// static
qint64 Time::s_testElapsed_nsecs = 0;
+
+// static
+QString Time::formatSeconds(double dSeconds, bool showCentis) {
+ if (dSeconds < 0) {
+ return "?";
+ }
+
+ const int days = static_cast<int>(dSeconds) / kSecondsPerDay;
+ dSeconds -= days * kSecondsPerDay;
+
+ // NOTE(uklotzde): Time() constructs a 'null' object, but
+ // we need 'zero' here.
+ QTime t = QTime(0, 0).addMSecs(dSeconds * kMillisPerSecond);
+
+ QString formatString =
+ (days > 0 ? (QString::number(days) %
+ QLatin1String("'d', ")) : QString()) %
+ QLatin1String(days > 0 || t.hour() > 0 ? "hh:mm:ss" : "mm:ss") %
+ QLatin1String(showCentis ? ".zzz" : "");
+
+ QString timeString = t.toString(formatString);
+
+ // The format string gives us milliseconds but we want
+ // centiseconds. Slice one character off.
+ if (showCentis) {
+ timeString = timeString.left(timeString.length() - 1);
+ }
+
+ return timeString;
+}
diff --git a/src/util/time.h b/src/util/time.h
index 7b38eb4..b4e2c2d 100644
--- a/src/util/time.h
+++ b/src/util/time.h
@@ -67,34 +67,7 @@ class Time {
// The standard way of formatting a time in seconds. Used for display of
// track duration, etc. showCentis indicates whether to include
// centisecond-precision or to round to the nearest second.
- static QString formatSeconds(double dSeconds, bool showCentis) {
- if (dSeconds < 0) {
- return "?";
- }
-
- const int days = static_cast<int>(dSeconds) / kSecondsPerDay;
- dSeconds -= days * kSecondsPerDay;
-
- // NOTE(uklotzde): Time() constructs a 'null' object, but
- // we need 'zero' here.
- QTime t = QTime(0, 0).addMSecs(dSeconds * kMillisPerSecond);
-
- QString formatString =
- (days > 0 ? (QString::number(days) %
- QLatin1String("'d', ")) : QString()) %
- QLatin1String(days > 0 || t.hour() > 0 ? "hh:mm:ss" : "mm:ss") %
- QLatin1String(showCentis ? ".zzz" : "");
-
- QString timeString = t.toString(formatString);
-
- // The format string gives us milliseconds but we want
- // centiseconds. Slice one character off.
- if (showCentis) {
- timeString = timeString.left(timeString.length() - 1);
- }
-
- return timeString;
- }
+ static QString formatSeconds(double dSeconds, bool showCentis);
private:
static LLTIMER s_timer;

View File

@@ -0,0 +1,280 @@
diff -dNur a/res/controllers/Hercules-DJ-Console-RMX-2-scripts.js b/res/controllers/Hercules-DJ-Console-RMX-2-scripts.js
--- a/res/controllers/Hercules-DJ-Console-RMX-2-scripts.js 2015-12-29 17:10:41.000000000 +0100
+++ b/res/controllers/Hercules-DJ-Console-RMX-2-scripts.js 2017-02-04 22:01:01.629506434 +0100
@@ -1,128 +1,159 @@
-/*╔══:::Made Lovingly By Circuitfry:::═════════════════════════════════╗
- ║ Hercules DJConsole RMX 2 Mapping Scripts v. 0.1.3 ║
- ╚════════════════════════════════════════════════════════════════════╝
- * Version 0.1.0: Basic Midi Wizard Mapping
- * Version 0.1.1: Partially-Functional platters (version 1).
- * Version 0.1.2: Functional platters (version 1)
- * Version 0.1.3: Functional EQ Kill/Pitch Bending buttons
- Functional Looping/Sample/Effect pads
- Bugfix: Source 2 Gain knob doesn't load tracks.
- Overhaul: MIDI Scripting file.
- Worklog: Need to implement Microphone/Source1/Source2 input.
- * Note 1: [DEP] Means the command is meant for Mixxx v1.10.x + below.
- * Note 2: [FUT] Means the command is meant for Mixxx v1.11.x + above.
-*/
-function DJCRMX2(){}
-DJCRMX2.scratching = [];
+/* ╔══:::Made Lovingly By Circuitfry:::═════════════════════════════════╗
+ * ║ Hercules DJConsole RMX 2 Mapping Scripts ║
+ * ╚════════════════════════════════════════════════════════════════════╝
+ */
-/* [ Function init ] - Version 0.1.3
- * Initiates some global variables and assigns an ID. Required.
-*/
-DJCRMX2.init = function(id){
- DJCRMX2.id = id;
- DJCRMX2.scratching[1]=false;
- DJCRMX2.scratching[2]=false;
- engine.setValue("[Microphone]","enabled",0);
- engine.setValue("[Microphone]","talkover",0);
+function DJCRMX2() {}
+DJCRMX2.decks = [];
+
+/* [ Function init ]
+ * Initiates some global variables and assigns an ID. Required.
+ */
+DJCRMX2.init = function (id) {
+ DJCRMX2.id = id;
+ DJCRMX2.decks[1] = new DJCRMX2.Deck(1);
+ DJCRMX2.decks[2] = new DJCRMX2.Deck(2);
+ engine.setValue("[Microphone]", "enabled", 0);
+ engine.setValue("[Microphone]", "talkover", 0);
}
-/* [ Function wheelPress ] - Version 0.1.2
- * Detects whether a jog wheel is pressed or not and sets a specific
- * variable on and off accordingly.
-*/
-DJCRMX2.wheelPress = function (channel, control, value, status, group){
- if (status == 0x90) // If status #144 is active (2 possibilities)
- {
- if (value == 0x7F) // And the jog wheel is pressed down:
- { /* engine.scratchEnable(int,int,float,float,float,bool);
- * [ int deck ] Which track/platter is playing?
- * [ int intervalsPerRev ] # of MIDI signals sent in 1 spin.
- * [ float rpm ] Imaginary vinyl rotation speed.
- * [ float alpha ] Just a fine-tuning variable.
- * [ float beta ] Just a fine-tuning variable.
- * [ bool ramp ] As far as I know, nothing...
- */
- var alpha = 1.0/8;
- var beta = alpha/32;
- if(group=="[Channel1]")
- {
- engine.scratchEnable(1, 250, 50, alpha, beta);
- DJCRMX2.scratching[1] = true; //[DEP]
- }
- if(group=="[Channel2]")
- {
- engine.scratchEnable(2, 250, 50, alpha, beta);
- DJCRMX2.scratching[2] = true; //[DEP]
- }
-
- }
- if (value == 0x00 ) // If the jog wheel is released:
- {
- if(group=="[Channel1]")
- {
- DJCRMX2.scratching[1] = false; // <- v1.10.x and below
- engine.scratchDisable(1);
- }
- if(group=="[Channel2]")
- {
- DJCRMX2.scratching[2] = false; // <- v1.10.x and below
- engine.scratchDisable(2);
- }
- }
- }
- else //Default setting where button is not held down.
- {
- DJCRMX2.scratching[1] = false; // Only for v1.10.x and below
- DJCRMX2.scratching[2] = false; // Only for v1.10.x and below
- engine.scratchDisable(1);
- engine.scratchDisable(2);
- }
- return;
+////////////////////////////////////////////////////////////////////////
+// Decks //
+////////////////////////////////////////////////////////////////////////
+
+DJCRMX2.Deck = function(number) {
+ this.number = number;
+ this.group = "[Channel" + this.number + "]";
+ this.scratchTimer = 0;
+};
+
+DJCRMX2.Deck.prototype.wheelPress = function (value) {
+ if (this.scratchTimer != 0) {
+ // The wheel was touched again, reset the timer.
+ engine.stopTimer(this.scratchTimer);
+ this.scratchTimer = 0;
+ }
+ if (value == 0x7F) {
+ // And the jog wheel is pressed down:
+
+ /* engine.scratchEnable(int,int,float,float,float,bool);
+ * [ int deck ] Which track/platter is playing?
+ * [ int intervalsPerRev ] # of MIDI signals sent in 1 spin.
+ * [ float rpm ] Imaginary vinyl rotation speed.
+ * [ float alpha ] Just a fine-tuning variable.
+ * [ float beta ] Just a fine-tuning variable.
+ * [ bool ramp ] As far as I know, nothing...
+ */
+
+ var alpha = 1.0 / 8;
+ var beta = alpha / 32;
+ engine.scratchEnable(this.number, 256, 33 + 1/3, alpha, beta);
+ } else {
+ // The wheel touch sensor can be overly sensitive, so don't release scratch mode right away.
+ // Depending on how fast the platter was moving, lengthen the time we'll wait.
+ var scratchRate = Math.abs(engine.getValue(this.group, "scratch2"));
+ var inertiaTime = Math.pow(1.8, scratchRate) * 50;
+ if (inertiaTime < 100) {
+ // Just do it now.
+ this.finishWheelPress();
+ } else {
+ this.scratchTimer = engine.beginTimer(
+ 100, "DJCRMX2.decks[" + this.number + "].finishWheelPress()", true);
+ }
+ }
+}
+
+DJCRMX2.Deck.prototype.finishWheelPress = function() {
+ this.scratchTimer = 0;
+ var play = engine.getValue(this.group, "play");
+ if (play != 0) {
+ // If we are playing, just hand off to the engine.
+ engine.scratchDisable(this.number, true);
+ } else {
+ // If things are paused, there will be a non-smooth handoff between scratching and jogging.
+ // Instead, keep scratch on until the platter is not moving.
+ var scratchRate = Math.abs(engine.getValue(this.group, "scratch2"));
+ if (scratchRate < 0.01) {
+ // The platter is basically stopped, now we can disable scratch and hand off to jogging.
+ engine.scratchDisable(this.number, false);
+ } else {
+ // Check again soon.
+ this.scratchTimer = engine.beginTimer(
+ 100, "DJCRMX2.decks[" + this.number + "].finishWheelPress()", true);
+ }
+ }
+};
+
+
+/* [ Function wheelTurn ]
+ * Pays attention to the current deck, checks scratching, affects the
+ * song accordingly.
+ */
+DJCRMX2.Deck.prototype.wheelTurn = function (value) {
+ var newValue = 0;
+ // Spinning backwards = 127 or less (less meaning faster)
+ // Spinning forwards = 1 or more (more meaning faster)
+ if (value - 64 > 0) {
+ newValue = value - 128;
+ } else {
+ newValue = value;
+ }
+
+ if (engine.isScratching(this.number)) {
+ engine.scratchTick(this.number, newValue);
+ } else {
+ engine.setValue(this.group, "jog", newValue);
+ }
}
+
+/* [ Function wheelPress ]
+ * Detects whether a jog wheel is pressed or not and sets a specific
+ * variable on and off accordingly.
+ */
+DJCRMX2.wheelPress = function (channel, control, value, status, group) {
+ var deck = 0;
+ if (group == "[Channel1]") {
+ deck = 1;
+ } else if (group == "[Channel2]") {
+ deck = 2;
+ } else {
+ return;
+ }
+ DJCRMX2.decks[deck].wheelPress(value);
+}
+
-/* [ Function wheelTurn ] - Version 0.1.2
- * Pays attention to the current deck, checks scratching, affects the
- * song accordingly.
-*/
-DJCRMX2.wheelTurn = function (channel, control, value, status, group){
- var newValue=0;
- // Spinning backwards = 127 or less (less meaning faster)
- // Spinning forwards = 1 or more (more meaning faster)
- if (value-64 > 0) newValue = (value-128);
- else newValue=value;
- //if (!engine.isScratching(DJCRMX2.currentDeck)) // [FUT]
- if(group=="[Channel1]")
- {
- if(DJCRMX2.scratching[1]==true) {engine.scratchTick(1,newValue);return;}
- }
- else if(group=="[Channel2]")
- {
- if(DJCRMX2.scratching[2]==true) {engine.scratchTick(2,newValue);return;}
- }
- engine.setValue(group, "jog", newValue);
- return;
+/* [ Function wheelTurn ]
+ * Pays attention to the current deck, checks scratching, affects the
+ * song accordingly.
+ */
+DJCRMX2.wheelTurn = function (channel, control, value, status, group) {
+ var deck = 0;
+ if (group == "[Channel1]") {
+ deck = 1;
+ } else if (group == "[Channel2]") {
+ deck = 2;
+ } else {
+ return;
+ }
+ DJCRMX2.decks[deck].wheelTurn(value);
}
-DJCRMX2.micSwitch = function (channel, control, value, status) //???
+DJCRMX2.micSwitch = function (channel, control, value, status)
{
- if(status == 0x90 && control == 0x48 && value == 0x7F)
- {
- engine.setValue("[Microphone]","enabled",1);
- engine.setValue("[Microphone]","talkover",1);
- }
- if(status == 0x90 && control == 0x48 && value == 0x00)
- {
- engine.setValue("[Microphone]","enabled",0);
- engine.setValue("[Microphone]","talkover",0);
- }
+ if (status == 0x90 && control == 0x48 && value == 0x7F) {
+ engine.setValue("[Microphone]","enabled",1);
+ engine.setValue("[Microphone]","talkover",1);
+ } else if (status == 0x90 && control == 0x48 && value == 0x00) {
+ engine.setValue("[Microphone]","enabled",0);
+ engine.setValue("[Microphone]","talkover",0);
+ }
}
-/* [ Function shutdown ] - Version 0.1.3
- * Sets variables down for shutoff.
-*/
-DJCRMX2.shutdown = function(id){
- DJCRMX2.scratching[1]=false;
- DJCRMX2.scratching[2]=false;
- engine.setValue("[Microphone]","enabled",0);
- engine.setValue("[Microphone]","talkover",0);
+/* [ Function shutdown ] - Version 0.1.3
+ * Sets variables down for shutoff.
+ */
+DJCRMX2.shutdown = function (id) {
+ engine.setValue("[Microphone]", "enabled", 0);
+ engine.setValue("[Microphone]", "talkover", 0);
}