Genericificationalizeified AudioFilter (now Filter).

Added primitive (non-undoable, placeholder, etc) quantization.


git-svn-id: svn://localhost/ardour2/trunk@2254 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2007-08-06 05:30:18 +00:00
parent d594470148
commit f68caf23dd
20 changed files with 196 additions and 98 deletions

View file

@ -50,7 +50,7 @@
#include <ardour/location.h> #include <ardour/location.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/region.h> #include <ardour/midi_region.h>
#include <ardour/session_route.h> #include <ardour/session_route.h>
#include <ardour/tempo.h> #include <ardour/tempo.h>
#include <ardour/utils.h> #include <ardour/utils.h>
@ -1531,7 +1531,7 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items)
while (i != selection->regions.end() && boost::dynamic_pointer_cast<AudioRegion>((*i)->region()) == 0) { while (i != selection->regions.end() && boost::dynamic_pointer_cast<AudioRegion>((*i)->region()) == 0) {
++i; ++i;
} }
bool const have_selected_audio_region = (i != selection->regions.end()); const bool have_selected_audio_region = (i != selection->regions.end());
if (have_selected_audio_region) { if (have_selected_audio_region) {
@ -1551,9 +1551,19 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items)
items.push_back (MenuElem (_("Normalize"), mem_fun (*this, &Editor::normalize_regions))); items.push_back (MenuElem (_("Normalize"), mem_fun (*this, &Editor::normalize_regions)));
} }
items.push_back (MenuElem (_("Reverse"), mem_fun(*this, &Editor::reverse_regions))); /* Find out if we have a selected MIDI region */
items.push_back (SeparatorElem()); i = selection->regions.begin();
while (i != selection->regions.end() && boost::dynamic_pointer_cast<MidiRegion>((*i)->region()) == 0) {
++i;
}
const bool have_selected_midi_region = (i != selection->regions.end());
if (have_selected_midi_region) {
items.push_back (MenuElem (_("Quantize"), mem_fun(*this, &Editor::quantize_regions)));
items.push_back (SeparatorElem());
}
/* range related stuff */ /* range related stuff */
@ -2200,24 +2210,24 @@ Editor::snap_to (nframes64_t& start, int32_t direction, bool for_mark)
break; break;
case SnapToAThirtysecondBeat: case SnapToAThirtysecondBeat:
start = session->tempo_map().round_to_beat_subdivision (start, 32); start = session->tempo_map().round_to_beat_subdivision (start, 32);
break; break;
case SnapToASixteenthBeat: case SnapToASixteenthBeat:
start = session->tempo_map().round_to_beat_subdivision (start, 16); start = session->tempo_map().round_to_beat_subdivision (start, 16);
break; break;
case SnapToAEighthBeat: case SnapToAEighthBeat:
start = session->tempo_map().round_to_beat_subdivision (start, 8); start = session->tempo_map().round_to_beat_subdivision (start, 8);
break; break;
case SnapToAQuarterBeat: case SnapToAQuarterBeat:
start = session->tempo_map().round_to_beat_subdivision (start, 4); start = session->tempo_map().round_to_beat_subdivision (start, 4);
break; break;
case SnapToAThirdBeat: case SnapToAThirdBeat:
start = session->tempo_map().round_to_beat_subdivision (start, 3); start = session->tempo_map().round_to_beat_subdivision (start, 3);
break; break;
case SnapToEditCursor: case SnapToEditCursor:
start = edit_cursor->current_frame; start = edit_cursor->current_frame;
@ -2308,6 +2318,52 @@ Editor::snap_to (nframes64_t& start, int32_t direction, bool for_mark)
} }
} }
double
Editor::snap_length_beats (nframes_t start)
{
if (!session) {
return 1.0;
}
const nframes64_t one_second = session->frame_rate();
const nframes64_t one_minute = session->frame_rate() * 60;
const nframes64_t one_smpte_second = (nframes64_t)(rint(session->smpte_frames_per_second()) * session->frames_per_smpte_frame());
nframes64_t one_smpte_minute = (nframes64_t)(rint(session->smpte_frames_per_second()) * session->frames_per_smpte_frame() * 60);
nframes64_t presnap = start;
/* FIXME: This could/should also work with non-tempo based snap settings (ie seconds) */
switch (snap_type) {
case SnapToBar:
return session->tempo_map().meter_at(start).beats_per_bar();
case SnapToBeat:
return 1.0;
case SnapToAThirtysecondBeat:
return 1.0 / (double)32.0;
break;
case SnapToASixteenthBeat:
return 1.0 / (double)16.0;
break;
case SnapToAEighthBeat:
return 1.0 / (double)8.0;
break;
case SnapToAQuarterBeat:
return 1.0 / (double)4.0;
break;
case SnapToAThirdBeat:
return 1.0 / (double)3.0;
default:
return 1.0;
}
}
void void
Editor::setup_toolbar () Editor::setup_toolbar ()
{ {

View file

@ -71,7 +71,7 @@ namespace ARDOUR {
class TempoSection; class TempoSection;
class NamedSelection; class NamedSelection;
class Session; class Session;
class AudioFilter; class Filter;
class Crossfade; class Crossfade;
class ChanCount; class ChanCount;
} }
@ -746,7 +746,7 @@ class Editor : public PublicEditor
/* snapshots */ /* snapshots */
Gtk::ScrolledWindow snapshot_display_scroller; Gtk::ScrolledWindow snapshot_display_scroller;
struct SnapshotDisplayModelColumns : public Gtk::TreeModel::ColumnRecord { struct SnapshotDisplayModelColumns : public Gtk::TreeModel::ColumnRecord {
SnapshotDisplayModelColumns() { SnapshotDisplayModelColumns() {
add (visible_name); add (visible_name);
@ -892,6 +892,7 @@ class Editor : public PublicEditor
void reverse_regions (); void reverse_regions ();
void normalize_regions (); void normalize_regions ();
void denormalize_regions (); void denormalize_regions ();
void quantize_regions ();
void audition_region_from_region_list (); void audition_region_from_region_list ();
void hide_region_from_region_list (); void hide_region_from_region_list ();
@ -1289,6 +1290,8 @@ class Editor : public PublicEditor
first = (nframes_t) first64; first = (nframes_t) first64;
} }
double snap_length_beats (nframes_t start);
uint32_t bbt_beat_subdivision; uint32_t bbt_beat_subdivision;
/* toolbar */ /* toolbar */
@ -1805,7 +1808,7 @@ class Editor : public PublicEditor
/* audio filters */ /* audio filters */
void apply_filter (ARDOUR::AudioFilter&, string cmd); void apply_filter (ARDOUR::Filter&, string cmd);
/* handling cleanup */ /* handling cleanup */

View file

@ -254,6 +254,8 @@ Editor::register_actions ()
ActionManager::session_sensitive_actions.push_back (act); ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "normalize-region", _("Normalize Regions"), mem_fun(*this, &Editor::normalize_regions)); act = ActionManager::register_action (editor_actions, "normalize-region", _("Normalize Regions"), mem_fun(*this, &Editor::normalize_regions));
ActionManager::session_sensitive_actions.push_back (act); ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "quantize-region", _("Quantize Regions"), mem_fun(*this, &Editor::quantize_regions));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "crop", _("crop"), mem_fun(*this, &Editor::crop_region_to_selection)); act = ActionManager::register_action (editor_actions, "crop", _("crop"), mem_fun(*this, &Editor::crop_region_to_selection));
ActionManager::session_sensitive_actions.push_back (act); ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "insert-chunk", _("Insert Chunk"), bind (mem_fun(*this, &Editor::paste_named_selection), 1.0f)); act = ActionManager::register_action (editor_actions, "insert-chunk", _("Insert Chunk"), bind (mem_fun(*this, &Editor::paste_named_selection), 1.0f));

