diff edwaveform.cpp @ 391:28a74940f2b6

More work on the editor.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 19 Oct 2012 04:30:24 +0300
parents e5220ff48bc8
children 5137db55f00b
line wrap: on
line diff
--- a/edwaveform.cpp	Fri Oct 19 04:30:01 2012 +0300
+++ b/edwaveform.cpp	Fri Oct 19 04:30:24 2012 +0300
@@ -3,46 +3,99 @@
 #include "edwaveform.h"
 
 
-WaveDisplay::WaveDisplay(QWidget *parent) : QWidget(parent)
+WaveTrackDisplay::WaveTrackDisplay(QWidget *parent) : QWidget(parent)
 {
     data      = NULL;
-    len       = 0;
+    size      = 0;
     format    = AUDIO_S16SYS;
     channels  = 1;
     freq      = 1;
     scale     = 1.0f;
     time      = offs = 0;
+    duration  = 0;
 
     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
 }
 
 
-void WaveDisplay::setWaveform(void *mdata, int mlen, int mformat, int mchannels, int mfreq)
+void WaveTrackDisplay::setWaveform(void *mdata, int msize, int mformat, int mchannels, int mfreq)
 {
     data     = mdata;
-    len      = mlen;
+    size     = msize;
     format   = mformat;
     channels = mchannels;
     freq     = mfreq;
+
+    int bps = getBps();
+    if (bps != 0)
+        duration = ((float) (size / bps) / (float) freq) * 1000.0f;
+    else
+        duration = 0;
+
     update();
 }
 
 
-void WaveDisplay::setTime(const int mtime)
+int WaveTrackDisplay::getBps()
 {
-    time = mtime;
-    update();
+    int bps = channels;
+    switch (format)
+    {
+        case AUDIO_S16SYS:
+        case AUDIO_U16SYS:
+            bps *= sizeof(quint16);
+            break;
+        case AUDIO_S8:
+        case AUDIO_U8:
+            bps *= sizeof(quint8);
+            break;
+    }
+    return bps;
+}
+
+
+float WaveTrackDisplay::getDuration()
+{
+    return duration;
+}
+
+
+float WaveTrackDisplay::getTimeScale(float value)
+{
+    return (value * scale * (float) freq) / 1000.0f;
 }
 
 
-void WaveDisplay::setOffset(const int moffs)
+float WaveTrackDisplay::getTimeFromCoord(float value)
 {
-    offs = moffs;
-    update();
+    return value * scale;
 }
 
 
-void WaveDisplay::setScale(const float mscale)
+void WaveTrackDisplay::setTime(const float mtime)
+{
+    fprintf(stderr, "setTime(%1.5f)\n", mtime);
+    if (time != mtime && mtime >= 0 && mtime < duration)
+    {
+        time = mtime;
+        update();
+        emit timeChanged(time);
+    }
+}
+
+
+void WaveTrackDisplay::setOffset(const float moffs)
+{
+    if (offs != moffs && moffs >= 0 && moffs < getDuration())
+    {
+        offs = moffs;
+        update();
+        emit offsetChanged(offs);
+    }
+}
+
+
+void WaveTrackDisplay::setScale(const float mscale)
 {
     if (mscale > 0.05)
         scale = mscale;
@@ -50,23 +103,29 @@
 }
 
 
-int WaveDisplay::getTime()
+float WaveTrackDisplay::getScaledWidth()
+{
+    return getTimeScale(width());
+}
+
+
+float WaveTrackDisplay::getTime()
 {
     return time;
 }
 
 
-int WaveDisplay::getOffset()
+float WaveTrackDisplay::getOffset()
 {
     return offs;
 }
 
 
-void WaveDisplay::paintEvent(QPaintEvent *)
+void WaveTrackDisplay::paintEvent(QPaintEvent *)
 {
     QColor waveColor(0, 150, 0);
     QColor waveCenterLine(0, 0, 0);
-    QColor markerColor(0,0,0);
+    QColor markerColor(255,255,255);
     QColor bgColor(0, 0, 0);//255, 255, 255);
 
     QPainter painter(this);
@@ -102,16 +161,17 @@
                 break;
         }
 
-        painter.scale(1.0f, 0.7f);
+        painter.scale(1.0f, 0.5f);
         painter.setPen(waveColor);
 
