You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
209 lines
6.9 KiB
209 lines
6.9 KiB
/*
|
|
Rosegarden
|
|
A MIDI and audio sequencer and musical notation editor.
|
|
|
|
This program is Copyright 2000-2008
|
|
Guillaume Laurent <glaurent@telegraph-road.org>,
|
|
Chris Cannam <cannam@all-day-breakfast.com>,
|
|
Richard Bown <richard.bown@ferventsoftware.com>
|
|
|
|
The moral rights of Guillaume Laurent, Chris Cannam, and Richard
|
|
Bown to claim authorship of this work have been asserted.
|
|
|
|
Other copyrights also apply to some parts of this work. Please
|
|
see the AUTHORS file and individual file headers for details.
|
|
|
|
This program 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. See the file
|
|
COPYING included with this distribution for more information.
|
|
*/
|
|
|
|
|
|
#include "AudioSegmentRescaleCommand.h"
|
|
|
|
#include "misc/Strings.h"
|
|
#include "base/Event.h"
|
|
#include "base/Composition.h"
|
|
#include "base/NotationTypes.h"
|
|
#include "base/Segment.h"
|
|
#include "document/RosegardenGUIDoc.h"
|
|
#include "sound/AudioFileTimeStretcher.h"
|
|
#include "sound/AudioFileManager.h"
|
|
#include "gui/widgets/ProgressDialog.h"
|
|
#include <tqstring.h>
|
|
|
|
|
|
namespace Rosegarden
|
|
{
|
|
|
|
AudioSegmentRescaleCommand::AudioSegmentRescaleCommand(RosegardenGUIDoc *doc,
|
|
Segment *s,
|
|
float ratio) :
|
|
KNamedCommand(getGlobalName()),
|
|
m_afm(&doc->getAudioFileManager()),
|
|
m_stretcher(new AudioFileTimeStretcher(m_afm)),
|
|
m_segment(s),
|
|
m_newSegment(0),
|
|
m_fid(-1),
|
|
m_timesGiven(false),
|
|
m_startTime(0),
|
|
m_endMarkerTime(0),
|
|
m_ratio(ratio),
|
|
m_detached(false)
|
|
{
|
|
// nothing
|
|
}
|
|
|
|
AudioSegmentRescaleCommand::AudioSegmentRescaleCommand(RosegardenGUIDoc *doc,
|
|
Segment *s,
|
|
float ratio,
|
|
timeT st,
|
|
timeT emt) :
|
|
KNamedCommand(getGlobalName()),
|
|
m_afm(&doc->getAudioFileManager()),
|
|
m_stretcher(new AudioFileTimeStretcher(m_afm)),
|
|
m_segment(s),
|
|
m_newSegment(0),
|
|
m_fid(-1),
|
|
m_timesGiven(true),
|
|
m_startTime(st),
|
|
m_endMarkerTime(emt),
|
|
m_ratio(ratio),
|
|
m_detached(false)
|
|
{
|
|
// nothing
|
|
}
|
|
|
|
AudioSegmentRescaleCommand::~AudioSegmentRescaleCommand()
|
|
{
|
|
delete m_stretcher;
|
|
|
|
if (m_detached) {
|
|
delete m_segment;
|
|
} else {
|
|
delete m_newSegment;
|
|
}
|
|
}
|
|
|
|
void
|
|
AudioSegmentRescaleCommand::connectProgressDialog(ProgressDialog *dlg)
|
|
{
|
|
TQObject::connect(m_stretcher, TQT_SIGNAL(setProgress(int)),
|
|
dlg->progressBar(), TQT_SLOT(setValue(int)));
|
|
TQObject::connect(dlg, TQT_SIGNAL(cancelClicked()),
|
|
m_stretcher, TQT_SLOT(slotStopTimestretch()));
|
|
}
|
|
|
|
void
|
|
AudioSegmentRescaleCommand::disconnectProgressDialog(ProgressDialog *dlg)
|
|
{
|
|
TQObject::disconnect(m_stretcher, TQT_SIGNAL(setProgress(int)),
|
|
dlg->progressBar(), TQT_SLOT(setValue(int)));
|
|
TQObject::disconnect(dlg, TQT_SIGNAL(cancelClicked()),
|
|
m_stretcher, TQT_SLOT(slotStopTimestretch()));
|
|
}
|
|
|
|
void
|
|
AudioSegmentRescaleCommand::execute()
|
|
{
|
|
timeT startTime = m_segment->getStartTime();
|
|
|
|
if (m_segment->getType() != Segment::Audio) {
|
|
return;
|
|
}
|
|
|
|
bool failed = false;
|
|
|
|
if (!m_newSegment) {
|
|
|
|
m_newSegment = new Segment(*m_segment);
|
|
|
|
TQString oldLabel = strtoqstr(m_segment->getLabel());
|
|
if (!oldLabel.endsWith(i18n("(rescaled)"))) {
|
|
m_newSegment->setLabel(qstrtostr(i18n("%1 (rescaled)").arg
|
|
(oldLabel)));
|
|
}
|
|
|
|
AudioFileId sourceFileId = m_segment->getAudioFileId();
|
|
float absoluteRatio = m_ratio;
|
|
|
|
std::cerr << "AudioSegmentRescaleCommand: segment file id " << sourceFileId << ", given ratio " << m_ratio << std::endl;
|
|
|
|
if (m_segment->getStretchRatio() != 1.f &&
|
|
m_segment->getStretchRatio() != 0.f) {
|
|
sourceFileId = m_segment->getUnstretchedFileId();
|
|
absoluteRatio *= m_segment->getStretchRatio();
|
|
std::cerr << "AudioSegmentRescaleCommand: unstretched file id " << sourceFileId << ", prev ratio " << m_segment->getStretchRatio() << ", resulting ratio " << absoluteRatio << std::endl;
|
|
}
|
|
|
|
if (!m_timesGiven) {
|
|
m_endMarkerTime = m_segment->getStartTime() +
|
|
(m_segment->getEndMarkerTime() - m_segment->getStartTime()) * m_ratio;
|
|
}
|
|
|
|
try {
|
|
m_fid = m_stretcher->getStretchedAudioFile(sourceFileId,
|
|
absoluteRatio);
|
|
m_newSegment->setAudioFileId(m_fid);
|
|
m_newSegment->setUnstretchedFileId(sourceFileId);
|
|
m_newSegment->setStretchRatio(absoluteRatio);
|
|
m_newSegment->setAudioStartTime(m_segment->getAudioStartTime() *
|
|
m_ratio);
|
|
if (m_timesGiven) {
|
|
m_newSegment->setStartTime(m_startTime);
|
|
m_newSegment->setAudioEndTime(m_segment->getAudioEndTime() *
|
|
m_ratio);
|
|
m_newSegment->setEndMarkerTime(m_endMarkerTime);
|
|
} else {
|
|
m_newSegment->setEndMarkerTime(m_endMarkerTime);
|
|
m_newSegment->setAudioEndTime(m_segment->getAudioEndTime() *
|
|
m_ratio);
|
|
}
|
|
} catch (SoundFile::BadSoundFileException e) {
|
|
std::cerr << "AudioSegmentRescaleCommand: ERROR: BadSoundFileException: "
|
|
<< e.getMessage() << std::endl;
|
|
delete m_newSegment;
|
|
m_newSegment = 0;
|
|
m_fid = -1;
|
|
failed = true;
|
|
} catch (AudioFileManager::BadAudioPathException e) {
|
|
std::cerr << "AudioSegmentRescaleCommand: ERROR: BadAudioPathException: "
|
|
<< e.getMessage() << std::endl;
|
|
delete m_newSegment;
|
|
m_newSegment = 0;
|
|
m_fid = -1;
|
|
failed = true;
|
|
} catch (AudioFileTimeStretcher::CancelledException e) {
|
|
std::cerr << "AudioSegmentRescaleCommand: ERROR: Rescale cancelled" << std::endl;
|
|
delete m_newSegment;
|
|
m_newSegment = 0;
|
|
m_fid = -1;
|
|
failed = true;
|
|
}
|
|
}
|
|
|
|
if (failed) return;
|
|
|
|
m_segment->getComposition()->addSegment(m_newSegment);
|
|
m_segment->getComposition()->detachSegment(m_segment);
|
|
|
|
// m_newSegment->setEndMarkerTime
|
|
// (startTime + rescale(m_segment->getEndMarkerTime() - startTime));
|
|
|
|
m_detached = true;
|
|
}
|
|
|
|
void
|
|
AudioSegmentRescaleCommand::unexecute()
|
|
{
|
|
if (m_newSegment) {
|
|
m_newSegment->getComposition()->addSegment(m_segment);
|
|
m_newSegment->getComposition()->detachSegment(m_newSegment);
|
|
m_detached = false;
|
|
}
|
|
}
|
|
|
|
}
|