diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2014-04-15 12:18:12 +0200 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2014-04-15 12:18:12 +0200 | 
| commit | 12b62ca84abab622889363b9b9f3215d52eb5167 (patch) | |
| tree | 3b649cec0efd1566355cf9628d3ef13b19bbc675 /dgedit | |
| parent | 0fcacc1c3329e905228ceb80903f69561a7db732 (diff) | |
Player interface changes. Player moved to MainWindow for easier component sharing.
Diffstat (limited to 'dgedit')
| -rw-r--r-- | dgedit/canvastoollisten.cc | 87 | ||||
| -rw-r--r-- | dgedit/canvastoollisten.h | 33 | ||||
| -rw-r--r-- | dgedit/mainwindow.cc | 10 | ||||
| -rw-r--r-- | dgedit/mainwindow.h | 3 | ||||
| -rw-r--r-- | dgedit/player.cc | 106 | ||||
| -rw-r--r-- | dgedit/player.h | 82 | 
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__*/ | 
