~ubuntu-branches/ubuntu/feisty/muse/feisty

« back to all changes in this revision

Viewing changes to waveedit/waveview.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2002-04-23 17:28:23 UTC
  • Revision ID: james.westby@ubuntu.com-20020423172823-w8yplzr81a759xa3
Tags: upstream-0.5.2
ImportĀ upstreamĀ versionĀ 0.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//=========================================================
 
2
//  MusE
 
3
//  Linux Music Editor
 
4
//    $Id: waveview.cpp,v 1.1 2002/01/30 14:10:09 muse Exp $
 
5
//  (C) Copyright 2000 Werner Schweer (ws@seh.de)
 
6
//=========================================================
 
7
 
 
8
#include <stdio.h>
 
9
#include <values.h>
 
10
 
 
11
#include <qpainter.h>
 
12
#include "../wave.h"
 
13
#include "waveview.h"
 
14
#include "song.h"
 
15
#include "event.h"
 
16
#include "../sf/sndfile.h"
 
17
#include "../midieditor.h"
 
18
 
 
19
//---------------------------------------------------------
 
20
//   WaveView
 
21
//---------------------------------------------------------
 
22
 
 
23
WaveView::WaveView(MidiEditor* pr, QWidget* parent, int xscale, int yscale)
 
24
   : View(parent, xscale, 1)
 
25
      {
 
26
      editor = pr;
 
27
      setVirt(true);
 
28
      pos[0] = int(tempomap.tick2time(song->cpos()) * sampleRate);
 
29
      pos[1] = int(tempomap.tick2time(song->lpos()) * sampleRate);
 
30
      pos[2] = int(tempomap.tick2time(song->rpos()) * sampleRate);
 
31
      yScale = yscale;
 
32
 
 
33
      setMouseTracking(true);
 
34
      setBg(white);
 
35
 
 
36
      if (editor->parts()->empty()) {
 
37
            curPart = 0;
 
38
            }
 
39
      else {
 
40
            curPart   = (WavePart*)(editor->parts()->begin()->second);
 
41
            curPartId = curPart->sn();
 
42
            }
 
43
      connect(song, SIGNAL(posChanged(int,int,bool)), SLOT(setPos(int,int,bool)));
 
44
      }
 
45
 
 
46
//---------------------------------------------------------
 
47
//   setYScale
 
48
//---------------------------------------------------------
 
49
 
 
50
void WaveView::setYScale(int val)
 
51
      {
 
52
      yScale = val;
 
53
      redraw();
 
54
      }
 
55
 
 
56
//---------------------------------------------------------
 
57
//   draw
 
58
//---------------------------------------------------------
 
59
 
 
60
void WaveView::pdraw(QPainter& p, const QRect& rr)
 
