From 70d7c0c62ca8cf9f6c10dad47d771e52e1e51aae Mon Sep 17 00:00:00 2001 From: Greedysky Date: Sat, 16 May 2026 19:48:40 +0800 Subject: [PATCH] feat: Add sidplayfp-3.0 support and fix memory leak[245148] --- .../plugins/Input/main/sid/decoder_sid.cpp | 67 +++++++++++++------ qmmp/src/plugins/Input/main/sid/decoder_sid.h | 5 +- .../plugins/Input/main/sid/settingsdialog.cpp | 29 ++++++-- .../plugins/Input/main/sid/settingsdialog.ui | 2 +- qmmp/src/plugins/Input/main/sid/sid.pro | 2 + .../Input/tracker/openmpt/settingsdialog.cpp | 6 +- 6 files changed, 77 insertions(+), 34 deletions(-) diff --git a/qmmp/src/plugins/Input/main/sid/decoder_sid.cpp b/qmmp/src/plugins/Input/main/sid/decoder_sid.cpp index a13ef696b..3a8959544 100644 --- qmmp/src/plugins/Input/main/sid/decoder_sid.cpp +++ qmmp/src/plugins/Input/main/sid/decoder_sid.cpp @@ -1,8 +1,14 @@ #include #include #include -#include -#include +#if LIBSIDPLAYFP_VERSION_MAJ >= 3 +# include +#else +# include +#endif +#ifdef HAVE_RESIDFP_HEADER +# include +#endif #include #include #include @@ -35,14 +41,15 @@ int track = -1; const QString &filePath = TrackInfo::pathFromUrl(m_path, &track); - m_tune.load(QmmpPrintable(filePath)); - if(!m_tune.getInfo()) + m_tune = std::unique_ptr(new SidTune(nullptr)); + m_tune->load(QmmpPrintable(filePath)); + if(!m_tune->getInfo()) { - qWarning("DecoderSID: unable to load tune, error: %s", m_tune.statusString()); + qWarning("DecoderSID: unable to load tune, error: %s, %s", m_tune->statusString(), qPrintable(filePath)); return false; } - int count = m_tune.getInfo()->songs(); + int count = m_tune->getInfo()->songs(); if(track == 0) track = count; @@ -52,15 +59,15 @@ return false; } - m_tune.selectSong(track); - if(!m_tune.getStatus()) + m_tune->selectSong(track); + if(!m_tune->getStatus()) { - qWarning("DecoderSID: error: %s", m_tune.statusString()); + qWarning("DecoderSID: error: %s", m_tune->statusString()); return false; } //send metadata for pseudo-protocol - const SidTuneInfo *tune_info = m_tune.getInfo(); + const SidTuneInfo *tune_info = m_tune->getInfo(); QMap metadata; metadata.insert(Qmmp::TITLE, tune_info->infoString(0)); metadata.insert(Qmmp::ARTIST, tune_info->infoString(1)); @@ -75,7 +82,7 @@ if(settings.value("use_hvsc", false).toBool()) { char md5[SidTune::MD5_LENGTH + 1]; - m_tune.createMD5(md5); + m_tune->createMD5(md5); m_length = m_db->length(md5, track) * 1000; } @@ -86,25 +93,41 @@ qDebug("DecoderSID: song length: %ld", m_length); - sidbuilder *rs = nullptr; +#if LIBSIDPLAYFP_VERSION_MAJ >= 3 +# ifdef HAVE_RESIDFP_HEADER + if(settings.value("engine", "sidlite").toString() == "residfp") + { + m_builder = std::unique_ptr(new ReSIDfpBuilder("ReSIDfp")); + } + else +# endif + { + m_builder = std::unique_ptr(new SIDLiteBuilder("SIDLite")); + } +#else +# ifdef HAVE_RESIDFP_HEADER if(settings.value("engine", "residfp").toString() == "residfp") { - rs = new ReSIDfpBuilder("ReSIDfp builder"); - qDebug("DecoderSID: using ReSIDfp emulation"); + m_builder = std::unique_ptr(new ReSIDfpBuilder("ReSIDfp")); } else +# endif { - rs = new ReSIDBuilder("ReSID builder"); - qDebug("DecoderSID: using ReSID emulation"); + m_builder = std::unique_ptr(new ReSIDBuilder("ReSID")); } - rs->create(m_player->info().maxsids()); + m_builder->create(m_player->info().maxsids()); +#endif + + qDebug("DecoderSID: using %s emulation", m_builder->name()); SidConfig cfg = m_player->config(); - cfg.frequency = settings.value("sample_rate", 48000).toInt(); - cfg.samplingMethod = (SidConfig::sampling_method_t)settings.value("resampling_method", SidConfig::INTERPOLATE).toInt(); - cfg.playback = SidConfig::STEREO; - cfg.sidEmulation = rs; + cfg.frequency = settings.value("sample_rate", 48000).toInt(); + cfg.samplingMethod = static_cast(settings.value("resampling_method", SidConfig::INTERPOLATE).toInt()); + cfg.sidEmulation = m_builder.get(); +#if LIBSIDPLAYFP_VERSION_MAJ < 3 + cfg.playback = SidConfig::STEREO; cfg.fastSampling = settings.value("fast_resampling", false).toBool(); +#endif settings.endGroup(); if(!m_player->config(cfg)) @@ -113,7 +136,7 @@ return false; } - if(!m_player->load(&m_tune)) + if(!m_player->load(m_tune.get())) { qWarning("DecoderSID: unable to load tune, error: %s", m_player->error()); return false; diff --git a/qmmp/src/plugins/Input/main/sid/decoder_sid.h b/qmmp/src/plugins/Input/main/sid/decoder_sid.h index 691d9a634..b820cc9ae 100644 --- qmmp/src/plugins/Input/main/sid/decoder_sid.h +++ qmmp/src/plugins/Input/main/sid/decoder_sid.h @@ -21,11 +21,13 @@ #ifndef DECODER_SID_H #define DECODER_SID_H +#include #include class sidplayfp; class SidDatabase; class SidTune; +class sidbuilder; /** @author Ilya Kotov @@ -50,7 +52,8 @@ class DecoderSID : public Decoder qint64 m_length = 0; qint64 m_length_in_bytes = 0; qint64 m_read_bytes = 0; - SidTune m_tune; + std::unique_ptr m_tune; + std::unique_ptr m_builder; }; diff --git a/qmmp/src/plugins/Input/main/sid/settingsdialog.cpp b/qmmp/src/plugins/Input/main/sid/settingsdialog.cpp index e0d422899..2098083c8 100644 --- qmmp/src/plugins/Input/main/sid/settingsdialog.cpp +++ qmmp/src/plugins/Input/main/sid/settingsdialog.cpp @@ -3,6 +3,7 @@ #include #include #include +#include SettingsDialog::SettingsDialog(SidDatabase *db, QWidget *parent) : QDialog(parent) @@ -25,20 +26,33 @@ SettingsDialog::SettingsDialog(SidDatabase *db, QWidget *parent) m_ui.sampleRateComboBox->addItem("44100", 44100); m_ui.sampleRateComboBox->addItem("48000", 48000); - int i = m_ui.sampleRateComboBox->findData(settings.value("sample_rate", 48000).toInt()); - m_ui.sampleRateComboBox->setCurrentIndex(i); + int index = m_ui.sampleRateComboBox->findData(settings.value("sample_rate", 48000).toInt()); + m_ui.sampleRateComboBox->setCurrentIndex(index); +#if LIBSIDPLAYFP_VERSION_MAJ >= 3 + m_ui.emuComboBox->addItem("SIDLite", "sidlite"); + m_ui.emuComboBox->addItem("ReSIDfp", "residfp"); + index = m_ui.emuComboBox->findData(settings.value("engine", "sidlite").toString()); + m_ui.emuComboBox->setCurrentIndex(qMax(index, 0)); + m_ui.fastResampligCheckBox->setVisible(false); +#else m_ui.emuComboBox->addItem("ReSID", "resid"); m_ui.emuComboBox->addItem("ReSIDfp", "residfp"); - i = m_ui.emuComboBox->findData(settings.value("engine", "residfp").toString()); - m_ui.emuComboBox->setCurrentIndex(i); - + index = m_ui.emuComboBox->findData(settings.value("engine", "residfp").toString()); + m_ui.emuComboBox->setCurrentIndex(qMax(index, 0)); m_ui.fastResampligCheckBox->setChecked(settings.value("fast_resampling", false).toBool()); +#endif + +// TODO use QFormLayout::setRowVisible +#ifndef HAVE_RESIDFP_HEADER + m_ui.emulationLabel->setVisible(false); + m_ui.emuComboBox->setVisible(false); +#endif m_ui.resamplingComboBox->addItem("Interpolate", SidConfig::INTERPOLATE); m_ui.resamplingComboBox->addItem("Resample interpolate", SidConfig::RESAMPLE_INTERPOLATE); - i = m_ui.resamplingComboBox->findData(settings.value("resampling_method", SidConfig::INTERPOLATE).toInt()); - m_ui.resamplingComboBox->setCurrentIndex(i); + index = m_ui.resamplingComboBox->findData(settings.value("resampling_method", SidConfig::INTERPOLATE).toInt()); + m_ui.resamplingComboBox->setCurrentIndex(index); settings.endGroup(); } diff --git a/qmmp/src/plugins/Input/main/sid/settingsdialog.ui b/qmmp/src/plugins/Input/main/sid/settingsdialog.ui index bca2e2688..43cdcf8a2 100644 --- qmmp/src/plugins/Input/main/sid/settingsdialog.ui +++ qmmp/src/plugins/Input/main/sid/settingsdialog.ui @@ -145,7 +145,7 @@ - + Emulation: diff --git a/qmmp/src/plugins/Input/main/sid/sid.pro b/qmmp/src/plugins/Input/main/sid/sid.pro index 32826f68c..5c136f22e 100644 --- qmmp/src/plugins/Input/main/sid/sid.pro +++ qmmp/src/plugins/Input/main/sid/sid.pro @@ -14,6 +14,8 @@ SOURCES += decodersidfactory.cpp \ FORMS += settingsdialog.ui +DEFINES += HAVE_RESIDFP_HEADER + INCLUDEPATH += $$EXTRA_LIB_PATH/libsidplayfp/include win32{ diff --git a/qmmp/src/plugins/Input/tracker/openmpt/settingsdialog.cpp b/qmmp/src/plugins/Input/tracker/openmpt/settingsdialog.cpp index 0d7a4da0a..d6e053438 100644 --- qmmp/src/plugins/Input/tracker/openmpt/settingsdialog.cpp +++ qmmp/src/plugins/Input/tracker/openmpt/settingsdialog.cpp @@ -50,9 +50,9 @@ void SettingsDialog::accept() void SettingsDialog::setInterpolator(int interpolator) { - const int i = m_ui.interpolate_combo->findData(interpolator); - if(i != -1) + const int index = m_ui.interpolate_combo->findData(interpolator); + if(index != -1) { - m_ui.interpolate_combo->setCurrentIndex(i); + m_ui.interpolate_combo->setCurrentIndex(index); } }