changeset 391:28a74940f2b6

More work on the editor.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 19 Oct 2012 04:30:24 +0300
parents a7ee3567f718
children fc9b476c46de
files edgui.cpp edmain.cpp edmain.h edview.cpp edview.h edwaveform.cpp edwaveform.h
diffstat 7 files changed, 362 insertions(+), 97 deletions(-) [+]
line wrap: on
line diff
--- a/edgui.cpp	Fri Oct 19 04:30:01 2012 +0300
+++ b/edgui.cpp	Fri Oct 19 04:30:24 2012 +0300
@@ -487,11 +487,16 @@
 
 
     timelineScrollBar = new QScrollBar(Qt::Horizontal);
-    timelineWaveform = new WaveformView();
-    demoView = new DemoView(this);
+    connect(timelineScrollBar, SIGNAL(valueChanged(int)), this, SLOT(actionTimelineScrollChanged(int)));
+    
+    timelineAudioTrack = new WaveTrackView();
+    connect(timelineAudioTrack, SIGNAL(offsetChanged(float)), this, SLOT(actionOffsetChanged(float)));
+    connect(timelineAudioTrack, SIGNAL(timeChanged(float)), this, SLOT(actionTimeChanged(float)));
+
+    demoView = new SWDemoView(this);
 
     verticalSplitter->addLayout(horizSplitter);
-    verticalSplitter->addWidget(timelineWaveform);
+    verticalSplitter->addWidget(timelineAudioTrack);
     verticalSplitter->addWidget(timelineScrollBar);
 
     horizSplitter->addWidget(sideVBoxContainer);
--- a/edmain.cpp	Fri Oct 19 04:30:01 2012 +0300
+++ b/edmain.cpp	Fri Oct 19 04:30:24 2012 +0300
@@ -246,11 +246,48 @@
 }
 
 
+// Return audio track duration in milliseconds
+int DemoEditor::getAudioTrackDuration()
+{
+    return timelineAudioTrack->getDuration();
+}
+
+
+int DemoEditor::getTimelineDuration()
+{
+    return getAudioTrackDuration();
+}
+
+
 void DemoEditor::updateTimelineView()
 {
-    timelineWaveform->setOffset(20000);
-    timelineWaveform->setScale(10);
-    timelineWaveform->setTime(200010);
+    timelineAudioTrack->setOffset(currViewOffset);
+    timelineAudioTrack->setScale(currViewScale);
+//    timelineAudioTrack->setTime(currFrameTime);
+
+    timelineScrollBar->setRange(0, getTimelineDuration() - timelineAudioTrack->getScaledWidth());
+    timelineScrollBar->setValue(currViewOffset);
+}
+
+
+void DemoEditor::actionTimelineScrollChanged(int value)
+{   
+    currViewOffset = value;
+    updateTimelineView();
+}
+
+
+void DemoEditor::actionOffsetChanged(float value)
+{   
+    currViewOffset = value;
+    updateTimelineView();
+}
+
+
+void DemoEditor::actionTimeChanged(float value)
+{   
+    currFrameTime = value;
+    updateTimelineView();
 }
 
 
@@ -258,6 +295,10 @@
 {
     int err;
 
+    currViewOffset = 0;
+    currFrameTime = 0;
+    currViewScale = 1.0f;
+    
     // Initialize resource subsystem
     statusMsg("Initializing resources subsystem.");
     if ((err = reopenResources()) != DMERR_OK)
@@ -291,7 +332,8 @@
     }
 
     // Etc.