61
      {
 
62
      int x1 = rr.x();
 
63
      int x2 = rr.right() + 1;
 
64
      if (x1 < 0)
 
65
            x1 = 0;
 
66
      if (x2 > width())
 
67
            x2 = width();
 
68
      int hh = height();
 
69
      int h  = hh/2;
 
70
      int y  = rr.y() + h;
 
71
 
 
72
      for (iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip) {
 
73
            WavePart* wp = (WavePart*)(ip->second);
 
74
            EventList* el = wp->events();
 
75
            for (iEvent e = el->begin(); e != el->end(); ++e) {
 
76
                  WaveEvent* event  = (WaveEvent*)e->second;
 
77
// printf("draw part %p event %p\n", curPart, event);
 
78
                  Clip* clip        = event->clip();
 
79
                  if (!clip)
 
80
                        continue;
 
81
                  const SndFile* f  = clip->file();
 
82
                  if (!f)
 
83
                        continue;
 
84
                  int xScale = xmag;
 
85
                  if (xScale < 0)
 
86
                        xScale = -xScale;
 
87
 
 
88
                  int sx  = (event->posSample() + xScale/2 - startSample) / xScale;
 
89
                  int ex  = (event->posSample() + event->lenSample() + xScale/2 - startSample) / xScale;
 
90
// printf("----%d-%d  xpos %d  %d-%d\n", sx,ex, xpos, x1,x2);
 
91
 
 
92
                  sx -= xpos;
 
93
                  ex -= xpos;
 
94
                  if (sx < x1)
 
95
                        sx = x1;
 
96
                  if (ex > x2)
 
97
                        ex = x2;
 
98
 
 
99
                  int pos = (xpos + sx) * xScale + clip->spos() - event->posSample();
 
100
                  h      = hh / (f->channels() * 2);
 
101
                  int cc = hh % (f->channels() * 2) ? 0 : 1;
 
102
 
 
103
// printf("draw %d-%d  pos %d  Event: pos %d len:%d, clip pos %d\n",
 
104
//         sx, ex, event->posSample(), pos, event->lenSample(), clip->spos());
 
105
 
 
106
                  for (int i = sx; i < ex; i++) {
 
107
                        y  = rr.y() + h;
 
108
                        SampleV sa[f->channels()];
 
109
                        const_cast<SndFile*>(f)->read(sa, xScale, pos);
 
110
                        pos += xScale;
 
111
                        for (unsigned k = 0; k < f->channels(); ++k) {
 
112
                              int peak = (sa[k].peak * (h - 1)) / yScale;
 
113
                              int rms  = (sa[k].rms  * (h - 1)) / yScale;
 
114
                              if (peak > h)
 
115
                                    peak = h;
 
116
                              if (rms > h)
 
117
                                    rms = h;
 
118
                              p.setPen(QColor(darkGray));
 
119
                              p.drawLine(i, y - peak - cc, i, y + peak);
 
120
                              p.setPen(QColor(black));
 
121
                              p.drawLine(i, y - rms - cc, i, y + rms);
 
122
                              y  += 2 * h;
 
123
                              }
 
124
                        }
 
125
                  }
 
126
            }
 
127
      View::pdraw(p, rr);
 
128
      }
 
129
 
 
130
//---------------------------------------------------------
 
131
//   draw
 
132
//---------------------------------------------------------
 
133
 
 
134
void WaveView::draw(QPainter& p, const QRect& r)
 
135
      {
 
136
      int x = r.x();
 
137
      int y = r.y();
 
138
      int w = r.width();
 
139
      int h = r.height();
 
140
      if (x < 0)
 
141
            x = 0;
 
142
      if (y < 0)
 
143
            y = 0;
 
144
 
 
145
      int x2 = x + w;
 
146
      int y2 = y + h;
 
147
 
 
148
      int h2 = height()/2;
 
149
      int h4 = h2/2;
 
150
      int center1 = h4;
 
151
      int center2 = h2+h4;
 
152
      //
 
153
      //    draw marker & centerline
 
154
      //
 
155
      p.setPen(red);
 
156
      if (pos[0] >= x && pos[0] < x2) {
 
157
            p.drawLine(pos[0], y, pos[0], y2);
 
158
            }
 
159
      p.setPen(blue);
 
160
      if (pos[1] >= x && pos[1] < x2) {
 
161
            p.drawLine(pos[1], y, pos[1], y2);
 
162
            }
 
163
      if (pos[2] >= x && pos[2] < x2)
 
164
            p.drawLine(pos[2], y, pos[2], y2);
 
165
      p.setPen(QColor(blue));
 
166
      p.drawLine(x, center1, x2, center1);
 
167
      p.setPen(QColor(red));
 
168
      p.drawLine(x, center2, x2, center2);
 
169
      p.setPen(QColor(black));
 
170
      p.drawLine(x, h2, x2, h2);
 
171
      }
 
172
 
 
173
//---------------------------------------------------------
 
174
//   getCaption
 
175
//---------------------------------------------------------
 
176
 
 
177
QString WaveView::getCaption() const
 
178
      {
 
179
      return QString("Part ") + curPart->name();
 
180
      }
 
181
 
 
182
//---------------------------------------------------------
 
183
//   songChanged
 
184
//---------------------------------------------------------
 
185
 
 
186
void WaveView::songChanged(int flags)
 
187
      {
 
188
      if (flags & ~SC_SELECTION) {
 
189
            startSample  = MAXINT;
 
190
            endSample    = 0;
 
191
            curPart      = 0;
 
192
            for (iPart p = editor->parts()->begin(); p != editor->parts()->end(); ++p) {
 
193
                  WavePart* part = (WavePart*)(p->second);
 
194
                  if (part->sn() == curPartId)
 
195
                        curPart = part;
 
196
                  int ssample = part->posSample();
 
197
                  int esample = ssample + part->lenSample();
 
198
                  if (ssample < startSample)
 
199
                        startSample = ssample;
 
200
                  if (esample > endSample)
 
201
                        endSample = esample;
 
202
                  }
 
203
            }
 
204
      redraw();
 
205
      }
 
