|
From: Tapio V. <aa...@us...> - 2011-02-28 10:04:36
|
Author: Tapio Vierros <tap...@gm...>
Date: Mon Feb 28 12:04:06 2011 +0200
Some code comments.
---
editorapp.hh | 1 +
notegraphwidget.cc | 4 +++-
notegraphwidget.hh | 2 +-
notelabel.cc | 4 ++++
notelabel.hh | 18 ++++++++++++++++++
operation.hh | 4 ++--
synth.hh | 21 +++++++++++++++------
7 files changed, 44 insertions(+), 10 deletions(-)
diff --git a/editorapp.hh b/editorapp.hh
index 35b9f1a..0164c14 100644
--- a/editorapp.hh
+++ b/editorapp.hh
@@ -27,6 +27,7 @@ public:
AboutDialog(QWidget* parent = 0);
};
+
class Piano: public QLabel
{
Q_OBJECT
diff --git a/notegraphwidget.cc b/notegraphwidget.cc
index ef9582b..eecfcb9 100644
--- a/notegraphwidget.cc
+++ b/notegraphwidget.cc
@@ -173,6 +173,7 @@ void NoteGraphWidget::timerEvent(QTimerEvent* event)
killTimer(m_analyzeTimer);
updatePitch();
}
+
} else if (event->timerId() == m_notePixmapTimer) {
// Here we create a pixmap for a NoteLabel
if (m_nextNotePixmap >= m_notes.size()) {
@@ -181,7 +182,7 @@ void NoteGraphWidget::timerEvent(QTimerEvent* event)
m_nextNotePixmap = 0;
return;
}
- // Loop until a pixmap-to-create is found
+ // Loop until a pixmap-to-create is found - we only create one at a time to not block the UI
while (m_nextNotePixmap < m_notes.size() && !m_notes[m_nextNotePixmap]->createPixmap())
++m_nextNotePixmap;
++m_nextNotePixmap;
@@ -191,6 +192,7 @@ void NoteGraphWidget::timerEvent(QTimerEvent* event)
void NoteGraphWidget::startNotePixmapUpdates()
{
// With 0-delay, note pixmaps are created whenever there is not events to process
+ // This means fast performance while keeping snappy interface
if (!m_notePixmapTimer) m_notePixmapTimer = startTimer(0);
m_nextNotePixmap = 0;
}
diff --git a/notegraphwidget.hh b/notegraphwidget.hh
index 80e5cd7..6b770ca 100644
--- a/notegraphwidget.hh
+++ b/notegraphwidget.hh
@@ -136,7 +136,7 @@ public slots:
void updatePitch();
void abortPitch() { if (m_pitch) m_pitch->cancel(); }
void scrollToFirstNote();
- void startNotePixmapUpdates();
+ void startNotePixmapUpdates(); ///< Starts creating pixmaps for NoteLabels
signals:
void analyzeProgress(int, int);
diff --git a/notelabel.cc b/notelabel.cc
index 5c4701b..b011b24 100644
--- a/notelabel.cc
+++ b/notelabel.cc
@@ -22,6 +22,10 @@ NoteLabel::NoteLabel(const Note ¬e, QWidget *parent, bool floating)
updateLabel();
setMouseTracking(true);
hide();
+ // We don't want to show the widget and create the pixmap as that is slow.
+ // Since the undo-framework relies on rapidly creating and deleting NoteLabels,
+ // this is a necessity to get adequete performance. NoteGraphWidget creates the
+ // pixmaps later on once the final NoteLabels have been found.
}
void NoteLabel::updatePixmap()
diff --git a/notelabel.hh b/notelabel.hh
index 21eec62..d608008 100644
--- a/notelabel.hh
+++ b/notelabel.hh
@@ -6,6 +6,21 @@
#include "notes.hh"
#include "operation.hh"
+/**
+ * @brief Widget representing a single note.
+ *
+ * Notes:
+ * - Is rather useless without a parent NoteGraphWidget-object
+ * - Widget is initially hidden and without a pixmap to allow quick creation
+ * - Pixmap updates are generally delayed a little
+ * - The idea is to allow some time to apply the base operation to every note
+ * and then do the gfx updates asynchronously
+ * - NoteLabel has its own mouse handling for moving, resizing, cursors, tooltips etc,
+ but requires the parent NoteGraphWidget to update some internal states
+ * - Geometry & position is calculated from the underlying Note attributes (i.e. time and pitch)
+ * - Setting size or pos manually will be overridden so the Note must be manipulated instead
+ * - NoteLabel can be serialized to Operation-class
+ */
class NoteLabel: public QLabel
{
Q_OBJECT
@@ -45,7 +60,10 @@ public:
bool operator<(const NoteLabel &rhs) const { return m_note.begin < rhs.note().begin; }
public slots:
+ /// Shows the widget and creates the pixmap; if already visible, do nothing
+ /// @return true if pixmap was actually created, false if the widget was already visible
bool createPixmap() { if (isVisible()) return false; show(); updatePixmap(); return true; }
+ /// Updates the pixmap but only if the widget is visible (i.e. createPixmap has been called)
void updatePixmap();
protected:
diff --git a/operation.hh b/operation.hh
index c90ee9e..8324f41 100644
--- a/operation.hh
+++ b/operation.hh
@@ -35,7 +35,7 @@ struct Operation
template<typename T>
T param(int index) const { validate(index); m_params[index].value<T>(); }
- /// Get Operation parameter at certain index (1-based)
+ // Get Operation parameter at certain index (1-based)
QString s(int index) const { validate(index); return m_params[index].toString(); }
char c(int index) const { validate(index); return m_params[index].toChar().toAscii(); }
@@ -46,7 +46,7 @@ struct Operation
double d(int index) const { validate(index); return m_params[index].toDouble(); }
QVariant q(int index) const { validate(index); return m_params[index]; }
- // Array access for modifying param
+ /// Array access for modifying param
QVariant& operator[](int index) { validate(index); return m_params[index]; }
std::string dump() const {
diff --git a/synth.hh b/synth.hh
index 58f822a..fccb9bd 100644
--- a/synth.hh
+++ b/synth.hh
@@ -30,7 +30,11 @@ struct SynthNote {
typedef QList<SynthNote> SynthNotes;
-
+/**
+ * @brief Threaded WAV buffer creator.
+ *
+ * Synthesizes and schedules notes in a thread and sends them to the main thread when its time to play them.
+ */
class Synth: public QThread
{
Q_OBJECT
@@ -170,14 +174,19 @@ private:
double m_delay; ///< How many seconds until the next sound must be played
double m_pos; ///< Position where we are now
double m_noteBegin; ///< Position of the next note
- QByteArray m_soundData[2];
- int m_curBuffer;
- bool m_quit;
- QMutex m_mutex;
- QWaitCondition m_condition;
+ QByteArray m_soundData[2]; ///< The WAV buffers
+ int m_curBuffer; ///< Which buffer we are currently using
+ bool m_quit; ///< Flag to signal the thread should quit
+ QMutex m_mutex; ///< Mutex for protecting resource access
+ QWaitCondition m_condition; ///< For signaling the thread
};
+/**
+ * @brief Class for playing a WAV buffer from memory.
+ *
+ * Designed to be reused, but won't play the buffer if the previous hasn't finished.
+ */
class BufferPlayer: public QObject
{
Q_OBJECT
|