From 98257a10d34b824d82d7c4e22113173f4cf8a3ec Mon Sep 17 00:00:00 2001 From: w1z7ard Date: Mon, 11 Feb 2008 13:41:44 +0000 Subject: [PATCH] almost correct mutex locking on projectm resets git-svn-id: https://projectm.svn.sourceforge.net/svnroot/projectm/trunk@817 6778bc44-b910-0410-a7a0-be141de4315d --- src/projectM-engine/PCM.cpp | 8 ------- src/qprojectM-jack/qprojectM-jack.cpp | 2 +- .../QPulseAudioThread.cpp | 15 ++++++++++--- .../QPulseAudioThread.hpp | 10 ++++++--- .../qprojectM-pulseaudio.cpp | 4 +++- src/qprojectM/QProjectM_MainWindow.cpp | 12 ++++++---- src/qprojectM/QProjectM_MainWindow.hpp | 22 ++++++++++++++----- 7 files changed, 47 insertions(+), 26 deletions(-) diff --git a/src/projectM-engine/PCM.cpp b/src/projectM-engine/PCM.cpp index c926c4210..06ba1d12d 100755 --- a/src/projectM-engine/PCM.cpp +++ b/src/projectM-engine/PCM.cpp @@ -107,14 +107,6 @@ void PCM::addPCMfloat(const float *PCMdata, int samples) const { int i,j; - std::cerr << "start:" << this->start << std::endl; - static bool firstTime = true; - - if (firstTime) { - start = 0; - firstTime = false; - } - for(i=0;ishow(); globalPM = mainWindow->getQProjectM(); diff --git a/src/qprojectM-pulseaudio/QPulseAudioThread.cpp b/src/qprojectM-pulseaudio/QPulseAudioThread.cpp index 514632cc0..e62e92429 100644 --- a/src/qprojectM-pulseaudio/QPulseAudioThread.cpp +++ b/src/qprojectM-pulseaudio/QPulseAudioThread.cpp @@ -46,7 +46,7 @@ pa_io_event * QPulseAudioThread::stdio_event = NULL; char * QPulseAudioThread::server = NULL; char * QPulseAudioThread::stream_name = NULL, *QPulseAudioThread::client_name = NULL, *QPulseAudioThread::device =0; - + QMutex QPulseAudioThread::s_audioMutex; int QPulseAudioThread::verbose = 0; pa_volume_t QPulseAudioThread::volume = PA_VOLUME_NORM; @@ -259,16 +259,21 @@ void QPulseAudioThread::pa_stream_success_callback(pa_stream *s, int success, vo pausedFlag = !pausedFlag; - //m_projectM._audioMutex.unlock(); + // necessarily static // can do pulse stuff here... } +QMutex * QPulseAudioThread::mutex() { + return &s_audioMutex; +} + void QPulseAudioThread::cork() { int b = 0; + s_audioMutex.tryLock(); pa_operation* op = pa_stream_cork(stream, b, pa_stream_success_callback, this); @@ -442,16 +447,20 @@ void QPulseAudioThread::stdout_callback ( pa_mainloop_api*a, pa_io_event *e, int } else { - QProjectM * prjm = static_cast ( userdata ); + //int * int_buf = (int *) buffer; //qDebug() << int_buf[buffer_index]; //qDebug() << buffer[buffer_index]; + s_audioMutex.tryLock(); + QProjectM * prjm = static_cast ( userdata ); assert(prjm); assert(prjm->pcm()); assert(buffer); qDebug() << "buffer index: " << buffer_index << ", buffer length:" << buffer_length; + prjm->pcm()->addPCMfloat ( buffer+buffer_index, buffer_length / ( sizeof ( float ) ) ); + s_audioMutex.unlock(); assert ( buffer_length ); diff --git a/src/qprojectM-pulseaudio/QPulseAudioThread.hpp b/src/qprojectM-pulseaudio/QPulseAudioThread.hpp index 136454d87..2ef33e4f4 100644 --- a/src/qprojectM-pulseaudio/QPulseAudioThread.hpp +++ b/src/qprojectM-pulseaudio/QPulseAudioThread.hpp @@ -7,7 +7,8 @@ #include #include #include -// +#include + extern "C" { #include @@ -29,6 +30,9 @@ class QPulseAudioThread : public QThread void run(); void cleanup(); + + QMutex * mutex(); + inline const SourceContainer & devices() { return s_sourceList; } @@ -82,8 +86,8 @@ class QPulseAudioThread : public QThread static void time_event_callback ( pa_mainloop_api*m, pa_time_event *e, const struct timeval *tv, void *userdata ); static void pa_stream_success_callback(pa_stream *s, int success, void *userdata); - - + + static QMutex s_audioMutex; static SourceContainer s_sourceList; static SourceContainer::const_iterator s_sourcePosition; int argc; diff --git a/src/qprojectM-pulseaudio/qprojectM-pulseaudio.cpp b/src/qprojectM-pulseaudio/qprojectM-pulseaudio.cpp index a29003d05..8fd7b32ad 100644 --- a/src/qprojectM-pulseaudio/qprojectM-pulseaudio.cpp +++ b/src/qprojectM-pulseaudio/qprojectM-pulseaudio.cpp @@ -93,7 +93,7 @@ int main ( int argc, char*argv[] ) std::string config_file; config_file = read_config(); - QProjectM_MainWindow * mainWindow = new QProjectM_MainWindow ( config_file); + QProjectM_MainWindow * mainWindow = new QProjectM_MainWindow ( config_file, 0); QAction pulseAction("Pulse audio settings...", mainWindow); @@ -103,6 +103,8 @@ int main ( int argc, char*argv[] ) QPulseAudioThread * pulseThread = new QPulseAudioThread(argc, argv, mainWindow->getQProjectM(), mainWindow); + mainWindow->getQProjectMWidget()->setAudioMutex(pulseThread->mutex()); + // First projectM_Initialized() has already happened, so manually start pulseThread->start(); diff --git a/src/qprojectM/QProjectM_MainWindow.cpp b/src/qprojectM/QProjectM_MainWindow.cpp index 150fb7a5e..49057ed86 100644 --- a/src/qprojectM/QProjectM_MainWindow.cpp +++ b/src/qprojectM/QProjectM_MainWindow.cpp @@ -70,7 +70,7 @@ class PlaylistWriteFunctor { }; -QProjectM_MainWindow::QProjectM_MainWindow ( const std::string & config_file ) +QProjectM_MainWindow::QProjectM_MainWindow ( const std::string & config_file, QMutex * audioMutex) :m_QPresetFileDialog ( new QPresetFileDialog ( this ) ), m_QPlaylistFileDialog ( new QPlaylistFileDialog ( this ) ), oldPresetIndex ( -1 ), playlistModel(0), configDialog(0), _menuVisible(true) { @@ -79,7 +79,7 @@ QProjectM_MainWindow::QProjectM_MainWindow ( const std::string & config_file ) ui = new Ui::QProjectM_MainWindow(); ui->setupUi ( this ); - m_QProjectMWidget = new QProjectMWidget ( config_file, this ); + m_QProjectMWidget = new QProjectMWidget ( config_file, this, audioMutex); m_timer = new QTimer ( this ); connect ( m_timer, SIGNAL ( timeout() ), m_QProjectMWidget, SLOT ( updateGL() ) ); @@ -220,9 +220,13 @@ void QProjectM_MainWindow::postProjectM_Initialize() ui->tableView->setModel ( playlistModel ); /// @bug only do this at startup? - refreshPlaylist(); - + static bool firstOfRefreshPlaylist = true; + if (firstOfRefreshPlaylist) { + refreshPlaylist(); + firstOfRefreshPlaylist = false; + } + if (!configDialog) { configDialog = new QProjectMConfigDialog(m_QProjectMWidget->configFile(), m_QProjectMWidget, this); diff --git a/src/qprojectM/QProjectM_MainWindow.hpp b/src/qprojectM/QProjectM_MainWindow.hpp index bfb28ca7e..361b2d6e5 100644 --- a/src/qprojectM/QProjectM_MainWindow.hpp +++ b/src/qprojectM/QProjectM_MainWindow.hpp @@ -70,8 +70,8 @@ class QProjectMWidget : public QGLWidget Q_OBJECT // must include this if you use Qt signals/slots public: - QProjectMWidget(const std::string & _config_file, QWidget *parent) - : QGLWidget(parent), config_file(_config_file), m_projectM(0) {} + QProjectMWidget(const std::string & _config_file, QWidget *parent, QMutex * audioMutex) + : QGLWidget(parent), config_file(_config_file), m_projectM(0), m_audioMutex(audioMutex) {} ~QProjectMWidget() { destroyProjectM(); } inline const std::string & configFile() { @@ -98,6 +98,7 @@ class QProjectMWidget : public QGLWidget // First wait for audio thread to stop by // waiting on it's mutex // s_audioMutex.tryLock(20000); + m_audioMutex->tryLock(); // Now destroy the projectM instance destroyProjectM(); @@ -106,11 +107,18 @@ class QProjectMWidget : public QGLWidget initializeGL(); // Allow audio thread to continue its business -// _audioMutex.unlock(); - + if (m_audioMutex) { + qDebug() << "UNLOCKED"; + m_audioMutex->unlock(); + } qDebug() << "reinit'ed"; } + + void setAudioMutex(QMutex * mutex) { + m_audioMutex = mutex; + } + void setPresetLock(int state) { m_projectM->setPresetLock((bool)state); emit(presetLockChanged((bool)state)); @@ -122,7 +130,8 @@ class QProjectMWidget : public QGLWidget private: std::string config_file; QProjectM * m_projectM; - QMutex _audioMutex; + + QMutex * m_audioMutex; protected: @@ -259,12 +268,13 @@ public: typedef QVector PlaylistItemVector; - QProjectM_MainWindow(const std::string & config_file); + QProjectM_MainWindow(const std::string & config_file, QMutex * audioMutex); virtual ~QProjectM_MainWindow(); void registerSettingsAction(QAction * action); void unregisterSettingsAction(QAction * action); void setMenuVisible(bool visible); + void keyReleaseEvent ( QKeyEvent * e ); QProjectM * getQProjectM(); void refreshPlaylist();