diff options
author | Uwe Klotz <uklotz@mixxx.org> | 2021-10-15 12:53:22 +0200 |
---|---|---|
committer | Uwe Klotz <uklotz@mixxx.org> | 2021-10-15 12:53:22 +0200 |
commit | c5030825a1b12af06bd481021b883bb1e85ba5ad (patch) | |
tree | 9ee48dcd9f9b32ccd9a08ae8dd2eff0648c31689 /src | |
parent | 8dfe5f60ff169b27f5d2c62e5c8b7cd456ab34f3 (diff) | |
parent | 79915d51e7d7e3e69f0cd2a381a8b89e9b6cb8cc (diff) |
Merge branch 'main' of git@github.com:mixxxdj/mixxx.git into track-metadata-sync
Diffstat (limited to 'src')
54 files changed, 342 insertions, 278 deletions
diff --git a/src/controllers/controlpickermenu.cpp b/src/controllers/controlpickermenu.cpp index ecef8b161e..973264201d 100644 --- a/src/controllers/controlpickermenu.cpp +++ b/src/controllers/controlpickermenu.cpp @@ -874,10 +874,10 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) for (int iSamplerNumber = 1; iSamplerNumber <= iNumSamplers; ++iSamplerNumber) { // PlayerManager::groupForSampler is 0-indexed. - QString playerGroup = PlayerManager::groupForSampler(iSamplerNumber - 1); + QString samplerGroup = PlayerManager::groupForSampler(iSamplerNumber - 1); // TODO(owen): Fix bad i18n here. addControl(effectUnitGroup, - QString("group_%1_enable").arg(playerGroup), + QString("group_%1_enable").arg(samplerGroup), assignString + m_samplerStr.arg(iSamplerNumber), assignString + m_samplerStr.arg(iSamplerNumber), effectUnitGroups, diff --git a/src/coreservices.cpp b/src/coreservices.cpp index eddcf83598..3abfef8045 100644 --- a/src/coreservices.cpp +++ b/src/coreservices.cpp @@ -3,6 +3,7 @@ #include <QApplication> #include <QFileDialog> #include <QPushButton> +#include <QStandardPaths> #ifdef __BROADCAST__ #include "broadcast/broadcastmanager.h" @@ -42,7 +43,7 @@ #include "util/sandbox.h" #endif -#if defined(Q_OS_LINUX) +#if defined(Q_OS_LINUX) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #include <X11/Xlib.h> #include <X11/Xlibint.h> @@ -74,7 +75,7 @@ void clearHelper(std::shared_ptr<T>& ref_ptr, const char* name) { // hack around https://gitlab.freedesktop.org/xorg/lib/libx11/issues/25 // https://bugs.launchpad.net/mixxx/+bug/1805559 -#if defined(Q_OS_LINUX) +#if defined(Q_OS_LINUX) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) typedef Bool (*WireToErrorType)(Display*, XErrorEvent*, xError*); constexpr int NUM_HANDLERS = 256; @@ -218,7 +219,7 @@ void CoreServices::initialize(QApplication* pApp) { VersionStore::logBuildDetails(); -#if defined(Q_OS_LINUX) +#if defined(Q_OS_LINUX) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // XESetWireToError will segfault if running as a Wayland client if (pApp->platformName() == QLatin1String("xcb")) { for (auto i = 0; i < NUM_HANDLERS; ++i) { diff --git a/src/dialog/dlgkeywheel.cpp b/src/dialog/dlgkeywheel.cpp index e05e075f55..af1126f021 100644 --- a/src/dialog/dlgkeywheel.cpp +++ b/src/dialog/dlgkeywheel.cpp @@ -155,7 +155,12 @@ void DlgKeywheel::updateSvg() { if (text.isText()) { QDomText textNode = text.toText(); - ChromaticKey key = static_cast<ChromaticKey>(id.midRef(2).toInt()); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + const int keyInt = QStringView(id).sliced(2).toInt(); +#else + const int keyInt = id.midRef(2).toInt(); +#endif + ChromaticKey key = static_cast<ChromaticKey>(keyInt); QString keyString = KeyUtils::keyToString(key, m_notation); textNode.setData(keyString); } diff --git a/src/encoder/encoderfdkaac.cpp b/src/encoder/encoderfdkaac.cpp index fef01f1de7..49871386d7 100644 --- a/src/encoder/encoderfdkaac.cpp +++ b/src/encoder/encoderfdkaac.cpp @@ -165,7 +165,7 @@ EncoderFdkAac::~EncoderFdkAac() { } delete[] m_pAacDataBuffer; - delete m_pFifoChunkBuffer; + delete[] m_pFifoChunkBuffer; delete m_pInputFifo; } @@ -283,6 +283,10 @@ int EncoderFdkAac::initEncoder(mixxx::audio::SampleRate sampleRate, QString* pUs // This initializes the encoder handle but not the encoder itself. // Actual encoder init is done below. aacEncOpen(&m_aacEnc, 0, m_channels); + VERIFY_OR_DEBUG_ASSERT(!m_pAacDataBuffer) { + delete[] m_pAacDataBuffer; + m_pAacDataBuffer = nullptr; + } m_pAacDataBuffer = new unsigned char[kOutBufferBits * m_channels](); // AAC Object Type: specifies "mode": AAC-LC, HE-AAC, HE-AACv2, DAB AAC, etc... @@ -345,8 +349,16 @@ int EncoderFdkAac::initEncoder(mixxx::audio::SampleRate sampleRate, QString* pUs // This is set to the buffer size of the sidechain engine because // Recording (which uses this engine) sends more samples at once to the encoder than // the Live Broadcasting implementation + VERIFY_OR_DEBUG_ASSERT(!m_pInputFifo) { + delete m_pInputFifo; + m_pInputFifo = nullptr; + } m_pInputFifo = new FIFO<SAMPLE>(EngineSideChain::SIDECHAIN_BUFFER_SIZE * 2); + VERIFY_OR_DEBUG_ASSERT(!m_pFifoChunkBuffer) { + delete[] m_pFifoChunkBuffer; + m_pFifoChunkBuffer = nullptr; + } m_pFifoChunkBuffer = new SAMPLE[m_readRequired * sizeof(SAMPLE)](); return 0; } diff --git a/src/engine/controls/bpmcontrol.cpp b/src/engine/controls/bpmcontrol.cpp index 76dc2a591e..bc3383ae10 100644 --- a/src/engine/controls/bpmcontrol.cpp +++ b/src/engine/controls/bpmcontrol.cpp @@ -162,7 +162,11 @@ void BpmControl::adjustBeatsBpm(double deltaBpm) { const auto centerBpm = mixxx::Bpm(math_max(kBpmAdjustMin, bpm.value() + deltaBpm)); mixxx::Bpm adjustedBpm = BeatUtils::roundBpmWithinRange( centerBpm - kBpmAdjustStep / 2, centerBpm, centerBpm + kBpmAdjustStep / 2); - pTrack->trySetBeats(pBeats->setBpm(adjustedBpm)); + const auto newBeats = pBeats->trySetBpm(adjustedBpm); + if (!newBeats) { + return; + } + pTrack->trySetBeats(*newBeats); } void BpmControl::slotAdjustBeatsFaster(double v) { @@ -191,7 +195,10 @@ void BpmControl::slotTranslateBeatsEarlier(double v) { if (pBeats) { const double sampleOffset = frameInfo().sampleRate * -0.01; const mixxx::audio::FrameDiff_t frameOffset = sampleOffset / mixxx::kEngineChannelCount; - pTrack->trySetBeats(pBeats->translate(frameOffset)); + const auto translatedBeats = pBeats->tryTranslate(frameOffset); + if (translatedBeats) { + pTrack->trySetBeats(*translatedBeats); + } } } @@ -208,7 +215,10 @@ void BpmControl::slotTranslateBeatsLater(double v) { // TODO(rryan): Track::frameInfo is possibly inaccurate! const double sampleOffset = frameInfo().sampleRate * 0.01; const mixxx::audio::FrameDiff_t frameOffset = sampleOffset / mixxx::kEngineChannelCount; - pTrack->trySetBeats(pBeats->translate(frameOffset)); + const auto translatedBeats = pBeats->tryTranslate(frameOffset); + if (translatedBeats) { + pTrack->trySetBeats(*translatedBeats); + } } } @@ -245,7 +255,11 @@ void BpmControl::slotTapFilter(double averageLength, int numSamples) { averageBpm = BeatUtils::roundBpmWithinRange(averageBpm - kBpmTabRounding, averageBpm, averageBpm + kBpmTabRounding); - pTrack->trySetBeats(pBeats->setBpm(averageBpm)); + const auto newBeats = pBeats->trySetBpm(averageBpm); + if (!newBeats) { + return; + } + pTrack->trySetBeats(*newBeats); } // static @@ -961,8 +975,11 @@ void BpmControl::slotBeatsTranslate(double v) { if (pBeats) { const auto currentPosition = frameInfo().currentPosition.toLowerFrameBoundary(); const auto closestBeat = pBeats->findClosestBeat(currentPosition); - const mixxx::audio::FrameDiff_t delta = currentPosition - closestBeat; - pTrack->trySetBeats(pBeats->translate(delta)); + const mixxx::audio::FrameDiff_t frameOffset = currentPosition - closestBeat; + const auto translatedBeats = pBeats->tryTranslate(frameOffset); + if (translatedBeats) { + pTrack->trySetBeats(*translatedBeats); + } } } @@ -980,8 +997,11 @@ void BpmControl::slotBeatsTranslateMatchAlignment(double v) { // otherwise it will always return 0 if sync lock is active. m_dUserOffset.setValue(0.0); - const mixxx::audio::FrameDiff_t frameOffset = getPhaseOffset(frameInfo().currentPosition); - pTrack->trySetBeats(pBeats->translate(-frameOffset)); + const mixxx::audio::FrameDiff_t frameOffset = -getPhaseOffset(frameInfo().currentPosition); + const auto translatedBeats = pBeats->tryTranslate(frameOffset); + if (translatedBeats) { + pTrack->trySetBeats(*translatedBeats); + } } } diff --git a/src/engine/controls/loopingcontrol.cpp b/src/engine/controls/loopingcontrol.cpp index 2f449e5df2..069fc80284 100644 --- a/src/engine/controls/loopingcontrol.cpp +++ b/src/engine/controls/loopingcontrol.cpp @@ -1124,7 +1124,11 @@ void LoopingControl::slotBeatLoopDeactivate(BeatLoopingControl* pBeatLoopControl void LoopingControl::slotBeatLoopDeactivateRoll(BeatLoopingControl* pBeatLoopControl) { pBeatLoopControl->deactivate(); const double size = pBeatLoopControl->getSize(); - auto* i = m_activeLoopRolls.begin(); + // clang-tidy wants auto to be auto* because QStack inherits from QVector + // and QVector::iterator is a pointer type in Qt5, but QStack inherits + // from QList in Qt6 so QStack::iterator is not a pointer type in Qt6. + // NOLINTNEXTLINE(readability-qualified-auto) + auto i = m_activeLoopRolls.begin(); while (i != m_activeLoopRolls.end()) { if (size == *i) { i = m_activeLoopRolls.erase(i); diff --git a/src/engine/sync/enginesync.cpp b/src/engine/sync/enginesync.cpp index 78a111f159..f8c564da52 100644 --- a/src/engine/sync/enginesync.cpp +++ b/src/engine/sync/enginesync.cpp @@ -369,10 +369,10 @@ void EngineSync::notifyPlayingAudible(Syncable* pSyncable, bool playingAudible) } else { Syncable* pOnlyPlayer = getUniquePlayingSyncedDeck(); if (pOnlyPlayer) { - // Even if we didn't change leader, if there is only one player (us), then we should - // update the beat distance. + // Even if we didn't change leader, if there is only one player, then we should + // reinit leader params. pOnlyPlayer->notifyUniquePlaying(); - updateLeaderBeatDistance(pOnlyPlayer, pOnlyPlayer->getBeatDistance()); + reinitLeaderParams(pOnlyPlayer); } } } @@ -446,6 +446,9 @@ void EngineSync::notifyBeatDistanceChanged(Syncable* pSyncable, double beatDista << pSyncable->getGroup() << beatDistance; } if (pSyncable != m_pInternalClock) { + if (getUniquePlayingSyncedDeck() == pSyncable) { + updateLeaderBeatDistance(pSyncable, beatDistance); + } return; } @@ -654,6 +657,10 @@ void EngineSync::reinitLeaderParams(Syncable* pSource) { mixxx::Bpm bpm = pSource->getBpm(); if (!bpm.isValid()) { bpm = baseBpm; + if (!bpm.isValid()) { + // This happens if the deck is the only playing one but the track has no beats + return; + } } if (kLogger.traceEnabled()) { kLogger.trace() << "BaseSyncableListener::reinitLeaderParams, source is" diff --git a/src/library/dao/playlistdao.cpp b/src/library/dao/playlistdao.cpp index c3ed470cce..beefa35028 100644 --- a/src/library/dao/playlistdao.cpp +++ b/src/library/dao/playlistdao.cpp @@ -966,7 +966,7 @@ void PlaylistDAO::shuffleTracks(const int playlistId, QHash<int, TrackId> trackPositionIds = allIds; QList<int> newPositions = positions; - const int searchDistance = math_max(trackPositionIds.count() / 4, 1); + const int searchDistance = math_max(static_cast<int>(trackPositionIds.count()) / 4, 1); qDebug() << "Shuffling Tracks"; qDebug() << "*** Search Distance: " << searchDistance; diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp index 21aacb01c5..c33d3e7b36 100644 --- a/src/library/dlgtrackinfo.cpp +++ b/src/library/dlgtrackinfo.cpp @@ -520,33 +520,35 @@ void DlgTrackInfo::clear() { } void DlgTrackInfo::slotBpmDouble() { - m_pBeatsClone = m_pBeatsClone->scale(mixxx::Beats::BpmScale::Double); - updateSpinBpmFromBeats(); + slotBpmScale(mixxx::Beats::BpmScale::Double); } void DlgTrackInfo::slotBpmHalve() { - m_pBeatsClone = m_pBeatsClone->scale(mixxx::Beats::BpmScale::Halve); - updateSpinBpmFromBeats(); + slotBpmScale(mixxx::Beats::BpmScale::Halve); } void DlgTrackInfo::slotBpmTwoThirds() { - m_pBeatsClone = m_pBeatsClone->scale(mixxx::Beats::BpmScale::TwoThirds); - updateSpinBpmFromBeats(); + slotBpmScale(mixxx::Beats::BpmScale::TwoThirds); } void DlgTrackInfo::slotBpmThreeFourth() { - m_pBeatsClone = m_pBeatsClone->scale(mixxx::Beats::BpmScale::ThreeFourths); - updateSpinBpmFromBeats(); + slotBpmScale(mixxx::Beats::BpmScale::ThreeFourths); } void DlgTrackInfo::slotBpmFourThirds() { - m_pBeatsClone = m_pBeatsClone->scale(mixxx::Beats::BpmScale::FourThirds); - updateSpinBpmFromBeats(); + slotBpmScale(mixxx::Beats::BpmScale::FourThirds); } void DlgTrackInfo::slotBpmThreeHalves() { - m_pBeatsClone = m_pBeatsClone->scale(mixxx::Beats::BpmScale::ThreeHalves); - updateSpinBpmFromBeats(); + slotBpmScale(mixxx::Beats::BpmScale::ThreeHalves); +} + +void DlgTrackInfo::slotBpmScale(mixxx::Beats::BpmScale bpmScale) { + const auto scaledBeats = m_pBeatsClone->tryScale(bpmScale); + if (scaledBeats) { + m_pBeatsClone = *scaledBeats; + updateSpinBpmFromBeats(); + } } void DlgTrackInfo::slotBpmClear() { @@ -610,7 +612,7 @@ void DlgTrackInfo::slotSpinBpmValueChanged(double value) { if (oldValue == bpm) { return; } - m_pBeatsClone = m_pBeatsClone->setBpm(bpm); + m_pBeatsClone = m_pBeatsClone->trySetBpm(bpm).value_or(m_pBeatsClone); } updateSpinBpmFromBeats(); diff --git a/src/library/dlgtrackinfo.h b/src/library/dlgtrackinfo.h index 2cb9d01011..b1a6be573e 100644 --- a/src/library/dlgtrackinfo.h +++ b/src/library/dlgtrackinfo.h @@ -57,6 +57,7 @@ class DlgTrackInfo : public QDialog, public Ui::DlgTrackInfo { void slotBpmThreeFourth(); void slotBpmFourThirds(); void slotBpmThreeHalves(); + void slotBpmScale(mixxx::Beats::BpmScale bpmScale); void slotBpmClear(); void slotBpmConstChanged(int state); void slotBpmTap(double averageLength, int numSamples); diff --git a/src/library/library.h b/src/library/library.h index 3c6cf53291..83dda1bb1c 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -75,11 +75,6 @@ class Library: public QObject { /// Needed for exposing models to QML LibraryTableModel* trackTableModel() const; - /// Needed for exposing sidebar to QML - SidebarModel* sidebarModel() const { - return m_pSidebarModel.get(); - } - int getTrackTableRowHeight() const { return m_iTrackTableRowHeight; } diff --git a/src/library/parsercsv.cpp b/src/library/parsercsv.cpp index 41f411d6f1..f34e5ea2d6 100644 --- a/src/library/parsercsv.cpp +++ b/src/library/parsercsv.cpp @@ -50,7 +50,7 @@ QList<QString> ParserCsv::parse(const QString& sFilename) { for (int i = 1; i < tokens.size(); ++i) { if (loc_coll < tokens[i].size()) { // Todo: check if path is relative - QFileInfo fi = tokens[i][loc_coll]; + QFileInfo fi(tokens[i][loc_coll]); if (fi.isRelative()) { // add base path qDebug() << "is relative" << basepath << fi.filePath(); @@ -140,9 +140,14 @@ bool ParserCsv::writeCSVFile(const QString &file_str, BaseSqlTableModel* pPlayli qDebug() << "Basepath: " << base; QTextStream out(&file); - out.setCodec("UTF-8"); // rfc4180: Common usage of CSV is US-ASCII ... - // Using UTF-8 to get around codepage issues - // and it's the default encoding in Ooo Calc + // rfc4180: Common usage of CSV is US-ASCII ... + // Using UTF-8 to get around codepage issues + // and it's the default encoding in Ooo Calc +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + DEBUG_ASSERT(out.encoding() == QStringConverter::Utf8); +#else + out.setCodec("UTF-8"); +#endif // writing header section bool first = true; diff --git a/src/library/parserm3u.cpp b/src/library/parserm3u.cpp index 797dd88d7d..d07c2a326e 100644 --- a/src/library/parserm3u.cpp +++ b/src/library/parserm3u.cpp @@ -21,6 +21,12 @@ #include "moc_parserm3u.cpp" +namespace { +// according to http://en.wikipedia.org/wiki/M3U the default encoding of m3u is Windows-1252 +// see also http://tools.ietf.org/html/draft-pantos-http-live-streaming-07 +const char* kStandardM3uTextEncoding = "Windows-1250"; +} // anonymous namespace + /** ToDo: - parse ALL information from the pls file if available , @@ -45,15 +51,15 @@ ParserM3u::~ParserM3u() } -QList<QString> ParserM3u::parse(const QString& sFilename) { - clearLocations(); +QList<QString> ParserM3u::parse(const QString& filename) { + QList<QString> paths; - QFile file(sFilename); + QFile file(filename); if (!file.open(QIODevice::ReadOnly)) { qWarning() << "Failed to open playlist file" - << sFilename; - return m_sLocations; + << filename; + return paths; } // Unfortunately QTextStream does not handle <CR> (=\r or asci value 13) line breaks. @@ -63,49 +69,36 @@ QList<QString> ParserM3u::parse(const QString& sFilename) { // Using QFile::readAll() we obtain the complete content of the playlist as a ByteArray. // We replace any '\r' with '\n' if applicaple // This ensures that playlists from iTunes on OS X can be parsed - QByteArray ba = file.readAll(); + QByteArray byteArray = file.readAll(); //detect encoding - bool isCRLF_encoded = ba.contains("\r\n"); - bool isCR_encoded = ba.contains("\r"); + bool isCRLF_encoded = byteArray.contains("\r\n"); + bool isCR_encoded = byteArray.contains("\r"); if (isCR_encoded && !isCRLF_encoded) { - ba.replace('\r', '\n'); + byteArray.replace('\r', '\n'); } - QTextStream textstream(ba.constData()); - if (isUtf8(ba.constData())) { - textstream.setCodec("UTF-8"); + QString fileContents; + if (isUtf8(byteArray.constData())) { + fileContents = QString::fromUtf8(byteArray); } else { - textstream.setCodec("windows-1252"); + // FIXME: replace deprecated QTextCodec with direct usage of libicu + fileContents = QTextCodec::codecForName(kStandardM3uTextEncoding) + ->toUnicode(byteArray); } - const auto basePath = sFilename.section('/', 0, -2); - while (!textstream.atEnd()) { - QString sLine = getFilePath(&textstream, basePath); - if (sLine.isEmpty()) { - continue; - } - m_sLocations.append(sLine); - } - - return m_sLocations; -} - -QString ParserM3u::getFilePath(QTextStream* stream, const QString& basePath) { - QString textline; - while (!(textline = stream->readLine().trimmed()).isEmpty()) { - if (textline.startsWith("#")) { - // Skip comments - continue; - } - auto trackFile = playlistEntryToFileInfo(textline, basePath); + QFileInfo fileInfo(filename); + const QStringList fileLines = fileContents.split('\n'); + for (const QString& line : fileLines) { + auto trackFile = playlistEntryToFileInfo(line, fileInfo.canonicalPath()); if (trackFile.checkFileExists()) { - return trackFile.location(); + paths.append(trackFile.location()); + } else { + qInfo() << "File" << trackFile.location() << "from M3U playlist" + << filename << "does not exist."; } - // We couldn't match this to a real file so ignore it - qWarning() << trackFile << "not found"; } - // Signal we reached the end - return QString(); + + return paths; } bool ParserM3u::writeM3UFile(const QString &file_str, const QList<QString> &items, bool useRelativePath) { @@ -122,26 +115,25 @@ bool ParserM3u::writeM3UFile(const QString &file_str, const QList<QString> &item // On Windows \n will produce a <CR><CL> (=\r\n)< |