-    timelineWaveform->setWaveform(
+    demoView->setEngineData(&engine);    
+    timelineAudioTrack->setWaveform(
         engine.audioRes->rdata, engine.audioRes->rdataSize,
         engine.optAfmt.format, engine.optAfmt.channels,
         engine.optAfmt.freq);
--- a/edmain.h	Fri Oct 19 04:30:01 2012 +0300
+++ b/edmain.h	Fri Oct 19 04:30:24 2012 +0300
@@ -63,6 +63,9 @@
     void performRedo();
 
     void actionControlChanged(QAction *);
+    void actionTimelineScrollChanged(int);
+    void actionOffsetChanged(float);
+    void actionTimeChanged(float);
 
 private:
     QTableView *effectTable;
@@ -70,8 +73,8 @@
 //    QAction *menuActCut, *menuActCopy, *menuActPaste, *menuActDelete;
     QActionGroup *actGroupControls;
     QScrollBar *timelineScrollBar;
-    WaveformView *timelineWaveform;
-    DemoView *demoView;
+    WaveTrackView *timelineAudioTrack;
+    GLDemoView *demoView;
     
     
 
@@ -94,7 +97,9 @@
     int reopenResources();
     int loadResources();
     bool initializeVideo();
-    
+
+    int getAudioTrackDuration();
+    int getTimelineDuration();    
 
     void createNewFile();
     void readFromFile(QString filename);
@@ -102,6 +107,10 @@
 
 
     bool changed, initSDL;
+    float currViewScale;
+    int currViewOffset;
+    int currFrameTime;
+
     TimelineObject *tl;
     DMEngineData engine;
 
--- a/edview.cpp	Fri Oct 19 04:30:01 2012 +0300
+++ b/edview.cpp	Fri Oct 19 04:30:24 2012 +0300
@@ -1,8 +1,9 @@
 #include "edview.h"
+#include <QtGui>
 
 
-DemoView::DemoView(QWidget *parent)
-    : QGLWidget(QGLFormat(QGL::SampleBuffers|QGL::AlphaChannel), parent)
+GLDemoView::GLDemoView(QWidget *parent) :
+    QGLWidget(QGLFormat(QGL::SampleBuffers|QGL::AlphaChannel), parent)
 {
     makeCurrent();
 
@@ -12,34 +13,50 @@
         format.setSamples(4);
         format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
 
-        render_fbo = new QGLFramebufferObject(512, 512, format);
-        texture_fbo = new QGLFramebufferObject(512, 512);
+//        render_fbo = new QGLFramebufferObject(512, 512, format);
+//        texture_fbo = new QGLFramebufferObject(512, 512);
     }
     else
     {
-        render_fbo = new QGLFramebufferObject(1024, 1024);
-        texture_fbo = render_fbo;
+//        render_fbo = new QGLFramebufferObject(1024, 1024);
+//        texture_fbo = render_fbo;
     }
 }
 
-DemoView::~DemoView()
+
+GLDemoView::~GLDemoView()
 {
-    delete texture_fbo;
-    if (render_fbo != texture_fbo)
-        delete render_fbo;
+}
+
+
+void GLDemoView::setEngineData(DMEngineData *mengine)
+{
+    engine = mengine;
 }
 
 
-void DemoView::paintEvent(QPaintEvent *)
+void GLDemoView::render(int frameTime)
 {
-    draw();
+    if (engine != NULL)
+    {
+        engine->frameTime = frameTime;
+
+        if (engine->demoRender != NULL)
+        {
+            engine->demoRender(engine);
+        }
+        else
+        {
+            dmExecuteTimeline(engine->ptl, engine->screen, engineGetTick(engine));
+        }
+        
+        engine->frameCount++;
+    }
 }
 
 
-void DemoView::draw()
+void GLDemoView::paintEvent(QPaintEvent *)
 {
-    QPainter p(this); // used for text overlay
-
     // save the GL state set for QPainter
     saveGLState();
 
@@ -48,7 +65,7 @@
 }
 
 
-void DemoView::saveGLState()
+void GLDemoView::saveGLState()
 {
     glPushAttrib(GL_ALL_ATTRIB_BITS);
     glMatrixMode(GL_PROJECTION);
@@ -58,7 +75,7 @@
 }
 
 
-void DemoView::restoreGLState()
+void GLDemoView::restoreGLState()
 {
     glMatrixMode(GL_PROJECTION);
     glPopMatrix();
@@ -66,3 +83,52 @@
     glPopMatrix();
     glPopAttrib();
 }
+
+
+SWDemoView::SWDemoView(QWidget *parent) : GLDemoView(parent)
+{
+    img = NULL;
+}
+
+
+SWDemoView::~SWDemoView()
+{
+    delete img;
+}
+
+
+void SWDemoView::setEngineData(DMEngineData *mengine)
+{
+    engine = mengine;
+    delete img;
+
+    img = new QImage((const uchar *)mengine->screen->pixels,
+        mengine->screen->w, mengine->screen->h,
+        mengine->screen->pitch, QImage::Format_RGB32);
+}
+
+
+void SWDemoView::paintEvent(QPaintEvent *)
+{
+    if (img != NULL)
+    {
+        QPainter painter(this);
+        painter.drawImage(QPoint(0, 0), *img);
+    }
+}
+
+
+void SWDemoView::render(int frameTime)
+{
+    if (SDL_MUSTLOCK(engine->screen) != 0 && SDL_LockSurface(engine->screen) != 0)
+        return;
+
+    GLDemoView::render(frameTime);
+
+    if (SDL_MUSTLOCK(engine->screen) != 0)
+        SDL_UnlockSurface(engine->screen);
+
+    update();
+}
+
+
--- a/edview.h	Fri Oct 19 04:30:01 2012 +0300
+++ b/edview.h	Fri Oct 19 04:30:24 2012 +0300
@@ -2,26 +2,46 @@
 #define EDVIEW_H
 
 #include <QtOpenGL>
