void WaveEdit::songChanged1(MusECore::SongChangedFlags_t bits) { if(_isDeleting) // Ignore while while deleting to prevent crash. return; if (bits & SC_SOLO) { MusECore::WavePart* part = (MusECore::WavePart*)(parts()->begin()->second); solo->blockSignals(true); solo->setChecked(part->track()->solo()); solo->blockSignals(false); } songChanged(bits); }
void WaveView::songChanged(MusECore::SongChangedFlags_t flags) { // Is it simply a midi controller value adjustment? Forget it. if(flags == SC_MIDI_CONTROLLER) return; if (flags & ~(SC_SELECTION | SC_PART_SELECTION | SC_TRACK_SELECTION)) { // TODO FIXME: don't we actually only want SC_PART_*, and maybe SC_TRACK_DELETED? // (same in ecanvas.cpp) startSample = INT_MAX; endSample = 0; curPart = 0; for (MusECore::iPart p = editor->parts()->begin(); p != editor->parts()->end(); ++p) { MusECore::WavePart* part = (MusECore::WavePart*)(p->second); if (part->sn() == curPartId) curPart = part; int ssample = part->frame(); int esample = ssample + part->lenFrame(); if (ssample < startSample) { startSample = ssample; //printf("startSample = %d\n", startSample); } if (esample > endSample) { endSample = esample; //printf("endSample = %d\n", endSample); } } } if (flags & SC_CLIP_MODIFIED) { redraw(); // Boring, but the only thing possible to do } if (flags & SC_TEMPO) { setPos(0, MusEGlobal::song->cpos(), false); setPos(1, MusEGlobal::song->lpos(), false); setPos(2, MusEGlobal::song->rpos(), false); } redraw(); }
void WaveView::pdraw(QPainter& p, const QRect& rr) { int x1 = rr.x(); int x2 = rr.right() + 1; if (x1 < 0) x1 = 0; if (x2 > width()) x2 = width(); int hh = height(); int h = hh/2; int y = rr.y() + h; // Added by T356. int xScale = xmag; if (xScale < 0) xScale = -xScale; for (MusECore::iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip) { MusECore::WavePart* wp = (MusECore::WavePart*)(ip->second); int channels = wp->track()->channels(); int px = wp->frame(); for (MusECore::ciEvent e = wp->events().begin(); e != wp->events().end(); ++e) { const MusECore::Event event& = e->second; if (event.empty()) continue; MusECore::SndFileR f = event.sndFile(); if(f.isNull()) continue; unsigned peoffset = px + event.frame() - event.spos(); int sx, ex; sx = event.frame() + px + xScale/2; ex = sx + event.lenFrame(); sx = sx / xScale - xpos; ex = ex / xScale - xpos; if (sx < x1) sx = x1; if (ex > x2) ex = x2; int pos = (xpos + sx) * xScale + event.spos() - event.frame() - px; //printf("pos=%d xpos=%d sx=%d ex=%d xScale=%d event.spos=%d event.frame=%d px=%d\n", // pos, xpos, sx, ex, xScale, event.spos(), event.frame(), px); h = hh / (channels * 2); int cc = hh % (channels * 2) ? 0 : 1; for (int i = sx; i < ex; i++) { y = rr.y() + h; MusECore::SampleV sa[f.channels()]; f.read(sa, xScale, pos); pos += xScale; if (pos < event.spos()) continue; int selectionStartPos = selectionStart - peoffset; // Offset transformed to event coords int selectionStopPos = selectionStop - peoffset; for (int k = 0; k < channels; ++k) { int kk = k % f.channels(); int peak = (sa[kk].peak * (h - 1)) / yScale; int rms = (sa[kk].rms * (h - 1)) / yScale; if (peak > h) peak = h; if (rms > h) rms = h; QColor peak_color = QColor(Qt::darkGray); QColor rms_color = QColor(Qt::black); // Changed by T356. Reduces (but not eliminates) drawing artifacts. //if (pos > selectionStartPos && pos < selectionStopPos) { if (pos > selectionStartPos && pos <= selectionStopPos) { peak_color = QColor(Qt::lightGray); rms_color = QColor(Qt::white); // Draw inverted p.setPen(QColor(Qt::black)); p.drawLine(i, y - h + cc, i, y + h - cc ); } p.setPen(peak_color); p.drawLine(i, y - peak - cc, i, y + peak); p.setPen(rms_color); p.drawLine(i, y - rms - cc, i, y + rms); y += 2 * h; } } } } View::pdraw(p, rr); }
WaveEdit::WaveEdit(MusECore::PartList* pl, QWidget* parent, const char* name) : MidiEditor(TopWin::WAVE, 1, pl, parent, name) { setFocusPolicy(Qt::NoFocus); colorMode = colorModeInit; QSignalMapper* mapper = new QSignalMapper(this); QSignalMapper* colorMapper = new QSignalMapper(this); QAction* act; //---------Pulldown Menu---------------------------- // We probably don't need an empty menu - Orcan //QMenu* menuFile = menuBar()->addMenu(tr("&File")); QMenu* menuEdit = menuBar()->addMenu(tr("&Edit")); menuFunctions = menuBar()->addMenu(tr("Func&tions")); menuGain = menuFunctions->addMenu(tr("&Gain")); act = menuGain->addAction("200%"); mapper->setMapping(act, WaveCanvas::CMD_GAIN_200); connect(act, SIGNAL(triggered()), mapper, SLOT(map())); act = menuGain->addAction("150%"); mapper->setMapping(act, WaveCanvas::CMD_GAIN_150); connect(act, SIGNAL(triggered()), mapper, SLOT(map())); act = menuGain->addAction("75%"); mapper->setMapping(act, WaveCanvas::CMD_GAIN_75); connect(act, SIGNAL(triggered()), mapper, SLOT(map())); act = menuGain->addAction("50%"); mapper->setMapping(act, WaveCanvas::CMD_GAIN_50); connect(act, SIGNAL(triggered()), mapper, SLOT(map())); act = menuGain->addAction("25%"); mapper->setMapping(act, WaveCanvas::CMD_GAIN_25); connect(act, SIGNAL(triggered()), mapper, SLOT(map())); act = menuGain->addAction(tr("Other")); mapper->setMapping(act, WaveCanvas::CMD_GAIN_FREE); connect(act, SIGNAL(triggered()), mapper, SLOT(map())); connect(mapper, SIGNAL(mapped(int)), this, SLOT(cmd(int))); menuFunctions->addSeparator(); copyAction = menuEdit->addAction(tr("&Copy")); mapper->setMapping(copyAction, WaveCanvas::CMD_EDIT_COPY); connect(copyAction, SIGNAL(triggered()), mapper, SLOT(map())); copyPartRegionAction = menuEdit->addAction(tr("&Create Part from Region")); mapper->setMapping(copyPartRegionAction, WaveCanvas::CMD_CREATE_PART_REGION); connect(copyPartRegionAction, SIGNAL(triggered()), mapper, SLOT(map())); cutAction = menuEdit->addAction(tr("C&ut")); mapper->setMapping(cutAction, WaveCanvas::CMD_EDIT_CUT); connect(cutAction, SIGNAL(triggered()), mapper, SLOT(map())); pasteAction = menuEdit->addAction(tr("&Paste")); mapper->setMapping(pasteAction, WaveCanvas::CMD_EDIT_PASTE); connect(pasteAction, SIGNAL(triggered()), mapper, SLOT(map())); act = menuEdit->addAction(tr("Edit in E&xternal Editor")); mapper->setMapping(act, WaveCanvas::CMD_EDIT_EXTERNAL); connect(act, SIGNAL(triggered()), mapper, SLOT(map())); menuEdit->addSeparator(); // REMOVE Tim. Also remove CMD_ADJUST_WAVE_OFFSET and so on... // adjustWaveOffsetAction = menuEdit->addAction(tr("Adjust wave offset...")); // mapper->setMapping(adjustWaveOffsetAction, WaveCanvas::CMD_ADJUST_WAVE_OFFSET); // connect(adjustWaveOffsetAction, SIGNAL(triggered()), mapper, SLOT(map())); act = menuFunctions->addAction(tr("Mute Selection")); mapper->setMapping(act, WaveCanvas::CMD_MUTE); connect(act, SIGNAL(triggered()), mapper, SLOT(map())); act = menuFunctions->addAction(tr("Normalize Selection")); mapper->setMapping(act, WaveCanvas::CMD_NORMALIZE); connect(act, SIGNAL(triggered()), mapper, SLOT(map())); act = menuFunctions->addAction(tr("Fade In Selection")); mapper->setMapping(act, WaveCanvas::CMD_FADE_IN); connect(act, SIGNAL(triggered()), mapper, SLOT(map())); act = menuFunctions->addAction(tr("Fade Out Selection")); mapper->setMapping(act, WaveCanvas::CMD_FADE_OUT); connect(act, SIGNAL(triggered()), mapper, SLOT(map())); act = menuFunctions->addAction(tr("Reverse Selection")); mapper->setMapping(act, WaveCanvas::CMD_REVERSE); connect(act, SIGNAL(triggered()), mapper, SLOT(map())); select = menuEdit->addMenu(QIcon(*selectIcon), tr("Select")); selectAllAction = select->addAction(QIcon(*select_allIcon), tr("Select &All")); mapper->setMapping(selectAllAction, WaveCanvas::CMD_SELECT_ALL); connect(selectAllAction, SIGNAL(triggered()), mapper, SLOT(map())); selectNoneAction = select->addAction(QIcon(*select_allIcon), tr("&Deselect All")); mapper->setMapping(selectNoneAction, WaveCanvas::CMD_SELECT_NONE); connect(selectNoneAction, SIGNAL(triggered()), mapper, SLOT(map())); select->addSeparator(); selectPrevPartAction = select->addAction(QIcon(*select_all_parts_on_trackIcon), tr("&Previous Part")); mapper->setMapping(selectPrevPartAction, WaveCanvas::CMD_SELECT_PREV_PART); connect(selectPrevPartAction, SIGNAL(triggered()), mapper, SLOT(map())); selectNextPartAction = select->addAction(QIcon(*select_all_parts_on_trackIcon), tr("&Next Part")); mapper->setMapping(selectNextPartAction, WaveCanvas::CMD_SELECT_NEXT_PART); connect(selectNextPartAction, SIGNAL(triggered()), mapper, SLOT(map())); QMenu* settingsMenu = menuBar()->addMenu(tr("Window &Config")); eventColor = settingsMenu->addMenu(tr("&Event Color")); QActionGroup* actgrp = new QActionGroup(this); actgrp->setExclusive(true); evColorNormalAction = actgrp->addAction(tr("&Part colors")); evColorNormalAction->setCheckable(true); colorMapper->setMapping(evColorNormalAction, 0); evColorPartsAction = actgrp->addAction(tr("&Gray")); evColorPartsAction->setCheckable(true); colorMapper->setMapping(evColorPartsAction, 1); connect(evColorNormalAction, SIGNAL(triggered()), colorMapper, SLOT(map())); connect(evColorPartsAction, SIGNAL(triggered()), colorMapper, SLOT(map())); eventColor->addActions(actgrp->actions()); connect(colorMapper, SIGNAL(mapped(int)), this, SLOT(eventColorModeChanged(int))); settingsMenu->addSeparator(); settingsMenu->addAction(subwinAction); settingsMenu->addAction(shareAction); settingsMenu->addAction(fullscreenAction); connect(MusEGlobal::muse, SIGNAL(configChanged()), SLOT(configChanged())); //-------------------------------------------------- // ToolBar: Solo Cursor1 Cursor2 tools2 = new MusEGui::EditToolBar(this, waveEditTools); addToolBar(tools2); addToolBarBreak(); tb1 = addToolBar(tr("WaveEdit tools")); tb1->setObjectName("WaveEdit tools"); //tb1->setLabel(tr("weTools")); solo = new QToolButton(); solo->setText(tr("Solo")); solo->setCheckable(true); solo->setFocusPolicy(Qt::NoFocus); tb1->addWidget(solo); connect(solo, SIGNAL(toggled(bool)), SLOT(soloChanged(bool))); QLabel* label = new QLabel(tr("Cursor")); tb1->addWidget(label); label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); label->setIndent(3); pos1 = new PosLabel(0); pos1->setFixedHeight(22); tb1->addWidget(pos1); pos2 = new PosLabel(0); pos2->setFixedHeight(22); pos2->setSmpte(true); tb1->addWidget(pos2); //--------------------------------------------------- // Rest //--------------------------------------------------- int yscale = 256; int xscale; if (!parts()->empty()) { // Roughly match total size of part MusECore::Part* firstPart = parts()->begin()->second; xscale = 0 - firstPart->lenFrame()/_widthInit[_type]; } else { xscale = -8000; } hscroll = new ScrollScale(-32768, 1, xscale, 10000, Qt::Horizontal, mainw, 0, false, 10000.0); //view = new WaveView(this, mainw, xscale, yscale); canvas = new WaveCanvas(this, mainw, xscale, yscale); //wview = canvas; // HACK! QSizeGrip* corner = new QSizeGrip(mainw); ymag = new QSlider(Qt::Vertical, mainw); ymag->setMinimum(1); ymag->setMaximum(256); ymag->setPageStep(256); ymag->setValue(yscale); ymag->setFocusPolicy(Qt::NoFocus); time = new MTScale(&_raster, mainw, xscale, true); ymag->setFixedWidth(16); connect(canvas, SIGNAL(mouseWheelMoved(int)), this, SLOT(moveVerticalSlider(int))); connect(ymag, SIGNAL(valueChanged(int)), canvas, SLOT(setYScale(int))); connect(canvas, SIGNAL(horizontalZoom(bool, const QPoint&)), SLOT(horizontalZoom(bool, const QPoint&))); connect(canvas, SIGNAL(horizontalZoom(int, const QPoint&)), SLOT(horizontalZoom(int, const QPoint&))); time->setOrigin(0, 0); mainGrid->setRowStretch(0, 100); mainGrid->setColumnStretch(0, 100); mainGrid->addWidget(time, 0, 0, 1, 2); mainGrid->addWidget(MusECore::hLine(mainw), 1, 0, 1, 2); mainGrid->addWidget(canvas, 2, 0); mainGrid->addWidget(ymag, 2, 1); mainGrid->addWidget(hscroll, 3, 0); mainGrid->addWidget(corner, 3, 1, Qt::AlignBottom | Qt::AlignRight); canvas->setFocus(); connect(canvas, SIGNAL(toolChanged(int)), tools2, SLOT(set(int))); connect(tools2, SIGNAL(toolChanged(int)), canvas, SLOT(setTool(int))); connect(hscroll, SIGNAL(scrollChanged(int)), canvas, SLOT(setXPos(int))); connect(hscroll, SIGNAL(scaleChanged(int)), canvas, SLOT(setXMag(int))); setWindowTitle(canvas->getCaption()); connect(canvas, SIGNAL(followEvent(int)), hscroll, SLOT(setOffset(int))); connect(hscroll, SIGNAL(scrollChanged(int)), time, SLOT(setXPos(int))); connect(hscroll, SIGNAL(scaleChanged(int)), time, SLOT(setXMag(int))); connect(time, SIGNAL(timeChanged(unsigned)), SLOT(timeChanged(unsigned))); connect(canvas, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned))); connect(canvas, SIGNAL(horizontalScroll(unsigned)),hscroll, SLOT(setPos(unsigned))); connect(canvas, SIGNAL(horizontalScrollNoLimit(unsigned)),hscroll, SLOT(setPosNoLimit(unsigned))); connect(hscroll, SIGNAL(scaleChanged(int)), SLOT(updateHScrollRange())); connect(MusEGlobal::song, SIGNAL(songChanged(MusECore::SongChangedFlags_t)), SLOT(songChanged1(MusECore::SongChangedFlags_t))); // For the wave editor, let's start with the operation range selection tool. canvas->setTool(MusEGui::RangeTool); tools2->set(MusEGui::RangeTool); setEventColorMode(colorMode); initShortcuts(); updateHScrollRange(); configChanged(); if(!parts()->empty()) { MusECore::WavePart* part = (MusECore::WavePart*)(parts()->begin()->second); solo->setChecked(part->track()->solo()); } initTopwinState(); finalizeInit(); }
void WaveEdit::soloChanged(bool flag) { MusECore::WavePart* part = (MusECore::WavePart*)(parts()->begin()->second); MusEGlobal::audio->msgSetSolo(part->track(), flag); MusEGlobal::song->update(SC_SOLO); }