|
From: Tapio V. <aa...@us...> - 2011-02-24 21:55:06
|
Author: Tapio Vierros <tap...@gm...>
Date: Thu Feb 24 23:54:21 2011 +0200
Click piano, hear what happens.
---
editorapp.cc | 24 ++++++++++++++++++---
editorapp.hh | 5 ++++
notegraphwidget.cc | 7 ++---
notegraphwidget.hh | 1 +
synth.hh | 56 ++++++++++++++++++++++++++--------------------------
5 files changed, 57 insertions(+), 36 deletions(-)
diff --git a/editorapp.cc b/editorapp.cc
index 27a81ba..06593fd 100644
--- a/editorapp.cc
+++ b/editorapp.cc
@@ -984,17 +984,19 @@ void EditorApp::updatePiano(int y)
piano->move(piano->x(), ui.noteGraphScroller->y() - y);
}
-Piano::Piano(QWidget *parent): QLabel(parent) {}
+Piano::Piano(QWidget *parent): QLabel(parent), m_player(new BufferPlayer(this))
+{
+ setMouseTracking(true);
+}
void Piano::updatePixmap(NoteGraphWidget *ngw)
{
- if (!ngw) return;
const int notes = 12 * 4; // Four octaves
const QColor borderColor = QColor("#c0c0c0");
const QColor selectionColor = QColor("#a00");
const QColor mouseColor = QColor("#090");
- int noteHeight = ngw->n2px(0) - ngw->n2px(1);
- int mousen = int(round(ngw->px2n(mapFromGlobal(QCursor::pos()).y())));
+ int noteHeight = 16;
+ int mousen = round((NoteGraphWidget::Height - mapFromGlobal(QCursor::pos()).y()) / 16.0);
QImage image(50, notes * noteHeight, QImage::Format_ARGB32_Premultiplied);
image.fill(qRgba(0, 0, 0, 0));
@@ -1038,3 +1040,17 @@ void Piano::updatePixmap(NoteGraphWidget *ngw)
}
setPixmap(QPixmap::fromImage(image));
}
+
+void Piano::mousePressEvent(QMouseEvent *event)
+{
+ if (!m_player) return;
+ QByteArray ba;
+ int n = round((NoteGraphWidget::Height - event->pos().y()) / 16.0);
+ Synth::createBuffer(ba, n % 12, 0.2);
+ m_player->play(ba);
+}
+
+void Piano::mouseMoveEvent(QMouseEvent *event)
+{
+ updatePixmap(NULL);
+}
diff --git a/editorapp.hh b/editorapp.hh
index 91df56e..35b9f1a 100644
--- a/editorapp.hh
+++ b/editorapp.hh
@@ -34,6 +34,11 @@ public:
Piano(QWidget *parent = 0);
public slots:
void updatePixmap(NoteGraphWidget *ngw);
+protected:
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+private:
+ BufferPlayer *m_player;
};
diff --git a/notegraphwidget.cc b/notegraphwidget.cc
index bde5149..ef9582b 100644
--- a/notegraphwidget.cc
+++ b/notegraphwidget.cc
@@ -24,10 +24,9 @@ namespace {
}
static const double endMarginSeconds = 5.0;
- static const int NoteGraphHeight = 768;
}
-
+/*static*/ const int NoteGraphWidget::Height = 768;
/*static*/ const QString NoteGraphWidget::BGColor = "#222";
NoteGraphWidget::NoteGraphWidget(QWidget *parent)
@@ -40,7 +39,7 @@ NoteGraphWidget::NoteGraphWidget(QWidget *parent)
// Initially expanding horizontally to fill the space
QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Fixed);
setSizePolicy(sp);
- setFixedHeight(NoteGraphHeight);
+ setFixedHeight(Height);
setFocusPolicy(Qt::StrongFocus);
setAcceptDrops(true);
@@ -731,7 +730,7 @@ QString NoteGraphWidget::dumpLyrics() const
SeekHandle::SeekHandle(QWidget *parent)
: QLabel(parent)
{
- QImage image(8, NoteGraphHeight, QImage::Format_ARGB32_Premultiplied);
+ QImage image(8, NoteGraphWidget::Height, QImage::Format_ARGB32_Premultiplied);
image.fill(qRgba(128, 128, 128, 128));
setPixmap(QPixmap::fromImage(image));
setMouseTracking(true);
diff --git a/notegraphwidget.hh b/notegraphwidget.hh
index 14c37e0..80e5cd7 100644
--- a/notegraphwidget.hh
+++ b/notegraphwidget.hh
@@ -109,6 +109,7 @@ class NoteGraphWidget: public NoteLabelManager
public:
static const QString BGColor;
+ static const int Height;
NoteGraphWidget(QWidget *parent = 0);
diff --git a/synth.hh b/synth.hh
index 6462cf0..58f822a 100644
--- a/synth.hh
+++ b/synth.hh
@@ -59,6 +59,32 @@ public:
m_condition.wakeOne();
}
+ /// Creates the sound
+ static void createBuffer(QByteArray &buffer, int note, double length) {
+ // This is simple beep, so we use mono and lowish sample rate
+ // --> quick to create and small memory footprint
+ // Going to 8 bits seems to create weird samples on Windows though
+ std::string header = writeWavHeader(16, 1, sampleRate, length * sampleRate);
+ buffer = QByteArray(header.c_str(), header.size());
+ double d = (note + 1) / 13.0;
+ double freq = MusicalScale().getNoteFreq(note + 12);
+ double phase = 0;
+ // Synthesize tones
+ for (size_t i = 0; i < length * sampleRate; ++i) {
+ float fvalue = d * 0.2 * std::sin(phase) + 0.2 * std::sin(2 * phase) + (1.0 - d) * 0.2 * std::sin(4 * phase);
+ phase += 2.0 * M_PI * freq / sampleRate;
+
+ // Convert float to 16-bit integer and push to buffer
+ qint16 svalue = fvalue * 32768;
+ char* value = reinterpret_cast<char*>(&svalue);
+ buffer.push_back(value[0]);
+ buffer.push_back(value[1]);
+ }
+
+ //std::ofstream of("/tmp/wavdump.wav");
+ //of.write(buf.data(), buf.size());
+ }
+
signals:
void playBuffer(const QByteArray&);
@@ -110,41 +136,15 @@ private:
if (n.begin != m_noteBegin) {
// Need to create a new buffer
m_noteBegin = n.begin;
- createBuffer(n.note % 12, n.length);
+ createBuffer(m_soundData[m_curBuffer], n.note % 12, n.length);
}
// Compensate for the time spent in this function
m_delay -= timer.elapsed() / 1000.0;
if (m_delay <= 0.001) m_delay = 0.001;
}
- /// Creates the sound
- void createBuffer(int note, double length) {
- // This is simple beep, so we use mono and lowish sample rate
- // --> quick to create and small memory footprint
- // Going to 8 bits seems to create weird samples on Windows though
- std::string header = writeWavHeader(16, 1, sampleRate, length * sampleRate);
- m_soundData[m_curBuffer] = QByteArray(header.c_str(), header.size());
- double d = (note + 1) / 13.0;
- double freq = MusicalScale().getNoteFreq(note + 12);
- double phase = 0;
- // Synthesize tones
- for (size_t i = 0; i < length * sampleRate; ++i) {
- float fvalue = d * 0.2 * std::sin(phase) + 0.2 * std::sin(2 * phase) + (1.0 - d) * 0.2 * std::sin(4 * phase);
- phase += 2.0 * M_PI * freq / sampleRate;
-
- // Convert float to 16-bit integer and push to buffer
- qint16 svalue = fvalue * 32768;
- char* value = reinterpret_cast<char*>(&svalue);
- m_soundData[m_curBuffer].push_back(value[0]);
- m_soundData[m_curBuffer].push_back(value[1]);
- }
-
- //std::ofstream of("/tmp/wavdump.wav");
- //of.write(buf.data(), buf.size());
- }
-
/// WAV header writer
- std::string writeWavHeader(unsigned bits, unsigned ch, unsigned sr, unsigned samples) {
+ static std::string writeWavHeader(unsigned bits, unsigned ch, unsigned sr, unsigned samples) {
std::ostringstream out;
unsigned bps = ch * bits / 8; // Bytes per sample
unsigned datasize = bps * samples;
|