From 7776aa97fc1c69a8f28ba4bab7387fb96be9a6e4 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Mon, 8 Sep 2014 20:48:38 +0200 Subject: Import dgedit from drumgizmo repository (split into its own project). --- src/canvas.cc | 285 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 src/canvas.cc (limited to 'src/canvas.cc') diff --git a/src/canvas.cc b/src/canvas.cc new file mode 100644 index 0000000..7007b0b --- /dev/null +++ b/src/canvas.cc @@ -0,0 +1,285 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * canvas.cc + * + * Tue Nov 10 08:37:37 CET 2009 + * Copyright 2009 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 "canvas.h" + +#include +#include +#include +#include +#include + +#include + +#define DEFYSCALE 200 + +Canvas::Canvas(QWidget *parent) + : QWidget(parent) +{ + setAttribute(Qt::WA_StaticContents); + setMouseTracking(true); + setFocusPolicy(Qt::ClickFocus); + + mipmap = NULL; + + data = NULL; + size = 0; + + xscale = 1.0; + yscale = 1.0; + xoffset = 0.0; + yoffset = 0.5; + + colBg = QColor(180, 200, 180); + colSec = QColor(160, 180, 160); + colWavMax = QColor(100, 100, 100); + colWavAvg = QColor(0, 0, 0); + colMax = QColor(127, 127, 255); + colHalf = QColor(180, 180, 255); + + setCursor(Qt::ArrowCursor); + + wav = QImage(width(), height(), QImage::Format_RGB32); +} + +Canvas::~Canvas() +{ + if(data) delete[] data; + if(mipmap) delete mipmap; +} + +void Canvas::load(QString file) +{ + if(data) { + delete[] data; + data = NULL; + size = 0; + } + + if(mipmap) { + delete mipmap; + mipmap = NULL; + } + + SF_INFO sf_info; + SNDFILE *fh = sf_open(file.toStdString().c_str(), SFM_READ, &sf_info); + if(!fh) { + printf("Load error...\n"); + return; + } + + size = sf_info.frames; + + printf("Size: %u\n", (unsigned int)sf_info.frames); + data = new float[size]; + + sf_read_float(fh, data, size); + + sf_close(fh); + + mipmap = new MipMap(data, size); + + updateWav(); + update(); +} + + +#define SCALEX ((xscale * (float)size/(float)width()) + 0.1) +#define OFFSETX (xoffset * (float)size) +float Canvas::mapX(float x) +{ + float val = (x - OFFSETX) / SCALEX; + return val; +} + +float Canvas::unmapX(float x) +{ + float val = x * SCALEX + OFFSETX; + return val; +} + +#define SCALEY (yscale * height()) +#define OFFSETY (((float)height() / 2.0) + ((yoffset * 2.0 - 1.0) * SCALEY)) +float Canvas::mapY(float y) +{ + float val = OFFSETY + (y * SCALEY); + return val; +} + +float Canvas::unmapY(float y) +{ + float val = (y - OFFSETY) / SCALEY; + return val; +} + +void Canvas::mouseMoveEvent(QMouseEvent *event) +{ + for(int i = 0; i < tools.size(); i++) { + if(tools[i]->mouseMoveEvent(event)) return; + } + + setCursor(Qt::ArrowCursor); +} + +void Canvas::mousePressEvent(QMouseEvent *event) +{ + for(int i = 0; i < tools.size(); i++) { + if(tools[i]->mousePressEvent(event)) return; + } +} + +void Canvas::mouseReleaseEvent(QMouseEvent *event) +{ + for(int i = 0; i < tools.size(); i++) { + if(tools[i]->mouseReleaseEvent(event)) return; + } +} + +void Canvas::resizeEvent(QResizeEvent *event) +{ + for(int i = 0; i < tools.size(); i++) { + tools[i]->resizeEvent(event); + } + + wav = QImage(width(), height(), QImage::Format_RGB32); + updateWav(); + update(); +} + +void Canvas::getWavValues(int last, int lx, float *vu, float *vl, + float *avgu, float *avgl) +{ + if(mipmap == NULL) return; + + MipMapValue val = mipmap->lookup(last, lx); + + *vu = val.max; + *vl = val.min; + *avgu = val.uavg; + *avgl = val.lavg; +} + +void Canvas::updateWav() +{ + QPainter painter(&wav); + + painter.setPen(colBg); + painter.setBrush(colBg); + painter.drawRect(0, 0, wav.width(), wav.height()); + + painter.setPen(colSec); + int step = 44100; + for(size_t i = 0; i < size; i += step) { + painter.drawLine(mapX(i), mapY(1.0), mapX(i), mapY(-1.0)); + } + + painter.setPen(colMax); + painter.drawLine(0, mapY(1.0), wav.width(), mapY(1.0)); + painter.drawLine(0, mapY(-1.0), wav.width(), mapY(-1.0)); + + painter.setPen(colHalf); + painter.drawLine(0, mapY(0.5), wav.width(), mapY(0.5)); + painter.drawLine(0, mapY(-0.5), wav.width(), mapY(-0.5)); + + if(data) { + int last = unmapX(0); + for(int x = 0; x < wav.width(); x++) { + int lx = unmapX(x); + if(lx > (int)size || lx < 0) break; + float vu = 0; + float vl = 0; + float avgu = 0; + float avgl = 0; + + getWavValues(last, lx, &vu, &vl, &avgu, &avgl); + + int c = mapY(0.0); + + painter.setPen(colWavMax); + painter.drawLine(x, c, x, mapY(vu)); + painter.drawLine(x, c, x, mapY(vl)); + + painter.setPen(colWavAvg); + painter.drawLine(x, c, x, mapY(avgu)); + painter.drawLine(x, c, x, mapY(avgl)); + + last = lx; + } + } +} + +void Canvas::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + + painter.drawImage(event->rect(),wav,event->rect()); + + for(int i = 0; i < tools.size(); i++) { + tools[i]->paintEvent(event, painter); + } +} + +void Canvas::keyReleaseEvent(QKeyEvent *event) +{ + for(int i = 0; i < tools.size(); i++) { + tools[i]->keyReleaseEvent(event); + } +} + +void Canvas::setXScale(float scale) +{ + scale = (pow(100.0,scale) / 100.0) - (pow(100.0, 0.0)/ 100.0); + if(scale < 0.0) scale = 0.0; + if(scale > 1.0) scale = 1.0; + xscale = scale; + updateWav(); + update(); +} + +void Canvas::setYScale(float scale) +{ + yscale = scale; + updateWav(); + update(); +} + +void Canvas::setXOffset(float offset) +{ + if(offset < 0.0) offset = 0.0; + if(offset > 1.0) offset = 1.0; + xoffset = offset; + updateWav(); + update(); +} + +void Canvas::setYOffset(float offset) +{ + if(offset < 0.0) offset = 0.0; + if(offset > 1.0) offset = 1.0; + yoffset = offset; + updateWav(); + update(); +} -- cgit v1.2.3