View file

@ -48,6 +48,7 @@
#include <ardour/region_factory.h> #include <ardour/region_factory.h>
#include <ardour/playlist_factory.h> #include <ardour/playlist_factory.h>
#include <ardour/reverse.h> #include <ardour/reverse.h>
#include <ardour/quantize.h>
#include "ardour_ui.h" #include "ardour_ui.h"
#include "editor.h" #include "editor.h"
@ -56,6 +57,7 @@
#include "automation_time_axis.h" #include "automation_time_axis.h"
#include "streamview.h" #include "streamview.h"
#include "audio_region_view.h" #include "audio_region_view.h"
#include "midi_region_view.h"
#include "rgb_macros.h" #include "rgb_macros.h"
#include "selection_templates.h" #include "selection_templates.h"
#include "selection.h" #include "selection.h"
@ -3281,8 +3283,21 @@ Editor::reverse_regions ()
apply_filter (rev, _("reverse regions")); apply_filter (rev, _("reverse regions"));
} }
void void
Editor::apply_filter (AudioFilter& filter, string command) Editor::quantize_regions ()
{
if (!session) {
return;
}
// FIXME: varying meter?
Quantize quant (*session, snap_length_beats(0));
apply_filter (quant, _("quantize regions"));
}
void
Editor::apply_filter (Filter& filter, string command)
{ {
if (selection->regions.empty()) { if (selection->regions.empty()) {
return; return;
@ -3293,26 +3308,31 @@ Editor::apply_filter (AudioFilter& filter, string command)
track_canvas.get_window()->set_cursor (*wait_cursor); track_canvas.get_window()->set_cursor (*wait_cursor);
gdk_flush (); gdk_flush ();
/* this is ugly. */
for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ) { for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r); RegionSelection::iterator tmp = r;
if (!arv)
continue;
boost::shared_ptr<Playlist> playlist = arv->region()->playlist();
RegionSelection::iterator tmp;
tmp = r;
++tmp; ++tmp;
if (arv->audio_region()->apply (filter) == 0) { MidiRegionView* const mrv = dynamic_cast<MidiRegionView*>(*r);
if (mrv) {
if (mrv->midi_region()->apply(filter) == 0) {
mrv->redisplay_model();
}
}
XMLNode &before = playlist->get_state(); AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
playlist->replace_region (arv->region(), filter.results.front(), arv->region()->position()); if (arv) {
XMLNode &after = playlist->get_state(); boost::shared_ptr<Playlist> playlist = arv->region()->playlist();
session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
} else { if (arv->audio_region()->apply (filter) == 0) {
goto out;
XMLNode &before = playlist->get_state();
playlist->replace_region (arv->region(), filter.results.front(), arv->region()->position());
XMLNode &after = playlist->get_state();
session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
} else {
goto out;
}
} }
r = tmp; r = tmp;

View file

@ -423,12 +423,6 @@ MidiRegionView::set_y_position_and_height (double y, double h)
} }
} }
void
MidiRegionView::show_region_editor ()
{
cerr << "No MIDI region editor." << endl;
}
GhostRegion* GhostRegion*
MidiRegionView::add_ghost (AutomationTimeAxisView& atv) MidiRegionView::add_ghost (AutomationTimeAxisView& atv)
{ {

View file

@ -69,7 +69,7 @@ class MidiRegionView : public RegionView
void set_y_position_and_height (double, double); void set_y_position_and_height (double, double);
void show_region_editor (); void redisplay_model();
GhostRegion* add_ghost (AutomationTimeAxisView&); GhostRegion* add_ghost (AutomationTimeAxisView&);
@ -164,7 +164,6 @@ class MidiRegionView : public RegionView
private: private:
void redisplay_model();
void clear_events(); void clear_events();
bool canvas_event(GdkEvent* ev); bool canvas_event(GdkEvent* ev);

View file

@ -116,6 +116,9 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
/** Snap a value according to the current snap setting. */ /** Snap a value according to the current snap setting. */
virtual void snap_to (nframes_t& first, int32_t direction = 0, bool for_mark = false) = 0; virtual void snap_to (nframes_t& first, int32_t direction = 0, bool for_mark = false) = 0;
/** Get the current snap value in beats */
virtual double snap_length_beats (nframes_t start) = 0;
/** Undo some transactions. /** Undo some transactions.
* @param n Number of transactions to undo. * @param n Number of transactions to undo.
*/ */

View file

@ -70,7 +70,7 @@ class RegionView : public TimeAxisViewItem
bool set_position(nframes_t pos, void* src, double* delta = 0); bool set_position(nframes_t pos, void* src, double* delta = 0);
void fake_set_opaque (bool yn); void fake_set_opaque (bool yn);
virtual void show_region_editor () = 0; virtual void show_region_editor () {}
virtual void hide_region_editor(); virtual void hide_region_editor();
virtual void region_changed (ARDOUR::Change); virtual void region_changed (ARDOUR::Change);

View file

@ -52,8 +52,8 @@ buffer_set.cc
meter.cc meter.cc
amp.cc amp.cc
panner.cc panner.cc
filter.cc
audiofilesource.cc audiofilesource.cc
audiofilter.cc
audioregion.cc audioregion.cc
audiosource.cc audiosource.cc
midi_source.cc midi_source.cc
@ -99,6 +99,7 @@ recent_sessions.cc
region.cc region.cc
region_factory.cc region_factory.cc
reverse.cc reverse.cc
quantize.cc
route.cc route.cc
route_group.cc route_group.cc
send.cc send.cc

View file

@ -38,7 +38,7 @@ namespace ARDOUR {
class Route; class Route;
class Playlist; class Playlist;
class Session; class Session;
class AudioFilter; class Filter;
class AudioSource; class AudioSource;
class AudioRegion : public Region class AudioRegion : public Region
@ -115,10 +115,6 @@ class AudioRegion : public Region
int separate_by_channel (ARDOUR::Session&, vector<boost::shared_ptr<AudioRegion> >&) const; int separate_by_channel (ARDOUR::Session&, vector<boost::shared_ptr<AudioRegion> >&) const;
/* filter */
int apply (AudioFilter&);
/* export */ /* export */
int exportme (ARDOUR::Session&, ARDOUR::AudioExportSpecification&); int exportme (ARDOUR::Session&, ARDOUR::AudioExportSpecification&);

View file

@ -1,5 +1,6 @@
/* /*
Copyright (C) 2004 Paul Davis Copyright (C) 2007 Paul Davis
Author: Dave Robillard
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -17,34 +18,34 @@
*/ */
#ifndef __ardour_audiofilter_h__ #ifndef __ardour_filter_h__
#define __ardour_audiofilter_h__ #define __ardour_filter_h__
#include <vector> #include <vector>
#include <ardour/audioregion.h> #include <ardour/region.h>
namespace ARDOUR { namespace ARDOUR {
class AudioRegion; class Region;
class Session; class Session;
class AudioFilter { class Filter {
public: public:
AudioFilter (ARDOUR::Session& s) virtual ~Filter() {}
: session (s){}
virtual ~AudioFilter() {}
virtual int run (boost::shared_ptr<ARDOUR::AudioRegion>) = 0; virtual int run (boost::shared_ptr<ARDOUR::Region>) = 0;
std::vector<boost::shared_ptr<ARDOUR::AudioRegion> > results; std::vector<boost::shared_ptr<ARDOUR::Region> > results;
protected: protected:
ARDOUR::Session& session; Filter (ARDOUR::Session& s) : session(s) {}
int make_new_sources (boost::shared_ptr<ARDOUR::AudioRegion>, ARDOUR::SourceList&); int make_new_sources (boost::shared_ptr<ARDOUR::Region>, ARDOUR::SourceList&);
int finish (boost::shared_ptr<ARDOUR::AudioRegion>, ARDOUR::SourceList&); int finish (boost::shared_ptr<ARDOUR::Region>, ARDOUR::SourceList&);
ARDOUR::Session& session;
}; };
} /* namespace */ } /* namespace */
#endif /* __ardour_audiofilter_h__ */ #endif /* __ardour_filter_h__ */

View file

@ -35,6 +35,7 @@ class XMLNode;
namespace ARDOUR { namespace ARDOUR {
class Playlist; class Playlist;
class Filter;
enum RegionEditState { enum RegionEditState {
EditChangesNothing = 0, EditChangesNothing = 0,
@ -166,6 +167,8 @@ class Region : public PBD::StatefulDestructible, public boost::enable_shared_fro
void set_locked (bool yn); void set_locked (bool yn);
void set_position_locked (bool yn); void set_position_locked (bool yn);
int apply (Filter&);
virtual uint32_t read_data_count() const { return _read_data_count; } virtual uint32_t read_data_count() const { return _read_data_count; }
boost::shared_ptr<ARDOUR::Playlist> playlist() const { return _playlist.lock(); } boost::shared_ptr<ARDOUR::Playlist> playlist() const { return _playlist.lock(); }

View file

@ -20,16 +20,16 @@
#ifndef __ardour_reverse_h__ #ifndef __ardour_reverse_h__
#define __ardour_reverse_h__ #define __ardour_reverse_h__
#include <ardour/audiofilter.h> #include <ardour/filter.h>
namespace ARDOUR { namespace ARDOUR {
class Reverse : public AudioFilter { class Reverse : public Filter {
public: public:
Reverse (ARDOUR::Session&); Reverse (ARDOUR::Session&);
~Reverse (); ~Reverse ();
int run (boost::shared_ptr<ARDOUR::AudioRegion>); int run (boost::shared_ptr<ARDOUR::Region>);
}; };
} /* namespace */ } /* namespace */

View file

@ -553,7 +553,7 @@ class Session : public PBD::StatefulDestructible
int region_name (string& result, string base = string(""), bool newlevel = false) const; int region_name (string& result, string base = string(""), bool newlevel = false) const;
string new_region_name (string); string new_region_name (string);
string path_from_region_name (string name, string identifier); string path_from_region_name (DataType type, string name, string identifier);
boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>); boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>);

View file

@ -38,7 +38,6 @@
#include <ardour/gain.h> #include <ardour/gain.h>
#include <ardour/dB.h> #include <ardour/dB.h>
#include <ardour/playlist.h> #include <ardour/playlist.h>
#include <ardour/audiofilter.h>
#include <ardour/audiofilesource.h> #include <ardour/audiofilesource.h>
#include <ardour/region_factory.h> #include <ardour/region_factory.h>
#include <ardour/runtime_functions.h> #include <ardour/runtime_functions.h>
@ -977,13 +976,6 @@ AudioRegion::separate_by_channel (Session& session, vector<boost::shared_ptr<Aud
return 0; return 0;
} }
int
AudioRegion::apply (AudioFilter& filter)
{
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (shared_from_this());
return filter.run (ar);
}
nframes_t nframes_t
AudioRegion::read_raw_internal (Sample* buf, nframes_t pos, nframes_t cnt) const AudioRegion::read_raw_internal (Sample* buf, nframes_t pos, nframes_t cnt) const
{ {

View file

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2004 Paul Davis Copyright (C) 2004-2007 Paul Davis
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -22,9 +22,10 @@
#include <pbd/basename.h> #include <pbd/basename.h>
#include <ardour/sndfilesource.h> #include <ardour/sndfilesource.h>
#include <ardour/smf_source.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/audioregion.h> #include <ardour/region.h>
#include <ardour/audiofilter.h> #include <ardour/filter.h>
#include <ardour/region_factory.h> #include <ardour/region_factory.h>
#include <ardour/source_factory.h> #include <ardour/source_factory.h>
@ -34,27 +35,28 @@ using namespace ARDOUR;
using namespace PBD; using namespace PBD;
int int
AudioFilter::make_new_sources (boost::shared_ptr<AudioRegion> region, SourceList& nsrcs) Filter::make_new_sources (boost::shared_ptr<Region> region, SourceList& nsrcs)
{ {
vector<string> names = region->master_source_names(); vector<string> names = region->master_source_names();
for (uint32_t i = 0; i < region->n_channels(); ++i) { for (uint32_t i = 0; i < region->n_channels(); ++i) {
string path = session.path_from_region_name (PBD::basename_nosuffix (names[i]), string ("")); string path = session.path_from_region_name (region->data_type(),
PBD::basename_nosuffix (names[i]), string (""));
if (path.length() == 0) { if (path.length() == 0) {
error << string_compose (_("audiofilter: error creating name for new audio file based on %1"), region->name()) error << string_compose (_("filter: error creating name for new file based on %1"), region->name())
<< endmsg; << endmsg;
return -1; return -1;
} }
try { try {
nsrcs.push_back (boost::dynamic_pointer_cast<AudioSource> ( nsrcs.push_back (boost::dynamic_pointer_cast<Source> (
SourceFactory::createWritable (DataType::AUDIO, session, path, false, session.frame_rate()))); SourceFactory::createWritable (region->data_type(), session, path, false, session.frame_rate())));
} }
catch (failed_constructor& err) { catch (failed_constructor& err) {
error << string_compose (_("audiofilter: error creating new audio file %1 (%2)"), path, strerror (errno)) << endmsg; error << string_compose (_("filter: error creating new file %1 (%2)"), path, strerror (errno)) << endmsg;
return -1; return -1;
} }
} }
@ -63,7 +65,7 @@ AudioFilter::make_new_sources (boost::shared_ptr<AudioRegion> region, SourceList
} }
int int
AudioFilter::finish (boost::shared_ptr<AudioRegion> region, SourceList& nsrcs) Filter::finish (boost::shared_ptr<Region> region, SourceList& nsrcs)
{ {
string region_name; string region_name;
@ -75,20 +77,29 @@ AudioFilter::finish (boost::shared_ptr<AudioRegion> region, SourceList& nsrcs)
time (&xnow); time (&xnow);
now = localtime (&xnow); now = localtime (&xnow);
/* this is ugly. */
for (SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) { for (SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) {
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*si); boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*si);
if (afs) { if (afs) {
afs->update_header (region->position(), *now, xnow); afs->update_header (region->position(), *now, xnow);
afs->mark_immutable (); afs->mark_immutable ();
} }
boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource>(*si);
if (smfs) {
smfs->update_header (region->position(), *now, xnow);
smfs->flush_footer ();
}
} }
/* create a new region */ /* create a new region */
region_name = session.new_region_name (region->name()); region_name = session.new_region_name (region->name());
results.clear (); results.clear ();
results.push_back (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (nsrcs, 0, region->length(), region_name, 0, results.push_back (RegionFactory::create (nsrcs, 0, region->length(), region_name, 0,
Region::Flag (Region::WholeFile|Region::DefaultFlags)))); Region::Flag (Region::WholeFile|Region::DefaultFlags)));
return 0; return 0;
} }

View file

@ -34,6 +34,7 @@
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/source.h> #include <ardour/source.h>
#include <ardour/region_factory.h> #include <ardour/region_factory.h>
#include <ardour/filter.h>
#include "i18n.h" #include "i18n.h"
@ -1265,3 +1266,10 @@ Region::get_parent() const
return boost::shared_ptr<Region>(); return boost::shared_ptr<Region>();
} }
int
Region::apply (Filter& filter)
{
return filter.run (shared_from_this());
}

View file

@ -33,7 +33,7 @@ using namespace std;
using namespace ARDOUR; using namespace ARDOUR;
Reverse::Reverse (Session& s) Reverse::Reverse (Session& s)
: AudioFilter (s) : Filter (s)
{ {
} }
@ -42,7 +42,7 @@ Reverse::~Reverse ()
} }
int int
Reverse::run (boost::shared_ptr<AudioRegion> region) Reverse::run (boost::shared_ptr<Region> r)
{ {
SourceList nsrcs; SourceList nsrcs;
SourceList::iterator si; SourceList::iterator si;
@ -53,6 +53,10 @@ Reverse::run (boost::shared_ptr<AudioRegion> region)
nframes_t to_read; nframes_t to_read;
int ret = -1; int ret = -1;
boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion>(r);
if (!region)
return ret;
/* create new sources */ /* create new sources */
if (make_new_sources (region, nsrcs)) { if (make_new_sources (region, nsrcs)) {

View file

@ -1502,19 +1502,24 @@ Session::get_sources_as_xml ()
} }
string string
Session::path_from_region_name (string name, string identifier) Session::path_from_region_name (DataType type, string name, string identifier)
{ {
char buf[PATH_MAX+1]; char buf[PATH_MAX+1];
uint32_t n; uint32_t n;
SessionDirectory sdir(get_best_session_directory_for_new_source()); SessionDirectory sdir(get_best_session_directory_for_new_source());
string sound_dir = sdir.sound_path().to_string(); string sound_dir = ((type == DataType::AUDIO)
? sdir.sound_path().to_string()
: sdir.midi_path().to_string());
string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
for (n = 0; n < 999999; ++n) { for (n = 0; n < 999999; ++n) {
if (identifier.length()) { if (identifier.length()) {
snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", sound_dir.c_str(), name.c_str(), snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
identifier.c_str(), n); identifier.c_str(), n, ext.c_str());
} else { } else {
snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", sound_dir.c_str(), name.c_str(), n); snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
n, ext.c_str());
} }
if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) { if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {

View file

@ -85,7 +85,7 @@ Session::tempoize_region (TimeStretchRequest& tsr)
rstr = names[i]; rstr = names[i];
} }
string path = path_from_region_name (PBD::basename_nosuffix (rstr), ident); string path = path_from_region_name (DataType::AUDIO, PBD::basename_nosuffix (rstr), ident);
if (path.length() == 0) { if (path.length() == 0) {
error << string_compose (_("tempoize: error creating name for new audio file based on %1"), tsr.region->name()) error << string_compose (_("tempoize: error creating name for new audio file based on %1"), tsr.region->name())