+        float mscale = (scale * (float)freq) / 1000.0f;
         int prevY = 0, prevX = 0;
         if (format == AUDIO_S16SYS || format == AUDIO_U16SYS)
         {
             qint16 *buf = (qint16 *) data;
             for (int xc = 0; xc < width(); xc++)
             {
-                int value = buf[(int) (((offs + xc) * scale)) * channels] + voffs;
+                int value = buf[(int) (((offs + xc) * mscale)) * channels] + voffs;
                 painter.drawLine(prevX, prevY, xc, value);
                 prevY = value;
                 prevX = xc;
@@ -123,7 +183,7 @@
             qint8 *buf = (qint8 *) data;
             for (int xc = 0; xc < width(); xc++)
             {
-                int value = buf[((int) ((offs + xc) * scale)) * channels] + voffs;
+                int value = buf[((int) ((offs + xc) * mscale)) * channels] + voffs;
                 painter.drawLine(prevX, prevY, xc, value);
                 prevY = value;
                 prevX = xc;
@@ -133,54 +193,57 @@
         painter.restore();
     }
     
-    if (time >= offs * scale) // && time - offs <= width() * scale)
+    float xc = getTimeScale(time - offs), wd = getTimeScale(width());
+    if (xc >= 0 && xc <= wd)
     {
-        int xc = time - offs;
-        painter.scale(1.0f / scale, 1.0f);
+        xc = time - offs;
+        painter.scale(scale, 1.0f);
         painter.setPen(markerColor);
         painter.drawLine(xc, 0, xc, height());
     }
 }
 
 
-void WaveDisplay::mousePressEvent(QMouseEvent *ev)
+void WaveTrackDisplay::mousePressEvent(QMouseEvent *ev)
 {
-/*
     if (ev->button() == Qt::LeftButton)
     {
-        lastPoint = ev->pos();
-        scribbling = true;
+        dragPoint = ev->pos();
+        dragOffs = offs;
+        dragging = false;
     }
-*/
 }
 
 
-void WaveDisplay::mouseMoveEvent(QMouseEvent *ev)
+void WaveTrackDisplay::mouseMoveEvent(QMouseEvent *ev)
 {
-/*
-    if ((ev->buttons() & Qt::LeftButton) && scribbling)
-        drawLineTo(ev->pos());
-*/
+    if ((ev->buttons() & Qt::LeftButton) && ev->pos().x() != dragPoint.x())
+    {
+        dragging = true;
+        setOffset(dragOffs - (ev->pos().x() - dragPoint.x()) / scale);
+    }
 }
 
 
-void WaveDisplay::mouseReleaseEvent(QMouseEvent *ev)
+void WaveTrackDisplay::mouseReleaseEvent(QMouseEvent *ev)
 {
-/*
-    if (ev->button() == Qt::LeftButton && scribbling)
+    if (ev->button() == Qt::LeftButton)
     {
-        drawLineTo(ev->pos());
-        scribbling = false;
+        dragging = false;
     }
-*/
+    else
+    if (ev->button() == Qt::RightButton && !dragging)
+    {
+        setTime(offs + getTimeFromCoord(ev->pos().x()));
+    }
 }
 
 
-WaveformView::WaveformView(QWidget *parent) : QWidget(parent)
+WaveTrackView::WaveTrackView(QWidget *parent) : QWidget(parent)
 {
     QHBoxLayout *mainLayout = new QHBoxLayout(this);
     mainLayout->setMargin(0);
-    wave = new WaveDisplay(this);
+    wave = new WaveTrackDisplay(this);
 
     QFrame *infoLayoutContainer = new QFrame(this);
     infoLayoutContainer->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
@@ -202,10 +265,13 @@
     mainLayout->addWidget(infoLayoutContainer);
 //    mainLayout->addLayout(infoLayout);
     mainLayout->addWidget(wave);
+
+    connect(wave, SIGNAL(timeChanged(float)), this, SLOT(slotTimeChanged(float)));
+    connect(wave, SIGNAL(offsetChanged(float)), this, SLOT(slotOffsetChanged(float)));
 }
 
 
-void WaveformView::setWaveform(void *mdata, int mlen, int mformat, int mchannels, int mfreq)
+void WaveTrackView::setWaveform(void *mdata, int msize, int mformat, int mchannels, int mfreq)
 {
     QString fmt;
     switch (mformat)
@@ -217,38 +283,67 @@
         default:           fmt = "?"; break;
     }
     infoData->setText(QString("<b>%1</b>, <b>%2</b> ch, <b>%3</b> Hz").arg(fmt).arg(mchannels).arg(mfreq));
-    wave->setWaveform(mdata, mlen, mformat, mchannels, mfreq);
+    wave->setWaveform(mdata, msize, mformat, mchannels, mfreq);
     update();
 }
 
 
-void WaveformView::setName(QString name)
+void WaveTrackView::setName(QString name)
 {
     infoName->setText(name);
     update();
 }
 
-void WaveformView::setTime(const int mtime)
+
+void WaveTrackView::setTime(const float mtime)
 {
     wave->setTime(mtime);
 }
 
-void WaveformView::setOffset(const int moffs)
+
+void WaveTrackView::setOffset(const float moffs)
 {
     wave->setOffset(moffs);
 }
 
-void WaveformView::setScale(const float mscale)
+
+void WaveTrackView::setScale(const float mscale)
 {
     wave->setScale(mscale);
 }
 
-int WaveformView::getTime()
+
+float WaveTrackView::getTime()
 {
     return wave->getTime();
 }
 
-int WaveformView::getOffset()
+
+float WaveTrackView::getOffset()
 {
     return wave->getOffset();
 }
+
+
+float WaveTrackView::getScaledWidth()
+{
+    return wave->getScaledWidth();
+}
+
+
+void WaveTrackView::slotTimeChanged(float value)
+{
+    emit timeChanged(value);
+}
+
+
+void WaveTrackView::slotOffsetChanged(float value)
+{
+    emit offsetChanged(value);
+}
+
+
+float WaveTrackView::getDuration()
+{
+    return wave->getDuration();
+}