|
From: Tapio V. <aa...@us...> - 2011-02-24 11:38:09
|
Author: Tapio Vierros <tap...@gm...>
Date: Thu Feb 24 13:10:38 2011 +0200
Synth work.
* Remove Windows QSound hack
* Use alternative BufferPlayer strategy (not constantly creating new ones)
* Now kind of works on Windows, but the sounds are wrong sometimes :S
---
editorapp.cc | 14 +++++++-------
editorapp.hh | 2 ++
synth.hh | 44 +++++++++++++++-----------------------------
3 files changed, 24 insertions(+), 36 deletions(-)
diff --git a/editorapp.cc b/editorapp.cc
index f8009a6..57b18a5 100644
--- a/editorapp.cc
+++ b/editorapp.cc
@@ -46,7 +46,7 @@ namespace {
EditorApp::EditorApp(QWidget *parent)
: QMainWindow(parent), gettingStarted(), noteGraph(), player(), audioOutput(), video(), synth(), statusbarProgress(),
- projectFileName(), latestPath(QDir::homePath())
+ projectFileName(), latestPath(QDir::homePath()), currentBufferPlayer()
{
ui.setupUi(this);
readSettings();
@@ -96,6 +96,9 @@ EditorApp::EditorApp(QWidget *parent)
audioOutput = new Phonon::AudioOutput(this);
player->setTickInterval(100);
Phonon::createPath(player, audioOutput);
+ bufferPlayers[0] = new BufferPlayer(this);
+ bufferPlayers[1] = new BufferPlayer(this);
+
// Audio signals
connect(player, SIGNAL(tick(qint64)), this, SLOT(audioTick(qint64)));
connect(player, SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(playerStateChanged(Phonon::State,Phonon::State)));
@@ -771,11 +774,7 @@ void EditorApp::on_chkSynth_clicked(bool checked)
if (checked && player && player->state() == Phonon::PlayingState) {
synth.reset(new Synth);
connect(synth.data(), SIGNAL(playBuffer(QByteArray)), this, SLOT(playBuffer(QByteArray)));
-#ifdef Q_OS_WIN
- if (audioOutput) audioOutput->setVolume(0.25);
-#else
- if (audioOutput) audioOutput->setVolume(0.75);
-#endif
+ if (audioOutput) audioOutput->setVolume(0.66);
} else if (!checked) {
synth.reset();
if (audioOutput) audioOutput->setVolume(1.0);
@@ -833,7 +832,8 @@ void EditorApp::playerStateChanged(Phonon::State newstate, Phonon::State oldstat
void EditorApp::playBuffer(const QByteArray& buffer)
{
- new BufferPlayer(buffer, this);
+ if (bufferPlayers[currentBufferPlayer]->play(buffer))
+ currentBufferPlayer = (currentBufferPlayer+1) % 2;
}
diff --git a/editorapp.hh b/editorapp.hh
index 91c512c..91df56e 100644
--- a/editorapp.hh
+++ b/editorapp.hh
@@ -139,10 +139,12 @@ private:
Phonon::MediaObject *player;
Phonon::AudioOutput *audioOutput;
Phonon::VideoPlayer *video;
+ BufferPlayer *bufferPlayers[2];
QScopedPointer<Synth> synth;
Piano *piano;
QProgressBar *statusbarProgress;
QPushButton *statusbarButton;
QString projectFileName;
QString latestPath;
+ int currentBufferPlayer;
};
diff --git a/synth.hh b/synth.hh
index 141c354..b914f33 100644
--- a/synth.hh
+++ b/synth.hh
@@ -13,10 +13,6 @@
#include "notes.hh"
#include "notegraphwidget.hh"
#include "notelabel.hh"
-#ifdef Q_OS_WIN
-#include <QTemporaryFile>
-#include <QSound>
-#endif
#ifndef M_PI
@@ -165,7 +161,7 @@ private:
return out.str();
}
- static const int sampleRate = 8000; ///< Sample rate
+ static const int sampleRate = 22050; ///< Sample rate
SynthNotes m_notes; ///< Notes to synthesize
double m_delay; ///< How many seconds until the next sound must be played
@@ -184,41 +180,31 @@ class BufferPlayer: public QObject
Q_OBJECT
Q_DISABLE_COPY(BufferPlayer);
public:
- BufferPlayer(const QByteArray& ba, QObject *parent): QObject(parent) {
-#ifdef Q_OS_WIN
- QTemporaryFile wavfile;
- if (wavfile.open()) {
- QDataStream stream(&wavfile);
- stream.writeRawData(ba.data(), ba.size());
- QSound::play(wavfile.fileName());
- }
- deleteLater();
-#else
- m_data = ba;
+ BufferPlayer(QObject *parent): QObject(parent) {
m_player = Phonon::createPlayer(Phonon::MusicCategory);
m_player->setParent(this);
- m_buffer = new QBuffer(&m_data, this);
- m_player->setCurrentSource(m_buffer);
+ m_buffer = new QBuffer(this);
connect(m_player, SIGNAL(finished()), this, SLOT(finished()));
- m_player->play();
-#endif
+ }
+
+ bool play(const QByteArray& ba) {
+ if (m_player->state() != Phonon::PlayingState) {
+ m_player->clear();
+ m_buffer->close();
+ m_buffer->setData(ba);
+ m_player->setCurrentSource(m_buffer);
+ m_player->play();
+ return true;
+ }
+ return false;
}
public slots:
void finished() {
m_player->clear();
- {
- // This seems a bit strange, but looks like it is the best
- // way to release the resources without an occasional crash.
- QObject deleter;
- m_player->setParent(&deleter);
- m_buffer->setParent(&deleter);
- }
- deleteLater();
}
private:
- QByteArray m_data;
QBuffer *m_buffer;
Phonon::MediaObject *m_player;
};
|