+#include <QImage>
+#include "dmengine.h"
 
-class DemoView : public QGLWidget
+
+class GLDemoView : public QGLWidget
 {
     Q_OBJECT
 
 public:
-    DemoView(QWidget *parent);
-    ~DemoView();
+    GLDemoView(QWidget *parent);
+    ~GLDemoView();
 
+    virtual void setEngineData(DMEngineData *mengine);
+    virtual void render(int frameTime);
+    void paintEvent(QPaintEvent *);
+
+private:
     void saveGLState();
     void restoreGLState();
 
-    void paintEvent(QPaintEvent *);
+protected:
+    DMEngineData *engine;
+};
+
 
-public slots:
-    void draw();
+class SWDemoView : public GLDemoView
+{
+    Q_OBJECT
+
+public:
+    SWDemoView(QWidget *parent);
+    ~SWDemoView();
+
+    void setEngineData(DMEngineData *mengine);
+    void render(int frameTime);
+    void paintEvent(QPaintEvent *);
 
 private:
-    QGLFramebufferObject *render_fbo;
-    QGLFramebufferObject *texture_fbo;
+    QImage *img;
 };
 
+
 #endif
--- 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();
+}
--- a/edwaveform.h	Fri Oct 19 04:30:01 2012 +0300
+++ b/edwaveform.h	Fri Oct 19 04:30:24 2012 +0300
@@ -5,19 +5,22 @@
 #include <QLabel>
 #include "dmengine.h"
 
-class WaveDisplay : public QWidget
+class WaveTrackDisplay : public QWidget
 {
     Q_OBJECT
 
 public:
-    WaveDisplay(QWidget *parent = 0);
+    WaveTrackDisplay(QWidget *parent = 0);
 
-    void setWaveform(void *mdata, int mlen, int mformat, int mchannels, int mfreq);
-    void setTime(const int mtime);
-    void setOffset(const int moffs);
+    void setWaveform(void *mdata, int msize, int mformat, int mchannels, int mfreq);
+    float getScaledWidth();
     void setScale(const float mscale);
-    int getTime();
-    int getOffset();
+    int getBps();
+    float getDuration();
+    float getTimeScale(float value);
+    float getTimeFromCoord(float value);
+    float getTime();
+    float getOffset();
 
     QSize minimumSizeHint() const
     {
@@ -29,6 +32,14 @@
         return QSize(600, 60);
     }
 
+public slots:
+    void setTime(const float mtime);
+    void setOffset(const float moffs);
+
+signals:
+    void timeChanged(float value);
+    void offsetChanged(float value);
+
 protected:
     void mousePressEvent(QMouseEvent *event);
     void mouseMoveEvent(QMouseEvent *event);
@@ -37,29 +48,46 @@
     void paintEvent(QPaintEvent *event);
 
 private:
+    bool dragging;
+    QPoint dragPoint;
+    float dragOffs; // milliseconds
+
     float scale;
-    int time, offs, len, channels, format, freq;
+    float time, offs, duration; // in milliseconds
+
+    int size, channels, format, freq;
     void *data;
 };
 
 
-class WaveformView : public QWidget
+class WaveTrackView : public QWidget
 {
     Q_OBJECT
 
 private:
-    WaveDisplay *wave;
+    WaveTrackDisplay *wave;
     QLabel *infoName, *infoData;
 
 public:
-    WaveformView(QWidget *parent = 0);
+
+    WaveTrackView(QWidget *parent = 0);
     void setWaveform(void *mdata, int mlen, int mformat, int mchannels, int mfreq);
     void setName(QString name);
-    void setTime(const int mtime);
-    void setOffset(const int moffs);
+    void setTime(const float mtime);
+    void setOffset(const float moffs);
+    float getScaledWidth();
     void setScale(const float mscale);
-    int getTime();
-    int getOffset();
+    float getDuration();
+    float getTime();
+    float getOffset();
+
+private slots:
+    void slotTimeChanged(float value);
+    void slotOffsetChanged(float value);
+
+signals:
+    void timeChanged(float value);
+    void offsetChanged(float value);
 };
 
 #endif