PsfPlayer: Update playback workflow.

This commit is contained in:
Jean-Philip Desjardins 2023-07-10 14:34:04 -04:00
parent 35917957f5
commit 3d0389eecb
7 changed files with 111 additions and 53 deletions

View file

@ -38,6 +38,8 @@ set(PSFCORE_SRC_FILES
AppConfig.h
Iop_PsfSubSystem.cpp
Iop_PsfSubSystem.h
PlaybackController.cpp
PlaybackController.h
Playlist.cpp
Playlist.h
PlaylistDiscoveryService.cpp

View file

@ -0,0 +1,59 @@
#include "PlaybackController.h"
#include <string>
void CPlaybackController::Play(const CPsfTags& tags)
{
m_volumeAdjust = 1.0f;
try
{
m_volumeAdjust = stof(tags.GetTagValue("volume"));
}
catch(...)
{
}
if(tags.HasTag("length"))
{
double length = CPsfTags::ConvertTimeString(tags.GetTagValue("length").c_str());
m_trackLength = static_cast<uint64>(length * 60.0);
}
else
{
m_trackLength = 3600; //1 minute default length
}
double fade = 10.f; //10 seconds default fade
if(tags.HasTag("fade"))
{
fade = CPsfTags::ConvertTimeString(tags.GetTagValue("fade").c_str());
}
m_fadePosition = m_trackLength;
m_trackLength += static_cast<uint64>(fade * 60.f);
m_frames = 0;
m_isPlaying = true;
VolumeChanged(m_volumeAdjust);
}
void CPlaybackController::Tick()
{
if(!m_isPlaying)
{
return;
}
m_frames++;
if(m_frames > m_trackLength)
{
m_isPlaying = false;
PlaybackCompleted();
}
else if(m_frames >= m_fadePosition)
{
float currentRatio = static_cast<float>(m_frames - m_fadePosition) / static_cast<float>(m_trackLength - m_fadePosition);
float currentVolume = (1.0f - currentRatio) * m_volumeAdjust;
VolumeChanged(currentVolume);
}
}
uint64 CPlaybackController::GetFrameCount() const
{
return m_frames;
}

View file

@ -0,0 +1,23 @@
#pragma once
#include "signal/Signal.h"
#include "PsfTags.h"
class CPlaybackController
{
public:
void Play(const CPsfTags&);
void Tick();
uint64 GetFrameCount() const;
Framework::CSignal<void()> PlaybackCompleted;
Framework::CSignal<void(float)> VolumeChanged;
private:
bool m_isPlaying = false;
float m_volumeAdjust = 1.0f;
uint64 m_frames = 0;
uint64 m_fadePosition = 0;
uint64 m_trackLength = 0;
};

View file

@ -1,4 +1,5 @@
#include "PlaylistDiscoveryService.h"
#include "ThreadUtils.h"
#include "PsfStreamProvider.h"
#include "PsfBase.h"
#include "PsfTags.h"
@ -12,6 +13,7 @@ CPlaylistDiscoveryService::CPlaylistDiscoveryService()
{
m_threadActive = true;
m_thread = std::thread([&]() { ThreadProc(); });
Framework::ThreadUtils::SetThreadName(m_thread, "Playlist Discovery Thread");
}
CPlaylistDiscoveryService::~CPlaylistDiscoveryService()

View file

@ -1,6 +1,7 @@
#include <stdexcept>
#include <assert.h>
#include "filesystem_def.h"
#include "ThreadUtils.h"
#include "PsfVm.h"
#include "Log.h"
#include "MA_MIPSIV.h"
@ -18,6 +19,7 @@ CPsfVm::CPsfVm()
{
m_isThreadOver = false;
m_thread = std::thread([&]() { ThreadProc(); });
Framework::ThreadUtils::SetThreadName(m_thread, "PsfVm Thread");
}
CPsfVm::~CPsfVm()

View file

@ -39,41 +39,20 @@ MainWindow::MainWindow(QWidget* parent)
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
ui->tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
m_PlaybackVolumeChangedConnection = m_playbackController.VolumeChanged.Connect(
[this](float volume) { m_virtualMachine->SetVolumeAdjust(volume); });
m_PlaybackCompletedConnection = m_playbackController.PlaybackCompleted.Connect(
[this]() { emit playbackCompleted(); });
auto homePath = QStringToPath(QDir::homePath());
CAppConfig::GetInstance().RegisterPreferencePath(PREFERENCE_UI_LASTFOLDER, homePath);
m_path = CAppConfig::GetInstance().GetPreferencePath(PREFERENCE_UI_LASTFOLDER);
// used as workaround to avoid direct ui access from a thread
connect(this, SIGNAL(ChangeRow(int)), ui->tableView, SLOT(selectRow(int)));
m_running = true;
m_thread = std::thread(&MainWindow::UiUpdateLoop, this);
}
void MainWindow::UiUpdateLoop()
{
while(m_running)
{
auto end = std::chrono::steady_clock::now() + std::chrono::milliseconds(16);
if(m_frames > m_trackLength)
{
m_frames = 0;
on_nextButton_clicked();
}
else if(m_frames >= m_fadePosition)
{
float currentRatio = static_cast<float>(m_frames - m_fadePosition) / static_cast<float>(m_trackLength - m_fadePosition);
float currentVolume = (1.0f - currentRatio) * m_volumeAdjust;
m_virtualMachine->SetVolumeAdjust(currentVolume);
}
std::this_thread::sleep_until(end);
}
connect(this, SIGNAL(playbackCompleted()), this, SLOT(on_playbackCompleted()));
}
MainWindow::~MainWindow()
{
m_running = false;
if(m_thread.joinable()) m_thread.join();
if(m_virtualMachine != nullptr)
{
m_virtualMachine->Pause();
@ -155,6 +134,7 @@ void MainWindow::AddArchiveToPlaylist(const fs::path& archivePath)
void MainWindow::UpdateTrackDetails(CPsfBase::TagMap& tags)
{
auto tag = CPsfTags(tags);
ui->current_game->setText(QString::fromWCharArray(tag.GetTagValue("game").c_str()));
ui->current_total_length->setText(QString::fromWCharArray(tag.GetTagValue("length").c_str()));
ui->current_title->setText(QString::fromWCharArray(tag.GetTagValue("title").c_str()));
@ -162,29 +142,20 @@ void MainWindow::UpdateTrackDetails(CPsfBase::TagMap& tags)
ui->current_cp->setText(QString::fromWCharArray(tag.GetTagValue("copyright").c_str()));
ui->current_year->setText(QString::fromWCharArray(tag.GetTagValue("year").c_str()));
m_volumeAdjust = 1.0f;
ui->tableView->selectRow(m_currentindex);
try
{
m_volumeAdjust = stof(tag.GetTagValue("volume"));
m_virtualMachine->SetVolumeAdjust(m_volumeAdjust);
}
catch(...)
{
}
double dlength = CPsfTags::ConvertTimeString(tag.GetTagValue("length").c_str());
double dfade = CPsfTags::ConvertTimeString(tag.GetTagValue("fade").c_str());
m_trackLength = static_cast<uint64>(dlength * 60.0);
m_fadePosition = m_trackLength - static_cast<uint64>(dfade * 60.0);
m_frames = 0;
m_playbackController.Play(tag);
}
ChangeRow(m_currentindex);
void MainWindow::on_playbackCompleted()
{
on_nextButton_clicked();
}
void MainWindow::OnNewFrame()
{
m_frames++;
ui->current_time->setText(QDateTime::fromTime_t(m_frames / 60).toUTC().toString("mm:ss"));
m_playbackController.Tick();
ui->current_time->setText(QDateTime::fromTime_t(m_playbackController.GetFrameCount() / 60).toUTC().toString("mm:ss"));
}
void MainWindow::on_tableView_customContextMenuRequested(const QPoint& pos)

View file

@ -3,6 +3,7 @@
#include <QMainWindow>
#include "PsfVm.h"
#include "PsfBase.h"
#include "PlaybackController.h"
#include "playlistmodel.h"
#include <thread>
#include "filesystem_def.h"
@ -24,7 +25,6 @@ public:
void AddArchiveToPlaylist(const fs::path&);
private:
void UiUpdateLoop();
void UpdateTrackDetails(CPsfBase::TagMap&);
void OnNewFrame();
@ -35,19 +35,17 @@ private:
CPsfVm* m_virtualMachine;
PlaylistModel model;
int m_currentindex = -1;
uint64 m_trackLength = 10;
uint64 m_frames = 0;
uint64 m_fadePosition = 1;
float m_volumeAdjust;
CPlaybackController m_playbackController;
std::thread m_thread;
std::atomic<bool> m_running;
fs::path m_path;
Framework::CSignal<void()>::Connection m_OnNewFrameConnection;
Q_SIGNALS:
void ChangeRow(int);
Framework::CSignal<void(float)>::Connection m_PlaybackVolumeChangedConnection;
Framework::CSignal<void()>::Connection m_PlaybackCompletedConnection;
signals:
void playbackCompleted();
private slots:
void on_actionOpen_triggered();
@ -59,4 +57,5 @@ private slots:
void on_actionPlayPause_triggered();
void on_actionPrev_triggered();
void on_actionNext_triggered();
void on_playbackCompleted();
};