diff options
| -rw-r--r-- | dgedit/canvastoollisten.cc | 29 | ||||
| -rw-r--r-- | dgedit/canvastoollisten.h | 1 | ||||
| -rw-r--r-- | dgedit/mainwindow.cc | 28 | ||||
| -rw-r--r-- | dgedit/mainwindow.h | 2 | ||||
| -rw-r--r-- | dgedit/player.cc | 104 | ||||
| -rw-r--r-- | dgedit/player.h | 27 | ||||
| -rw-r--r-- | dgedit/selection.h | 8 | 
7 files changed, 133 insertions, 66 deletions
| diff --git a/dgedit/canvastoollisten.cc b/dgedit/canvastoollisten.cc index bd16b15..847c32d 100644 --- a/dgedit/canvastoollisten.cc +++ b/dgedit/canvastoollisten.cc @@ -39,7 +39,6 @@ bool CanvasToolListen::mousePressEvent(QMouseEvent *event)  {    if(!isActive()) return false;    player.setPosition(canvas->unmapX(event->x())); -  player.playing = true;    canvas->update();    connect(&player, SIGNAL(positionUpdate(size_t)), this, SLOT(update(size_t)));    return true; @@ -48,7 +47,7 @@ bool CanvasToolListen::mousePressEvent(QMouseEvent *event)  bool CanvasToolListen::mouseReleaseEvent(QMouseEvent *event)  {    if(!isActive()) return false; -  player.playing = false; +  player.stop();    disconnect(&player, SIGNAL(positionUpdate(size_t)),               this, SLOT(update(size_t)));    lastpos = 0; @@ -60,7 +59,7 @@ void CanvasToolListen::paintEvent(QPaintEvent *event, QPainter &painter)  {    if(!isActive()) return; -  if(player.playing) { +  if(player.pos < player.end) {      painter.setPen(QColor(0, 127, 127));      painter.drawLine(canvas->mapX(pos),                       event->rect().y(), @@ -80,27 +79,3 @@ void CanvasToolListen::update(size_t pos)    canvas->update(r);    lastpos = pos;  } - -void CanvasToolListen::setVolume(int 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(); -  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 810e7cb..bfb2d41 100644 --- a/dgedit/canvastoollisten.h +++ b/dgedit/canvastoollisten.h @@ -48,7 +48,6 @@ public:  public slots:    void update(size_t position); -  void setVolume(int v);  private:    Canvas *canvas; diff --git a/dgedit/mainwindow.cc b/dgedit/mainwindow.cc index d573ff4..9f877bf 100644 --- a/dgedit/mainwindow.cc +++ b/dgedit/mainwindow.cc @@ -42,12 +42,12 @@  #include <QIntValidator>  #include <QTabWidget>  #include <QProgressBar> +#include <QTime> -#include <unistd.h> +//#include <unistd.h>  #include "canvastool.h"  #include "canvastoolthreshold.h" -#include "canvastoollisten.h"  #include "volumefader.h"  #include "selectioneditor.h" @@ -65,7 +65,6 @@ static void addTool(QToolBar *toolbar, Canvas *canvas, CanvasTool *tool)    canvas->tools.push_back(tool);  } -static CanvasToolListen *g_listen;  MainWindow::MainWindow()  {    { @@ -84,8 +83,7 @@ MainWindow::MainWindow()    canvas = new Canvas(this);    QToolBar *toolbar = addToolBar("Tools"); -  g_listen = new CanvasToolListen(canvas, player); -  CanvasTool *listen = g_listen; +  listen = new CanvasToolListen(canvas, player);    addTool(toolbar, canvas, listen);    threshold = new CanvasToolThreshold(canvas);    canvas->tools.push_back(threshold);//addTool(toolbar, canvas, threshold); @@ -426,8 +424,6 @@ void MainWindow::setVolumeLineEd(int value)  void MainWindow::playSamples()  { -  //unsigned int length = 44100 / 4; // 0.25 seconds in 44k1Hz -    QVector<sel_id_t> ids = selections.ids();    for(int v1 = 0; v1 < ids.size(); v1++) {      for(int v2 = 0; v2 < ids.size(); v2++) { @@ -452,15 +448,25 @@ void MainWindow::playSamples()      unsigned int sample_length = sel.to - sel.from;      unsigned int to = sel.to; -    unsigned int sleep = 0;      if(sample_length > length) to = sel.from + length; -    else sleep = length - sample_length;      selections.setActive(*i); -    g_listen->playRange(sel.from, to); -    usleep(1000000 * sleep / 44100); +    connect(&player, SIGNAL(positionUpdate(size_t)), +            listen, SLOT(update(size_t))); + +    player.playSelection(sel, to - sel.from); +    QTime t; +    t.start(); +    while(t.elapsed() < sb_playsamples->value()) { +      qApp->processEvents(); +      usleep(25 * 1000); +    } +    player.stop(); + +    disconnect(&player, SIGNAL(positionUpdate(size_t)), +               listen, SLOT(update(size_t)));      i++;    }  } diff --git a/dgedit/mainwindow.h b/dgedit/mainwindow.h index 620c116..6fef5db 100644 --- a/dgedit/mainwindow.h +++ b/dgedit/mainwindow.h @@ -40,6 +40,7 @@  #include "filelist.h"  #include "canvastoolselections.h"  #include "canvastoolthreshold.h" +#include "canvastoollisten.h"  #include "selection.h"  #include "player.h" @@ -88,6 +89,7 @@ private:    Canvas *canvas;    CanvasToolSelections *tool_selections;    CanvasToolThreshold *threshold; +  CanvasToolListen *listen;    AudioExtractor *extractor;    FileList *filelist;    QScrollBar *yoffset; diff --git a/dgedit/player.cc b/dgedit/player.cc index baaf975..745052e 100644 --- a/dgedit/player.cc +++ b/dgedit/player.cc @@ -28,17 +28,17 @@  #include <math.h> -#define BUFSZ 1024 * 2 +#define BUFSZ 512  Player::Player()  { -  playing = false; -    peak = 0;    pos = 0;    gain_scalar = 1.0;    pcm_data = NULL;    pcm_size = 0; +  end = 0; +  new_selection = false;    connect(&report_timer, SIGNAL(timeout()), this, SLOT(reportTimeout()));    report_timer.start(50); // Update 25 times per second @@ -52,8 +52,11 @@ Player::~Player()    wait(); // Wait for player thread to stop.  } +#define _MIN(a, b) (a<b?a:b)  void Player::run()  { +  Selection sel; +    ao_initialize();    ao_sample_format sf; @@ -69,31 +72,75 @@ void Player::run()    short s[BUFSZ];    while(running) { -    if(playing) { -      for(size_t i = 0; i < BUFSZ; i++) { -        double sample = 0.0; -        if(i + pos < pcm_size) { -          sample = pcm_data[pos + i] * gain_scalar; -        } else { -          playing = false; -        } -        if(abs(sample) > peak) peak = abs(sample); -        s[i] = sample * SHRT_MAX; + +    { // Check for new Selection. +      QMutexLocker lock(&mutex); +      if(new_selection) { +        sel = selection; +        pos = sel.from; +        end = sel_end; +        new_selection = false;        } +    } -      ao_play(dev, (char*)s, BUFSZ * sizeof(short)); +    for(size_t i = 0; i < BUFSZ; i++) { +      double sample = 0.0; +      size_t p = i + pos; +      if(p < sel.to && p < end && p < pcm_size) { +        double fade = 1; +        if(p < (sel.from + sel.fadein)) { +          // Apply linear fade-in +          double fp = p - sel.from; +          fade = fp / (double)sel.fadeout; +        } -      pos += BUFSZ; +        if(p > (sel.to - sel.fadeout)) { +          // Apply linear fade-out +          double fp = (double)(((int)sel.to - (int)sel.fadeout) - (int)p); +          fade = 1 + (fp / (double)sel.fadeout); +        } -    } else { -      msleep(22); +        sample = pcm_data[p] * fade * gain_scalar; +      } +      if(abs(sample) > peak) peak = abs(sample); +      s[i] = _MIN(sample * SHRT_MAX, SHRT_MAX);      } +     +    ao_play(dev, (char*)s, BUFSZ * sizeof(short)); + +    pos += BUFSZ;    }    ao_close(dev);    ao_shutdown();  } +bool Player::playSelectionDone() +{ +  return pos >= sel_end || pos >= selection.to; +} + +void Player::playSelection(Selection s, int len) +{ +  { // Enqueue new Selection for player consumation +    QMutexLocker lock(&mutex); + +    selection = s; + +    if(len > 0) sel_end = len; +    else sel_end = selection.to - selection.from; +     +    sel_end += selection.from; + +    new_selection = true; +  } + +  // Wait until player actually consumed the new Selection. +  while(new_selection) { +    msleep(1); +  } +} +  void Player::setGainScalar(double g)  {    gain_scalar = g; @@ -120,7 +167,22 @@ void Player::setPcmData(float *data, size_t size)    pcm_size = size;  } - void Player::setPosition(size_t position) - { -   pos = position; - } +void Player::setPosition(size_t position) +{ +  Selection s; +  s.from = position; +  s.to = pcm_size; +  s.fadein = 0; +  s.fadeout = 0; +  playSelection(s); +} + +void Player::stop() +{ +  Selection s; +  s.from = 0; +  s.to = 0; +  s.fadein = 0; +  s.fadeout = 0; +  playSelection(s, pos); +} diff --git a/dgedit/player.h b/dgedit/player.h index 2977103..60b2ccb 100644 --- a/dgedit/player.h +++ b/dgedit/player.h @@ -29,10 +29,11 @@  #include <QThread>  #include <QTimer> +#include <QMutex>  #include <ao/ao.h> -#include "canvas.h" +#include "selection.h"  class Player : public QThread {  Q_OBJECT @@ -45,8 +46,9 @@ public:    // 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 bool playing;    volatile size_t pos; +  volatile size_t end;  public slots:    /** @@ -72,6 +74,22 @@ public slots:     */    void setPosition(size_t position); +  /** +   * Play range based on selection including fade-in/out. +   * @param length Stop playing after length samples. -1 means play all. +   */ +  void playSelection(Selection selection, int length = -1); + +  /** +   * Return true if last selection is done playing. +   */ +  bool playSelectionDone(); + +  /** +   * Stop playing +   */ +  void stop(); +  signals:    /**     * The absolute maximum of samples seen since last update. @@ -103,6 +121,11 @@ private:    double peak;    bool running; + +  QMutex mutex; +  volatile bool new_selection; +  size_t sel_end; +  Selection selection;  };  #endif/*__DRUMGIZMO_PLAYER_H__*/ diff --git a/dgedit/selection.h b/dgedit/selection.h index 08b897b..c6c7ecc 100644 --- a/dgedit/selection.h +++ b/dgedit/selection.h @@ -40,10 +40,10 @@ public:      this->fadein = fadein;      this->fadeout = fadeout;    } -  int from; -  int to; -  int fadein; -  int fadeout; +  size_t from; +  size_t to; +  size_t fadein; +  size_t fadeout;    double energy; | 
