summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dgedit/canvastoollisten.cc87
-rw-r--r--dgedit/canvastoollisten.h33
-rw-r--r--dgedit/mainwindow.cc10
-rw-r--r--dgedit/mainwindow.h3
-rw-r--r--dgedit/player.cc106
-rw-r--r--dgedit/player.h82
6 files changed, 224 insertions, 97 deletions
diff --git a/dgedit/canvastoollisten.cc b/dgedit/canvastoollisten.cc
index 569a164..f842235 100644
--- a/dgedit/canvastoollisten.cc
+++ b/dgedit/canvastoollisten.cc
@@ -28,78 +28,19 @@
#include <QApplication>
-#define BUFSZ 1024 * 2
-
-Player::Player(Canvas *c)
-{
- canvas = c;
- playing = false;
- pos = 0;
-
- ao_initialize();
-
- ao_sample_format sf;
- sf.bits = 16;
- sf.rate = 44100;
- sf.channels = 1;
- sf.byte_format = AO_FMT_NATIVE;
-
- dev = ao_open_live(ao_default_driver_id(), &sf, 0);
-
- volume = 1000;
-}
-
-Player::~Player()
-{
- ao_close(dev);
- ao_shutdown();
-}
-
-void Player::run()
-{
- while(true) {
- if(playing) {
- short s[BUFSZ];
- for(size_t i = 0; i < BUFSZ; i++) {
- if(i + pos < canvas->size) s[i] = canvas->data[pos + i] * volume;
- else {
- s[i] = 0;
- playing = false;
- }
- }
-
- ao_play(dev, (char*)s, BUFSZ * sizeof(short));
- // canvas->update();
-
- pos += BUFSZ;
-
- } else {
- msleep(22);
- }
- }
-}
-
-void Player::setVolume(double v)
+CanvasToolListen::CanvasToolListen(Canvas *c, Player &p)
+ : player(p)
{
- volume = v;
-}
-
-CanvasToolListen::CanvasToolListen(Canvas *c)
- : player(c)
-{
- lastpos = 0;
+ lastpos = pos = 0;
canvas = c ;
- player.start();
- QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(update()));
}
bool CanvasToolListen::mousePressEvent(QMouseEvent *event)
{
if(!isActive()) return false;
- player.pos = canvas->unmapX(event->x());
player.playing = true;
canvas->update();
- timer.start(50);
+ connect(&player, SIGNAL(positionUpdate(size_t)), this, SLOT(update(size_t)));
return true;
}
@@ -107,7 +48,8 @@ bool CanvasToolListen::mouseReleaseEvent(QMouseEvent *event)
{
if(!isActive()) return false;
player.playing = false;
- timer.stop();
+ disconnect(&player, SIGNAL(positionUpdate(size_t)),
+ this, SLOT(update(size_t)));
lastpos = 0;
canvas->update();
return true;
@@ -119,16 +61,16 @@ void CanvasToolListen::paintEvent(QPaintEvent *event, QPainter &painter)
if(player.playing) {
painter.setPen(QColor(0, 127, 127));
- painter.drawLine(canvas->mapX(player.pos),
+ painter.drawLine(canvas->mapX(pos),
event->rect().y(),
- canvas->mapX(player.pos),
+ canvas->mapX(pos),
event->rect().y() + event->rect().height());
}
}
-void CanvasToolListen::update()
+void CanvasToolListen::update(size_t pos)
{
- size_t pos = player.pos;
+ this->pos = pos;
size_t last = canvas->mapX(lastpos);
size_t x = canvas->mapX(player.pos);
QRect r(last, 0,
@@ -140,19 +82,24 @@ void CanvasToolListen::update()
void CanvasToolListen::setVolume(int v)
{
- player.setVolume(v);
+ player.setGainScalar(v);
}
+/*
+ * UGLY HACK: This method is in dire need of a rewrite!
+ */
#include <unistd.h>
void CanvasToolListen::playRange(unsigned int from, unsigned int to)
{
player.pos = from;
player.playing = true;
canvas->update();
- timer.start(50);
+ connect(&player, SIGNAL(positionUpdate(size_t)), this, SLOT(update(size_t)));
while(player.pos < to) {
qApp->processEvents();
usleep(10000);
}
+ disconnect(&player, SIGNAL(positionUpdate(size_t)),
+ this, SLOT(update(size_t)));
player.playing = false;
}
diff --git a/dgedit/canvastoollisten.h b/dgedit/canvastoollisten.h
index dccc3f9..810e7cb 100644
--- a/dgedit/canvastoollisten.h
+++ b/dgedit/canvastoollisten.h
@@ -29,35 +29,15 @@
#include "canvastool.h"
-#include <QThread>
-#include <QTimer>
-
-#include <ao/ao.h>
+//#include <QTimer>
#include "canvas.h"
-
-class Player : public QThread {
-public:
- Player(Canvas *canvas);
- ~Player();
-
- void run();
-
- volatile bool playing;
- volatile size_t pos;
-
- void setVolume(double v);
-
-private:
- ao_device *dev;
- Canvas *canvas;
- double volume;
-};
+#include "player.h"
class CanvasToolListen : public CanvasTool {
Q_OBJECT
public:
- CanvasToolListen(Canvas *canvas);
+ CanvasToolListen(Canvas *canvas, Player &player);
QString name() { return "Listen"; }
bool mousePressEvent(QMouseEvent *event);
@@ -67,15 +47,16 @@ public:
void playRange(unsigned int from, unsigned int to);
public slots:
- void update();
+ void update(size_t position);
void setVolume(int v);
private:
Canvas *canvas;
- Player player;
- QTimer timer;
+ Player &player;
+
size_t lastpos;
+ size_t pos;
};
#endif/*__DRUMGIZMO_CANVASTOOLLISTEN_H__*/
diff --git a/dgedit/mainwindow.cc b/dgedit/mainwindow.cc
index 412cd32..82eaaa6 100644
--- a/dgedit/mainwindow.cc
+++ b/dgedit/mainwindow.cc
@@ -73,8 +73,11 @@ MainWindow::MainWindow()
extractor = new AudioExtractor(session, this);
canvas = new Canvas(this);
+ player = new Player(canvas);
+ player->start();
+
QToolBar *toolbar = addToolBar("Tools");
- g_listen = new CanvasToolListen(canvas);
+ g_listen = new CanvasToolListen(canvas, *player);
CanvasTool *listen = g_listen;
addTool(toolbar, canvas, listen);
CanvasTool *threshold = new CanvasToolThreshold(canvas);
@@ -298,6 +301,11 @@ MainWindow::MainWindow()
statusBar()->showMessage("Ready");
}
+MainWindow::~MainWindow()
+{
+ delete player;
+}
+
void MainWindow::setAttackLengthLineEd(int value)
{
lineed_attacklength->setText(QString::number(value));
diff --git a/dgedit/mainwindow.h b/dgedit/mainwindow.h
index 6758779..ccb2f07 100644
--- a/dgedit/mainwindow.h
+++ b/dgedit/mainwindow.h
@@ -40,6 +40,7 @@
#include "filelist.h"
#include "canvastoolselections.h"
#include "selection.h"
+#include "player.h"
class Preset {
public:
@@ -54,6 +55,7 @@ class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow();
+ ~MainWindow();
public slots:
void setXScale(int);
@@ -96,6 +98,7 @@ private:
// Session state information:
Selections session;
+ Player *player;
private slots:
void setAttackLengthLineEd(int);
diff --git a/dgedit/player.cc b/dgedit/player.cc
new file mode 100644
index 0000000..a7f09c3
--- /dev/null
+++ b/dgedit/player.cc
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * player.cc
+ *
+ * Tue Apr 15 10:34:18 CEST 2014
+ * Copyright 2014 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "player.h"
+
+#include <math.h>
+
+#define BUFSZ 1024 * 2
+
+Player::Player(Canvas *c)
+{
+ canvas = c;
+ playing = false;
+ pos = 0;
+
+ ao_initialize();
+
+ ao_sample_format sf;
+ sf.bits = 16;
+ sf.rate = 44100;
+ sf.channels = 1;
+ sf.byte_format = AO_FMT_NATIVE;
+
+ dev = ao_open_live(ao_default_driver_id(), &sf, 0);
+
+ gain_scalar = 1000;
+
+ peak = 0;
+
+ connect(&report_timer, SIGNAL(timeout()), this, SLOT(reportTimeout()));
+ report_timer.start(50); // Update 25 times per second
+}
+
+Player::~Player()
+{
+ ao_close(dev);
+ ao_shutdown();
+}
+
+void Player::run()
+{
+ short s[BUFSZ];
+ while(true) {
+ if(playing) {
+ for(size_t i = 0; i < BUFSZ; i++) {
+ double sample = 0.0;
+ if(i + pos < canvas->size) {
+ sample = canvas->data[pos + i] * gain_scalar;
+ } else {
+ playing = false;
+ }
+ if(abs(sample) > peak) peak = abs(sample);
+ s[i] = sample * SHRT_MAX;
+ }
+
+ ao_play(dev, (char*)s, BUFSZ * sizeof(short));
+
+ pos += BUFSZ;
+
+ } else {
+ msleep(22);
+ }
+ }
+}
+
+void Player::setGainScalar(double g)
+{
+ gain_scalar = g / 10000.0;
+}
+
+void Player::setGainDB(double gain_db)
+{
+ setGainScalar(20*log10(gain_db));
+}
+
+void Player::reportTimeout()
+{
+ emit peakUpdate(peak);
+ peak = 0.0;
+
+ emit positionUpdate(pos);
+ peak = 0.0;
+}
diff --git a/dgedit/player.h b/dgedit/player.h
new file mode 100644
index 0000000..af278f5
--- /dev/null
+++ b/dgedit/player.h
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * player.h
+ *
+ * Tue Apr 15 10:34:18 CEST 2014
+ * Copyright 2014 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#ifndef __DRUMGIZMO_PLAYER_H__
+#define __DRUMGIZMO_PLAYER_H__
+
+#include <QThread>
+#include <QTimer>
+
+#include <ao/ao.h>
+
+#include "canvas.h"
+
+class Player : public QThread {
+Q_OBJECT
+public:
+ Player(Canvas *canvas); // TODO: Don't use canvas pointer here. Instead introduce setData slot or similar.
+ ~Player();
+
+ void run();
+
+ // TODO: Make these private.
+ // These two need to be public in order for the ugly hack in
+ // CanvasToolListen::playRange to work...
+ volatile bool playing;
+ volatile size_t pos;
+
+public slots:
+ /**
+ * Set gain scalar.
+ * This value is multiplied with each sample before it is played.
+ */
+ void setGainScalar(double gain_scalar);
+
+ /**
+ * Set gain is dB.
+ * Convenience method for setGainScalar. It simple recalculates the dB value
+ * to a scalar and sets the gain scalar accordingly.
+ */
+ void setGainDB(double gain_db);
+
+signals:
+ void peakUpdate(double peak);
+ void positionUpdate(size_t position);
+
+private slots:
+ void reportTimeout();
+
+private:
+ ao_device *dev;
+ Canvas *canvas;
+
+ QTimer report_timer;
+
+ double gain_scalar;
+ double peak;
+};
+
+#endif/*__DRUMGIZMO_PLAYER_H__*/