From 3d6be8e271fd44647efae7200e1d23ed89c09b3f Mon Sep 17 00:00:00 2001 From: Leandro Nini Date: Wed, 16 Oct 2024 20:32:21 +0200 Subject: [PATCH 1/6] Use a separate thread to update the display (#57) --- src/player.cpp | 22 +++++++++++++++++----- src/player.h | 5 +++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/player.cpp b/src/player.cpp index 2963ba0..7cff6a3 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -52,7 +52,7 @@ using std::endl; #include #include - +#include #include using filter_map_t = std::unordered_map; @@ -774,6 +774,18 @@ bool ConsolePlayer::createSidEmu (SIDEMUS emu, const SidTuneInfo *tuneInfo) return false; } +void ConsolePlayer::displayThread() +{ + using namespace std::chrono_literals; + + while (m_state == playerRunning) + { + updateDisplay(); + // TODO 16ms for NTSC? + std::this_thread::sleep_for(20ms); + } +} + bool ConsolePlayer::open (void) { @@ -884,7 +896,8 @@ bool ConsolePlayer::open (void) // Update display menu(); - updateDisplay(); + m_thread = new std::thread(&ConsolePlayer::displayThread, this); + return true; } @@ -917,6 +930,8 @@ void ConsolePlayer::close () cerr << endl; #endif } + m_thread->join(); + delete m_thread; } // Flush any hardware sid fifos so all music is played @@ -946,8 +961,6 @@ bool ConsolePlayer::play() uint_least32_t frames = 0; if (m_state == playerRunning) { - updateDisplay(); - // Fill buffer short *buffer = m_driver.selected->buffer(); // getBufSize returns the number of frames @@ -1064,7 +1077,6 @@ uint_least32_t ConsolePlayer::getBufSize() } -// External Timer Event void ConsolePlayer::updateDisplay() { #ifdef FEAT_NEW_SONLEGTH_DB diff --git a/src/player.h b/src/player.h index 399d06f..17563ab 100644 --- a/src/player.h +++ b/src/player.h @@ -41,6 +41,7 @@ #include #include +#include #ifdef HAVE_TSID # if HAVE_TSID > 1 @@ -184,6 +185,8 @@ class ConsolePlayer int m_precision; int m_buffer_size; + std::thread *m_thread; + struct m_filter_t { // Filter parameter for reSID @@ -261,6 +264,8 @@ class ConsolePlayer inline bool tryOpenTune(const char *hvscBase); inline bool tryOpenDatabase(const char *hvscBase, const char *suffix); + void displayThread(); + public: ConsolePlayer (const char * const name); virtual ~ConsolePlayer() = default; From 5c892b21d0bb53593fd87c6bba1169b776a3475f Mon Sep 17 00:00:00 2001 From: Leandro Nini Date: Sun, 20 Oct 2024 16:27:34 +0200 Subject: [PATCH 2/6] Fix possible crash at exit --- src/player.cpp | 8 ++++++-- src/player.h | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/player.cpp b/src/player.cpp index 7cff6a3..b2e74eb 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -930,8 +930,12 @@ void ConsolePlayer::close () cerr << endl; #endif } - m_thread->join(); - delete m_thread; + + if (m_thread) + { + m_thread->join(); + delete m_thread; + } } // Flush any hardware sid fifos so all music is played diff --git a/src/player.h b/src/player.h index 17563ab..b350881 100644 --- a/src/player.h +++ b/src/player.h @@ -185,7 +185,7 @@ class ConsolePlayer int m_precision; int m_buffer_size; - std::thread *m_thread; + std::thread *m_thread = nullptr; struct m_filter_t { From d16f016e1161d37d9c8962f4ca1d0bb26d79720e Mon Sep 17 00:00:00 2001 From: Leandro Nini Date: Sun, 20 Oct 2024 18:00:09 +0200 Subject: [PATCH 3/6] Use a lambra for display update function --- src/player.cpp | 25 +++++++++++-------------- src/player.h | 2 -- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/player.cpp b/src/player.cpp index b2e74eb..9dd6570 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -774,19 +774,6 @@ bool ConsolePlayer::createSidEmu (SIDEMUS emu, const SidTuneInfo *tuneInfo) return false; } -void ConsolePlayer::displayThread() -{ - using namespace std::chrono_literals; - - while (m_state == playerRunning) - { - updateDisplay(); - // TODO 16ms for NTSC? - std::this_thread::sleep_for(20ms); - } -} - - bool ConsolePlayer::open (void) { if ((m_state & ~playerFast) == playerRestart) @@ -896,7 +883,17 @@ bool ConsolePlayer::open (void) // Update display menu(); - m_thread = new std::thread(&ConsolePlayer::displayThread, this); + m_thread = new std::thread([this]() + { + using namespace std::chrono_literals; + + while (m_state == playerRunning) + { + updateDisplay(); + // TODO 16ms for NTSC? + std::this_thread::sleep_for(20ms); + } + }); return true; } diff --git a/src/player.h b/src/player.h index b350881..37b8918 100644 --- a/src/player.h +++ b/src/player.h @@ -264,8 +264,6 @@ class ConsolePlayer inline bool tryOpenTune(const char *hvscBase); inline bool tryOpenDatabase(const char *hvscBase, const char *suffix); - void displayThread(); - public: ConsolePlayer (const char * const name); virtual ~ConsolePlayer() = default; From 18a8c1d8a5cdfdbe146a4a482cdfa45cc23d989d Mon Sep 17 00:00:00 2001 From: Leandro Nini Date: Sun, 20 Oct 2024 18:17:38 +0200 Subject: [PATCH 4/6] Update display at 60Hz for NTSC playback --- src/player.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/player.cpp b/src/player.cpp index 9dd6570..eb98d7b 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -809,22 +809,19 @@ bool ConsolePlayer::open (void) return false; } + const bool isNTSC = ( + (m_engCfg.defaultC64Model == SidConfig::NTSC) && + (m_engCfg.forceC64Model || (tuneInfo->clockSpeed() != SidTuneInfo::CLOCK_PAL)) + ) || + (tuneInfo->clockSpeed() == SidTuneInfo::CLOCK_NTSC); + #ifdef FEAT_FILTER_DISABLE m_engine.filter(0, m_filter.enabled); m_engine.filter(1, m_filter.enabled); m_engine.filter(2, m_filter.enabled); #endif #ifdef FEAT_REGS_DUMP_SID - if ( - ( - (m_engCfg.defaultC64Model == SidConfig::NTSC) && - (m_engCfg.forceC64Model || (tuneInfo->clockSpeed() != SidTuneInfo::CLOCK_PAL)) - ) || - (tuneInfo->clockSpeed() == SidTuneInfo::CLOCK_NTSC) - ) - m_freqTable = freqTableNtsc; - else - m_freqTable = freqTablePal; + m_freqTable = isNTSC ? freqTableNtsc : freqTablePal; #endif // Start the player. Do this by fast // forwarding to the start position @@ -883,17 +880,17 @@ bool ConsolePlayer::open (void) // Update display menu(); - m_thread = new std::thread([this]() - { - using namespace std::chrono_literals; + // Update display at 50/60Hz + int delay = isNTSC ? 16 : 20; + m_thread = new std::thread([this](int delay) + { while (m_state == playerRunning) { updateDisplay(); - // TODO 16ms for NTSC? - std::this_thread::sleep_for(20ms); + std::this_thread::sleep_for(std::chrono::milliseconds(delay)); } - }); + }, delay); return true; } From 1cc56ac4403dc5138fd26a75a0c8e66a4169b5c5 Mon Sep 17 00:00:00 2001 From: Leandro Nini Date: Sun, 20 Oct 2024 20:39:36 +0200 Subject: [PATCH 5/6] Mark variable atomic as it is being altered in a separate thread --- src/player.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/player.h b/src/player.h index 37b8918..3532c0c 100644 --- a/src/player.h +++ b/src/player.h @@ -42,6 +42,7 @@ #include #include #include +#include #ifdef HAVE_TSID # if HAVE_TSID > 1 @@ -216,7 +217,7 @@ class ConsolePlayer struct m_timer_t { // secs uint_least32_t start; - uint_least32_t current; + std::atomic current; uint_least32_t stop; uint_least32_t length; bool valid; From 7abc1d6af7e78af5f976c77912378ea4932de4bf Mon Sep 17 00:00:00 2001 From: Leandro Nini Date: Tue, 22 Oct 2024 21:01:48 +0200 Subject: [PATCH 6/6] Fix few display issues --- src/player.cpp | 7 ++++--- src/player.h | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/player.cpp b/src/player.cpp index eb98d7b..346894b 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -885,9 +885,10 @@ bool ConsolePlayer::open (void) int delay = isNTSC ? 16 : 20; m_thread = new std::thread([this](int delay) { - while (m_state == playerRunning) + while (m_state != playerStopped) { - updateDisplay(); + if (m_state == playerRunning) + updateDisplay(); std::this_thread::sleep_for(std::chrono::milliseconds(delay)); } }, delay); @@ -897,7 +898,7 @@ bool ConsolePlayer::open (void) void ConsolePlayer::close () { - m_engine.stop(); + stop(); if (m_state == playerExit) { // Natural finish emuflush (); diff --git a/src/player.h b/src/player.h index 3532c0c..d5416ee 100644 --- a/src/player.h +++ b/src/player.h @@ -148,7 +148,9 @@ class ConsolePlayer sidplayfp m_engine; SidConfig m_engCfg; SidTune m_tune; - player_state_t m_state; + + std::atomic m_state; + const char* m_outfile; std::string m_filename;