206
 
 
207
//---------------------------------------------------------
 
208
//   setPos
 
209
//    set one of three markers
 
210
//    idx   - 0-cpos  1-lpos  2-rpos
 
211
//    flag  - emit followEvent()
 
212
//---------------------------------------------------------
 
213
 
 
214
void WaveView::setPos(int idx, int val, bool adjustScrollbar)
 
215
      {
 
216
      val = int(tempomap.tick2time(val) * sampleRate);
 
217
      if (!isVisible()) {
 
218
            pos[idx] = val;
 
219
            return;
 
220
            }
 
221
      if (pos[idx] == val)
 
222
            return;
 
223
      int opos = mapx(pos[idx]);
 
224
      int npos = mapx(val);
 
225
 
 
226
      if (adjustScrollbar && idx == 0) {
 
227
            switch (song->follow()) {
 
228
                  case  Song::NO:
 
229
                        break;
 
230
                  case Song::JUMP:
 
231
                        if (npos >= width()) {
 
232
                              pos[0] = val;
 
233
                              emit followEvent(val);
 
234
                              return;
 
235
                              }
 
236
                        break;
 
237
                  case Song::CONTINUOUS:
 
238
                        {
 
239
                        int w2 = width()/2;
 
240
                        if (npos > w2) {
 
241
                              int ppos =  pos[0] - rmapxDev(w2);
 
242
                              if (ppos < 0)
 
243
                                    ppos = 0;
 
244
                              emit followEvent(ppos);
 
245
                              opos = mapx(pos[0]);
 
246
                              npos = mapx(val);
 
247
                              }
 
248
                        }
 
249
                        break;
 
250
                  }
 
251
            }
 
252
#if 0
 
253
      int x;
 
254
      int w = 1;
 
255
      if (opos > npos) {
 
256
            w += opos - npos;
 
257
            x = npos;
 
258
            }
 
259
      else {
 
260
            w += npos - opos;
 
261
            x = opos;
 
262
            }
 
263
#endif
 
264
      pos[idx] = val;
 
265
//      redraw(QRect(x, 0, w, height()));
 
266
      redraw(QRect(opos, 0, 1, height()));
 
267
      redraw(QRect(npos, 0, 1, height()));
 
268
      }
 
269
 
 
270
//---------------------------------------------------------
 
271
//   viewMousePressEvent
 
272
//---------------------------------------------------------
 
273
 
 
274
void WaveView::viewMousePressEvent(QMouseEvent* event)
 
275
      {
 
276
      button = event->button();
 
277
      viewMouseMoveEvent(event);
 
278
      }
 
279
 
 
280
void WaveView::viewMouseReleaseEvent(QMouseEvent*)
 
281
      {
 
282
      button = QMouseEvent::NoButton;
 
283
      }
 
284
 
 
285
//---------------------------------------------------------
 
286
//   viewMouseMoveEvent
 
287
//---------------------------------------------------------
 
288
 
 
289
void WaveView::viewMouseMoveEvent(QMouseEvent* event)
 
290
      {
 
291
      int x = event->x();
 
292
      int i;
 
293
      emit timeChanged(x);
 
294
 
 
295
      switch (button) {
 
296
            case QMouseEvent::LeftButton:
 
297
                  i = 0;
 
298
                  break;
 
299
            case QMouseEvent::MidButton:
 
300
                  i = 1;
 
301
                  break;
 
302
            case QMouseEvent::RightButton:
 
303
                  i = 2;
 
304
                  break;
 
305
            default:
 
306
                  return;
 
307
            }
 
308
      x = tempomap.time2tick(double(x) / double(sampleRate));
 
309
      song->setPos(i, x);
 
310
      }
 
311
 
 
312
//---------------------------------------------------------
 
313
//   range
 
314
//    returns range in samples
 
315
//---------------------------------------------------------
 
316
 
 
317
void WaveView::range(int* s, int *e)
 
318
      {
 
319
      *s = curPart->posSample();
 
320
      int etick = curPart->posTick() + curPart->lenTick();
 
321
      *e = tempomap.tick2samples(etick);
 
322
      }
 
323