Heavy-duty abstraction work to split type-specific classes into
specializations of (new, for the most part) generic bases. (eg. most everything from the MIDI branch except for actual MIDI things, so merges have a chance of succeeding). Also the new edit toolbar, and various other cleanup things I did along the way. Should be functionally equivalent (except the toolbar), this is just design work. She's a big'un.... git-svn-id: svn://localhost/ardour2/trunk@727 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
@@ -539,7 +539,7 @@ if env['SYSLIBS']:
|
||||
|
||||
# libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
|
||||
libraries['soundtouch'] = LibraryInfo()
|
||||
libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
|
||||
libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
|
||||
|
||||
coredirs = [
|
||||
'templates'
|
||||
|
||||
@@ -75,6 +75,7 @@ ardour_ui_ed.cc
|
||||
ardour_ui_mixer.cc
|
||||
ardour_ui_options.cc
|
||||
audio_clock.cc
|
||||
route_time_axis.cc
|
||||
audio_time_axis.cc
|
||||
automation_gain_line.cc
|
||||
automation_line.cc
|
||||
@@ -157,10 +158,11 @@ public_editor.cc
|
||||
redirect_automation_line.cc
|
||||
redirect_automation_time_axis.cc
|
||||
redirect_box.cc
|
||||
region_editor.cc
|
||||
audio_region_editor.cc
|
||||
region_gain_line.cc
|
||||
region_selection.cc
|
||||
regionview.cc
|
||||
region_view.cc
|
||||
audio_region_view.cc
|
||||
route_params_ui.cc
|
||||
route_redirect_selection.cc
|
||||
route_ui.cc
|
||||
@@ -168,7 +170,8 @@ selection.cc
|
||||
sfdb_ui.cc
|
||||
send_ui.cc
|
||||
streamview.cc
|
||||
taperegionview.cc
|
||||
audio_streamview.cc
|
||||
tape_region_view.cc
|
||||
tempo_dialog.cc
|
||||
time_axis_view.cc
|
||||
time_axis_view_item.cc
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <gtkmm/treeiter.h>
|
||||
|
||||
#include <ardour/audioregion.h>
|
||||
#include <ardour/playlist.h>
|
||||
#include <ardour/audioplaylist.h>
|
||||
#include <ardour/types.h>
|
||||
|
||||
#include "analysis_window.h"
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "time_axis_view.h"
|
||||
#include "public_editor.h"
|
||||
#include "selection.h"
|
||||
#include "regionview.h"
|
||||
#include "audio_region_view.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
@@ -225,11 +225,16 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
|
||||
|
||||
Selection s = PublicEditor::instance().get_selection();
|
||||
TimeSelection ts = s.time;
|
||||
AudioRegionSelection ars = s.audio_regions;
|
||||
RegionSelection ars = s.regions;
|
||||
|
||||
|
||||
for (TrackSelection::iterator i = s.tracks.begin(); i != s.tracks.end(); ++i) {
|
||||
ARDOUR::Playlist *pl = (*i)->playlist();
|
||||
ARDOUR::AudioPlaylist *pl
|
||||
= dynamic_cast<ARDOUR::AudioPlaylist*>((*i)->playlist());
|
||||
|
||||
if (!pl)
|
||||
continue;
|
||||
|
||||
RouteUI *rui = dynamic_cast<RouteUI *>(*i);
|
||||
|
||||
// Busses don't have playlists, so we need to check that we actually are working with a playlist
|
||||
@@ -274,24 +279,29 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
|
||||
|
||||
TimeAxisView *current_axis = (*i);
|
||||
|
||||
for (std::set<AudioRegionView *>::iterator j = ars.begin(); j != ars.end(); ++j) {
|
||||
for (std::set<RegionView *>::iterator j = ars.begin(); j != ars.end(); ++j) {
|
||||
// Check that the region is actually audio (so we can analyze it)
|
||||
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*j);
|
||||
if (!arv)
|
||||
continue;
|
||||
|
||||
// Check that the region really is selected on _this_ track/solo
|
||||
if ( &(*j)->get_time_axis_view() != current_axis)
|
||||
if ( &arv->get_time_axis_view() != current_axis)
|
||||
continue;
|
||||
|
||||
// cerr << " - " << (*j)->region.name() << ": " << (*j)->region.length() << " samples starting at " << (*j)->region.position() << endl;
|
||||
// cerr << " - " << (*j)->region().name() << ": " << (*j)->region().length() << " samples starting at " << (*j)->region().position() << endl;
|
||||
jack_nframes_t i = 0;
|
||||
int n;
|
||||
|
||||
while ( i < (*j)->region.length() ) {
|
||||
while ( i < arv->region().length() ) {
|
||||
// TODO: What about stereo+ channels? composite all to one, I guess
|
||||
|
||||
n = fft_graph.windowSize();
|
||||
if (i + n >= (*j)->region.length() ) {
|
||||
n = (*j)->region.length() - i;
|
||||
if (i + n >= arv->region().length() ) {
|
||||
n = arv->region().length() - i;
|
||||
}
|
||||
|
||||
n = (*j)->region.read_at(buf, mixbuf, gain, work, (*j)->region.position() + i, n);
|
||||
|
||||
n = arv->audio_region().read_at(buf, mixbuf, gain, work, arv->region().position() + i, n);
|
||||
|
||||
if ( n < fft_graph.windowSize()) {
|
||||
for (int j = n; j < fft_graph.windowSize(); j++) {
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <midi++/mmc.h>
|
||||
|
||||
#include <ardour/ardour.h>
|
||||
#include <ardour/session_route.h>
|
||||
#include <ardour/port.h>
|
||||
#include <ardour/audioengine.h>
|
||||
#include <ardour/playlist.h>
|
||||
@@ -53,7 +54,6 @@
|
||||
#include <ardour/audio_diskstream.h>
|
||||
#include <ardour/audiofilesource.h>
|
||||
#include <ardour/recent_sessions.h>
|
||||
#include <ardour/session_diskstream.h>
|
||||
#include <ardour/port.h>
|
||||
#include <ardour/audio_track.h>
|
||||
|
||||
@@ -186,8 +186,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
|
||||
gettimeofday (&last_shuttle_request, 0);
|
||||
|
||||
ARDOUR::AudioDiskstream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
|
||||
ARDOUR::AudioDiskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
|
||||
ARDOUR::AudioDiskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
|
||||
ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
|
||||
ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
|
||||
|
||||
/* handle pending state with a dialog */
|
||||
|
||||
@@ -543,9 +543,10 @@ ARDOUR_UI::update_buffer_load ()
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::count_recenabled_diskstreams (AudioDiskstream& ds)
|
||||
ARDOUR_UI::count_recenabled_diskstreams (Route& route)
|
||||
{
|
||||
if (ds.record_enabled()) {
|
||||
Track* track = dynamic_cast<Track*>(&route);
|
||||
if (track && track->diskstream().record_enabled()) {
|
||||
rec_enabled_diskstreams++;
|
||||
}
|
||||
}
|
||||
@@ -571,7 +572,7 @@ ARDOUR_UI::update_disk_space()
|
||||
if (session->actively_recording()){
|
||||
|
||||
rec_enabled_diskstreams = 0;
|
||||
session->foreach_audio_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
|
||||
session->foreach_route (this, &ARDOUR_UI::count_recenabled_diskstreams);
|
||||
|
||||
if (rec_enabled_diskstreams) {
|
||||
frames /= rec_enabled_diskstreams;
|
||||
@@ -918,7 +919,7 @@ restart JACK with more ports."));
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::diskstream_added (AudioDiskstream* ds)
|
||||
ARDOUR_UI::diskstream_added (Diskstream* ds)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1169,12 +1170,15 @@ ARDOUR_UI::toggle_record_enable (uint32_t dstream)
|
||||
|
||||
if ((r = session->route_by_remote_id (dstream)) != 0) {
|
||||
|
||||
AudioTrack* at;
|
||||
Track* t;
|
||||
|
||||
if ((at = dynamic_cast<AudioTrack*>(r.get())) != 0) {
|
||||
at->disk_stream().set_record_enabled (!at->disk_stream().record_enabled(), this);
|
||||
if ((t = dynamic_cast<Track*>(r.get())) != 0) {
|
||||
t->diskstream().set_record_enabled (!t->diskstream().record_enabled());
|
||||
}
|
||||
}
|
||||
if (session == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2150,11 +2154,11 @@ ARDOUR_UI::halt_on_xrun_message ()
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::AudioFileSource*>* deletion_list)
|
||||
ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
|
||||
|
||||
for (list<AudioFileSource*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
|
||||
for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
|
||||
|
||||
@@ -520,7 +520,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
|
||||
sigc::connection point_one_second_connection;
|
||||
sigc::connection point_zero_one_second_connection;
|
||||
|
||||
void diskstream_added (ARDOUR::AudioDiskstream*);
|
||||
void diskstream_added (ARDOUR::Diskstream*);
|
||||
|
||||
gint session_menu (GdkEventButton *);
|
||||
|
||||
@@ -621,7 +621,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
|
||||
void toggle_record_enable (uint32_t);
|
||||
|
||||
uint32_t rec_enabled_diskstreams;
|
||||
void count_recenabled_diskstreams (ARDOUR::AudioDiskstream&);
|
||||
void count_recenabled_diskstreams (ARDOUR::Route&);
|
||||
|
||||
About* about;
|
||||
bool shown_flag;
|
||||
@@ -640,7 +640,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
|
||||
struct timeval last_peak_grab;
|
||||
struct timeval last_shuttle_request;
|
||||
|
||||
void delete_sources_in_the_right_thread (list<ARDOUR::AudioFileSource*>*);
|
||||
void delete_sources_in_the_right_thread (list<ARDOUR::Source*>*);
|
||||
|
||||
void editor_display_control_changed (Editing::DisplayControl c);
|
||||
|
||||
|
||||
@@ -76,8 +76,8 @@ ARDOUR_UI::connect_to_session (Session *s)
|
||||
rec_button.set_sensitive (true);
|
||||
shuttle_box.set_sensitive (true);
|
||||
|
||||
if (session->n_audio_diskstreams() == 0) {
|
||||
session->AudioDiskstreamAdded.connect (mem_fun(*this, &ARDOUR_UI::diskstream_added));
|
||||
if (session->n_diskstreams() == 0) {
|
||||
session->DiskstreamAdded.connect (mem_fun(*this, &ARDOUR_UI::diskstream_added));
|
||||
}
|
||||
|
||||
if (connection_editor) {
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
#include <gtkmm2ext/stop_signal.h>
|
||||
#include <cmath>
|
||||
|
||||
#include "region_editor.h"
|
||||
#include "regionview.h"
|
||||
#include "audio_region_editor.h"
|
||||
#include "audio_region_view.h"
|
||||
#include "ardour_ui.h"
|
||||
#include "utils.h"
|
||||
#include "gui_thread.h"
|
||||
@@ -37,9 +37,8 @@ using namespace PBD;
|
||||
using namespace sigc;
|
||||
using namespace std;
|
||||
|
||||
AudioRegionEditor::AudioRegionEditor (Session&s, AudioRegion& r, AudioRegionView& rv)
|
||||
: ArdourDialog ("audio region editor"),
|
||||
_session (s),
|
||||
AudioRegionEditor::AudioRegionEditor (Session& s, AudioRegion& r, AudioRegionView& rv)
|
||||
: RegionEditor (s),
|
||||
_region (r),
|
||||
_region_view (rv),
|
||||
name_label (_("NAME:")),
|
||||
@@ -18,8 +18,8 @@
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef __gtk_ardour_region_edit_h__
|
||||
#define __gtk_ardour_region_edit_h__
|
||||
#ifndef __gtk_ardour_audio_region_edit_h__
|
||||
#define __gtk_ardour_audio_region_edit_h__
|
||||
|
||||
#include <map>
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
#include "audio_clock.h"
|
||||
#include "ardour_dialog.h"
|
||||
#include "region_editor.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
class AudioRegion;
|
||||
@@ -49,14 +50,13 @@ namespace ARDOUR {
|
||||
|
||||
class AudioRegionView;
|
||||
|
||||
class AudioRegionEditor : public ArdourDialog
|
||||
class AudioRegionEditor : public RegionEditor
|
||||
{
|
||||
public:
|
||||
AudioRegionEditor (ARDOUR::Session&, ARDOUR::AudioRegion&, AudioRegionView& rv);
|
||||
~AudioRegionEditor ();
|
||||
|
||||
private:
|
||||
ARDOUR::Session& _session;
|
||||
ARDOUR::AudioRegion& _region;
|
||||
AudioRegionView& _region_view;
|
||||
|
||||
@@ -183,4 +183,4 @@ class AudioRegionEditor : public ArdourDialog
|
||||
bool spin_arrow_grab;
|
||||
};
|
||||
|
||||
#endif /* __gtk_ardour_region_edit_h__ */
|
||||
#endif /* __gtk_ardour_audio_region_edit_h__ */
|
||||
1125
gtk2_ardour/audio_region_view.cc
Normal file
1125
gtk2_ardour/audio_region_view.cc
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (C) 2001-2004 Paul Davis
|
||||
Copyright (C) 2001-2006 Paul Davis
|
||||
|
||||
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
|
||||
@@ -14,12 +14,10 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef __gtk_ardour_region_view_h__
|
||||
#define __gtk_ardour_region_view_h__
|
||||
#ifndef __gtk_ardour_audio_region_view_h__
|
||||
#define __gtk_ardour_audio_region_view_h__
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -28,6 +26,8 @@
|
||||
#include <sigc++/signal.h>
|
||||
#include <ardour/region.h>
|
||||
|
||||
#include "region_view.h"
|
||||
#include "route_time_axis.h"
|
||||
#include "time_axis_view_item.h"
|
||||
#include "automation_line.h"
|
||||
#include "enums.h"
|
||||
@@ -46,51 +46,38 @@ class AudioRegionEditor;
|
||||
class GhostRegion;
|
||||
class AutomationTimeAxisView;
|
||||
|
||||
class AudioRegionView : public TimeAxisViewItem
|
||||
class AudioRegionView : public RegionView
|
||||
{
|
||||
public:
|
||||
AudioRegionView (ArdourCanvas::Group *,
|
||||
AudioTimeAxisView&,
|
||||
RouteTimeAxisView&,
|
||||
ARDOUR::AudioRegion&,
|
||||
double initial_samples_per_unit,
|
||||
Gdk::Color& basic_color);
|
||||
|
||||
~AudioRegionView ();
|
||||
|
||||
virtual void init (double amplitude_above_axis, Gdk::Color& base_color, bool wait_for_waves);
|
||||
virtual void init (Gdk::Color& base_color, bool wait_for_data = false);
|
||||
|
||||
ARDOUR::AudioRegion& audio_region() const;
|
||||
|
||||
ARDOUR::AudioRegion& region; // ok, let 'em have it
|
||||
bool is_valid() const { return valid; }
|
||||
void set_valid (bool yn) { valid = yn; }
|
||||
|
||||
void set_height (double);
|
||||
void set_samples_per_unit (double);
|
||||
bool set_duration (jack_nframes_t, void*);
|
||||
|
||||
void set_amplitude_above_axis (gdouble spp);
|
||||
|
||||
void move (double xdelta, double ydelta);
|
||||
|
||||
void raise ();
|
||||
void raise_to_top ();
|
||||
void lower ();
|
||||
void lower_to_bottom ();
|
||||
|
||||
bool set_position(jack_nframes_t pos, void* src, double* delta = 0);
|
||||
|
||||
void temporarily_hide_envelope (); // dangerous
|
||||
void unhide_envelope (); // dangerous
|
||||
void temporarily_hide_envelope (); ///< Dangerous!
|
||||
void unhide_envelope (); ///< Dangerous!
|
||||
|
||||
void set_envelope_visible (bool);
|
||||
void set_waveform_visible (bool yn);
|
||||
void set_waveform_shape (WaveformShape);
|
||||
|
||||
bool waveform_rectified() const { return _flags & WaveformRectified; }
|
||||
bool waveform_visible() const { return _flags & WaveformVisible; }
|
||||
bool envelope_visible() const { return _flags & EnvelopeVisible; }
|
||||
bool waveform_visible() const { return _flags & WaveformVisible; }
|
||||
bool envelope_visible() const { return _flags & EnvelopeVisible; }
|
||||
|
||||
void show_region_editor ();
|
||||
void hide_region_editor();
|
||||
|
||||
void add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event);
|
||||
void remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event);
|
||||
@@ -100,19 +87,13 @@ class AudioRegionView : public TimeAxisViewItem
|
||||
void region_changed (ARDOUR::Change);
|
||||
void envelope_active_changed ();
|
||||
|
||||
static sigc::signal<void,AudioRegionView*> AudioRegionViewGoingAway;
|
||||
sigc::signal<void> GoingAway;
|
||||
|
||||
GhostRegion* add_ghost (AutomationTimeAxisView&);
|
||||
void remove_ghost (GhostRegion*);
|
||||
|
||||
void reset_fade_in_shape_width (jack_nframes_t);
|
||||
void reset_fade_out_shape_width (jack_nframes_t);
|
||||
void set_fade_in_active (bool);
|
||||
void set_fade_out_active (bool);
|
||||
|
||||
uint32_t get_fill_color ();
|
||||
|
||||
virtual void entered ();
|
||||
virtual void exited ();
|
||||
|
||||
@@ -124,44 +105,18 @@ class AudioRegionView : public TimeAxisViewItem
|
||||
*/
|
||||
|
||||
AudioRegionView (ArdourCanvas::Group *,
|
||||
AudioTimeAxisView&,
|
||||
ARDOUR::AudioRegion&,
|
||||
double initial_samples_per_unit,
|
||||
Gdk::Color& basic_color,
|
||||
TimeAxisViewItem::Visibility);
|
||||
RouteTimeAxisView&,
|
||||
ARDOUR::AudioRegion&,
|
||||
double samples_per_unit,
|
||||
Gdk::Color& basic_color,
|
||||
TimeAxisViewItem::Visibility);
|
||||
|
||||
enum Flags {
|
||||
EnvelopeVisible = 0x1,
|
||||
WaveformVisible = 0x4,
|
||||
WaveformRectified = 0x8
|
||||
};
|
||||
|
||||
vector<ArdourCanvas::WaveView *> waves; /* waveviews */
|
||||
vector<ArdourCanvas::WaveView *> tmp_waves; /* see ::create_waves()*/
|
||||
ArdourCanvas::Polygon* sync_mark; /* polgyon for sync position */
|
||||
ArdourCanvas::Text* no_wave_msg; /* text */
|
||||
ArdourCanvas::SimpleLine* zero_line; /* simpleline */
|
||||
ArdourCanvas::Polygon* fade_in_shape; /* polygon */
|
||||
ArdourCanvas::Polygon* fade_out_shape; /* polygon */
|
||||
ArdourCanvas::SimpleRect* fade_in_handle; /* simplerect */
|
||||
ArdourCanvas::SimpleRect* fade_out_handle; /* simplerect */
|
||||
|
||||
AudioRegionGainLine* gain_line;
|
||||
AudioRegionEditor *editor;
|
||||
|
||||
vector<ControlPoint *> control_points;
|
||||
double _amplitude_above_axis;
|
||||
double current_visible_sync_position;
|
||||
|
||||
uint32_t _flags;
|
||||
uint32_t fade_color;
|
||||
bool valid; /* see StreamView::redisplay_diskstream() */
|
||||
double _pixel_width;
|
||||
double _height;
|
||||
bool in_destructor;
|
||||
bool wait_for_waves;
|
||||
sigc::connection peaks_ready_connection;
|
||||
|
||||
|
||||
void reset_fade_shapes ();
|
||||
void reset_fade_in_shape ();
|
||||
void reset_fade_out_shape ();
|
||||
@@ -173,34 +128,37 @@ class AudioRegionView : public TimeAxisViewItem
|
||||
void region_resized (ARDOUR::Change);
|
||||
void region_moved (void *);
|
||||
void region_muted ();
|
||||
void region_locked ();
|
||||
void region_opacity ();
|
||||
void region_layered ();
|
||||
void region_renamed ();
|
||||
void region_sync_changed ();
|
||||
void region_scale_amplitude_changed ();
|
||||
|
||||
static gint _lock_toggle (ArdourCanvas::Item*, GdkEvent*, void*);
|
||||
void lock_toggle ();
|
||||
|
||||
void create_waves ();
|
||||
void create_one_wave (uint32_t, bool);
|
||||
void manage_zero_line ();
|
||||
void peaks_ready_handler (uint32_t);
|
||||
void reset_name (gdouble width);
|
||||
void set_flags (XMLNode *);
|
||||
void store_flags ();
|
||||
|
||||
void set_colors ();
|
||||
void compute_colors (Gdk::Color&);
|
||||
virtual void set_frame_color ();
|
||||
void reset_width_dependent_items (double pixel_width);
|
||||
void set_waveview_data_src();
|
||||
|
||||
void color_handler (ColorID, uint32_t);
|
||||
|
||||
vector<GnomeCanvasWaveViewCache*> wave_caches;
|
||||
vector<GhostRegion*> ghosts;
|
||||
|
||||
void color_handler (ColorID, uint32_t);
|
||||
vector<ArdourCanvas::WaveView *> waves;
|
||||
vector<ArdourCanvas::WaveView *> tmp_waves; ///< see ::create_waves()
|
||||
ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position
|
||||
ArdourCanvas::SimpleLine* zero_line;
|
||||
ArdourCanvas::Polygon* fade_in_shape;
|
||||
ArdourCanvas::Polygon* fade_out_shape;
|
||||
ArdourCanvas::SimpleRect* fade_in_handle;
|
||||
ArdourCanvas::SimpleRect* fade_out_handle;
|
||||
AudioRegionGainLine* gain_line;
|
||||
|
||||
double _amplitude_above_axis;
|
||||
|
||||
uint32_t _flags;
|
||||
uint32_t fade_color;
|
||||
};
|
||||
|
||||
#endif /* __gtk_ardour_region_view_h__ */
|
||||
#endif /* __gtk_ardour_audio_region_view_h__ */
|
||||
@@ -15,7 +15,7 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id$
|
||||
$Id: regionview.cc 678 2006-07-11 15:45:19Z paul $
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <ardour/audio_diskstream.h>
|
||||
|
||||
#include "streamview.h"
|
||||
#include "regionview.h"
|
||||
#include "region_view.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "simplerect.h"
|
||||
#include "simpleline.h"
|
||||
698
gtk2_ardour/audio_streamview.cc
Normal file
698
gtk2_ardour/audio_streamview.cc
Normal file
@@ -0,0 +1,698 @@
|
||||
/*
|
||||
Copyright (C) 2001, 2006 Paul Davis
|
||||
|
||||
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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
|
||||
#include <gtkmm.h>
|
||||
|
||||
#include <gtkmm2ext/gtk_ui.h>
|
||||
|
||||
#include <ardour/audioplaylist.h>
|
||||
#include <ardour/audioregion.h>
|
||||
#include <ardour/audiosource.h>
|
||||
#include <ardour/audio_diskstream.h>
|
||||
#include <ardour/audio_track.h>
|
||||
#include <ardour/playlist_templates.h>
|
||||
#include <ardour/source.h>
|
||||
|
||||
#include "audio_streamview.h"
|
||||
#include "audio_region_view.h"
|
||||
#include "tape_region_view.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "canvas-waveview.h"
|
||||
#include "canvas-simplerect.h"
|
||||
#include "region_selection.h"
|
||||
#include "selection.h"
|
||||
#include "public_editor.h"
|
||||
#include "ardour_ui.h"
|
||||
#include "crossfade_view.h"
|
||||
#include "rgb_macros.h"
|
||||
#include "gui_thread.h"
|
||||
#include "utils.h"
|
||||
#include "color.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
using namespace Editing;
|
||||
|
||||
AudioStreamView::AudioStreamView (AudioTimeAxisView& tv)
|
||||
: StreamView (tv)
|
||||
{
|
||||
crossfades_visible = true;
|
||||
|
||||
if (tv.is_audio_track())
|
||||
stream_base_color = color_map[cAudioTrackBase];
|
||||
else
|
||||
stream_base_color = color_map[cAudioBusBase];
|
||||
|
||||
canvas_rect->property_outline_color_rgba() = color_map[cAudioTrackOutline];
|
||||
|
||||
_amplitude_above_axis = 1.0;
|
||||
|
||||
use_rec_regions = tv.editor.show_waveforms_recording ();
|
||||
last_rec_peak_frame = 0;
|
||||
}
|
||||
|
||||
AudioStreamView::~AudioStreamView ()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
AudioStreamView::set_height (gdouble h)
|
||||
{
|
||||
/* limit the values to something sane-ish */
|
||||
if (h < 10.0 || h > 1000.0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
StreamView::set_height(h);
|
||||
|
||||
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
(*i)->set_height (h);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
AudioStreamView::set_samples_per_unit (gdouble spp)
|
||||
{
|
||||
StreamView::set_samples_per_unit(spp);
|
||||
|
||||
for (CrossfadeViewList::iterator xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) {
|
||||
(*xi)->set_samples_per_unit (spp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
AudioStreamView::set_amplitude_above_axis (gdouble app)
|
||||
{
|
||||
RegionViewList::iterator i;
|
||||
|
||||
if (app < 1.0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_amplitude_above_axis = app;
|
||||
|
||||
for (i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
|
||||
if (arv)
|
||||
arv->set_amplitude_above_axis (app);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::add_region_view_internal (Region *r, bool wait_for_waves)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_region_view), r));
|
||||
|
||||
AudioRegion* region = dynamic_cast<AudioRegion*> (r);
|
||||
|
||||
if (region == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
AudioRegionView *region_view;
|
||||
list<RegionView *>::iterator i;
|
||||
|
||||
for (i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
if (&(*i)->region() == r) {
|
||||
|
||||
/* great. we already have a AudioRegionView for this Region. use it again. */
|
||||
|
||||
(*i)->set_valid (true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (_trackview.audio_track()->mode()) {
|
||||
case Normal:
|
||||
region_view = new AudioRegionView (canvas_group, _trackview, *region,
|
||||
_samples_per_unit, region_color);
|
||||
break;
|
||||
case Destructive:
|
||||
region_view = new TapeAudioRegionView (canvas_group, _trackview, *region,
|
||||
_samples_per_unit, region_color);
|
||||
break;
|
||||
}
|
||||
|
||||
region_view->init (region_color, wait_for_waves);
|
||||
region_view->set_amplitude_above_axis(_amplitude_above_axis);
|
||||
region_views.push_front (region_view);
|
||||
|
||||
/* follow global waveform setting */
|
||||
|
||||
region_view->set_waveform_visible(_trackview.editor.show_waveforms());
|
||||
|
||||
/* catch regionview going away */
|
||||
|
||||
region->GoingAway.connect (mem_fun (*this, &AudioStreamView::remove_region_view));
|
||||
|
||||
RegionViewAdded (region_view);
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::remove_region_view (Region *r)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::remove_region_view), r));
|
||||
|
||||
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end();) {
|
||||
list<CrossfadeView*>::iterator tmp;
|
||||
|
||||
tmp = i;
|
||||
++tmp;
|
||||
|
||||
AudioRegion* ar = dynamic_cast<AudioRegion*>(r);
|
||||
if (ar && (*i)->crossfade.involves (*ar)) {
|
||||
delete *i;
|
||||
crossfade_views.erase (i);
|
||||
}
|
||||
|
||||
i = tmp;
|
||||
}
|
||||
|
||||
StreamView::remove_region_view(r);
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::undisplay_diskstream ()
|
||||
{
|
||||
StreamView::undisplay_diskstream();
|
||||
|
||||
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
|
||||
crossfade_views.clear ();
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::playlist_modified ()
|
||||
{
|
||||
ENSURE_GUI_THREAD (mem_fun (*this, &AudioStreamView::playlist_modified));
|
||||
|
||||
StreamView::playlist_modified();
|
||||
|
||||
/* if the playlist is modified, make sure xfades are on top and all the regionviews are stacked
|
||||
correctly.
|
||||
*/
|
||||
|
||||
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
(*i)->get_canvas_group()->raise_to_top();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::playlist_changed (Diskstream *ds)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::playlist_changed), ds));
|
||||
|
||||
StreamView::playlist_changed(ds);
|
||||
|
||||
AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(ds->playlist());
|
||||
if (apl)
|
||||
playlist_connections.push_back (apl->NewCrossfade.connect (mem_fun (*this, &AudioStreamView::add_crossfade)));
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::add_crossfade (Crossfade *crossfade)
|
||||
{
|
||||
AudioRegionView* lview = 0;
|
||||
AudioRegionView* rview = 0;
|
||||
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_crossfade), crossfade));
|
||||
|
||||
/* first see if we already have a CrossfadeView for this Crossfade */
|
||||
|
||||
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
if (&(*i)->crossfade == crossfade) {
|
||||
if (!crossfades_visible) {
|
||||
(*i)->hide();
|
||||
} else {
|
||||
(*i)->show ();
|
||||
}
|
||||
(*i)->set_valid (true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* create a new one */
|
||||
|
||||
for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*i);
|
||||
|
||||
if (!lview && arv && &(arv->region()) == &crossfade->out()) {
|
||||
lview = arv;
|
||||
}
|
||||
if (!rview && arv && &(arv->region()) == &crossfade->in()) {
|
||||
rview = arv;
|
||||
}
|
||||
}
|
||||
|
||||
CrossfadeView *cv = new CrossfadeView (_trackview.canvas_display,
|
||||
_trackview,
|
||||
*crossfade,
|
||||
_samples_per_unit,
|
||||
region_color,
|
||||
*lview, *rview);
|
||||
|
||||
crossfade->Invalidated.connect (mem_fun (*this, &AudioStreamView::remove_crossfade));
|
||||
crossfade_views.push_back (cv);
|
||||
|
||||
if (!crossfades_visible) {
|
||||
cv->hide ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::remove_crossfade (Crossfade *xfade)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::remove_crossfade), xfade));
|
||||
|
||||
for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
if (&(*i)->crossfade == xfade) {
|
||||
delete *i;
|
||||
crossfade_views.erase (i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::redisplay_diskstream ()
|
||||
{
|
||||
list<RegionView *>::iterator i, tmp;
|
||||
list<CrossfadeView*>::iterator xi, tmpx;
|
||||
|
||||
|
||||
for (i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
(*i)->set_valid (false);
|
||||
}
|
||||
|
||||
for (xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) {
|
||||
(*xi)->set_valid (false);
|
||||
if ((*xi)->visible()) {
|
||||
(*xi)->show ();
|
||||
}
|
||||
}
|
||||
|
||||
if (_trackview.is_audio_track()) {
|
||||
_trackview.get_diskstream()->playlist()->foreach_region (static_cast<StreamView*>(this), &StreamView::add_region_view);
|
||||
AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(_trackview.get_diskstream()->playlist());
|
||||
if (apl)
|
||||
apl->foreach_crossfade (this, &AudioStreamView::add_crossfade);
|
||||
}
|
||||
|
||||
for (i = region_views.begin(); i != region_views.end(); ) {
|
||||
tmp = i;
|
||||
tmp++;
|
||||
|
||||
if (!(*i)->is_valid()) {
|
||||
delete *i;
|
||||
region_views.erase (i);
|
||||
}
|
||||
|
||||
i = tmp;
|
||||
}
|
||||
|
||||
for (xi = crossfade_views.begin(); xi != crossfade_views.end();) {
|
||||
tmpx = xi;
|
||||
tmpx++;
|
||||
|
||||
if (!(*xi)->valid()) {
|
||||
delete *xi;
|
||||
crossfade_views.erase (xi);
|
||||
}
|
||||
|
||||
xi = tmpx;
|
||||
}
|
||||
|
||||
/* now fix layering */
|
||||
|
||||
playlist_modified ();
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::set_show_waveforms (bool yn)
|
||||
{
|
||||
for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
|
||||
if (arv)
|
||||
arv->set_waveform_visible (yn);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::set_waveform_shape (WaveformShape shape)
|
||||
{
|
||||
for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
|
||||
if (arv)
|
||||
arv->set_waveform_shape (shape);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::setup_rec_box ()
|
||||
{
|
||||
// cerr << _trackview.name() << " streamview SRB\n";
|
||||
|
||||
if (_trackview.session().transport_rolling()) {
|
||||
|
||||
// cerr << "\trolling\n";
|
||||
|
||||
if (!rec_active &&
|
||||
_trackview.session().record_status() == Session::Recording &&
|
||||
_trackview.get_diskstream()->record_enabled()) {
|
||||
|
||||
if (_trackview.audio_track()->mode() == Normal && use_rec_regions && rec_regions.size() == rec_rects.size()) {
|
||||
|
||||
/* add a new region, but don't bother if they set use_rec_regions mid-record */
|
||||
|
||||
AudioRegion::SourceList sources;
|
||||
|
||||
for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) {
|
||||
(*prc).disconnect();
|
||||
}
|
||||
peak_ready_connections.clear();
|
||||
|
||||
// FIXME
|
||||
AudioDiskstream* ads = dynamic_cast<AudioDiskstream*>(_trackview.get_diskstream());
|
||||
assert(ads);
|
||||
|
||||
for (uint32_t n=0; n < ads->n_channels(); ++n) {
|
||||
AudioSource *src = (AudioSource *) ads->write_source (n);
|
||||
if (src) {
|
||||
sources.push_back (src);
|
||||
peak_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), src)));
|
||||
}
|
||||
}
|
||||
|
||||
// handle multi
|
||||
|
||||
jack_nframes_t start = 0;
|
||||
if (rec_regions.size() > 0) {
|
||||
start = rec_regions.back()->start() + _trackview.get_diskstream()->get_captured_frames(rec_regions.size()-1);
|
||||
}
|
||||
|
||||
AudioRegion * region = new AudioRegion(sources, start, 1 , "", 0, (Region::Flag)(Region::DefaultFlags | Region::DoNotSaveState), false);
|
||||
region->set_position (_trackview.session().transport_frame(), this);
|
||||
rec_regions.push_back (region);
|
||||
/* catch it if it goes away */
|
||||
region->GoingAway.connect (mem_fun (*this, &AudioStreamView::remove_rec_region));
|
||||
|
||||
/* we add the region later */
|
||||
}
|
||||
|
||||
/* start a new rec box */
|
||||
|
||||
AudioTrack* at;
|
||||
|
||||
at = _trackview.audio_track(); /* we know what it is already */
|
||||
AudioDiskstream& ds = at->audio_diskstream();
|
||||
jack_nframes_t frame_pos = ds.current_capture_start ();
|
||||
gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos);
|
||||
gdouble xend;
|
||||
uint32_t fill_color;
|
||||
|
||||
switch (_trackview.audio_track()->mode()) {
|
||||
case Normal:
|
||||
xend = xstart;
|
||||
fill_color = color_map[cRecordingRectFill];
|
||||
break;
|
||||
|
||||
case Destructive:
|
||||
xend = xstart + 2;
|
||||
fill_color = color_map[cRecordingRectFill];
|
||||
/* make the recording rect translucent to allow
|
||||
the user to see the peak data coming in, etc.
|
||||
*/
|
||||
fill_color = UINT_RGBA_CHANGE_A (fill_color, 120);
|
||||
break;
|
||||
}
|
||||
|
||||
ArdourCanvas::SimpleRect * rec_rect = new Gnome::Canvas::SimpleRect (*canvas_group);
|
||||
rec_rect->property_x1() = xstart;
|
||||
rec_rect->property_y1() = 1.0;
|
||||
rec_rect->property_x2() = xend;
|
||||
rec_rect->property_y2() = (double) _trackview.height - 1;
|
||||
rec_rect->property_outline_color_rgba() = color_map[cRecordingRectOutline];
|
||||
rec_rect->property_fill_color_rgba() = fill_color;
|
||||
|
||||
RecBoxInfo recbox;
|
||||
recbox.rectangle = rec_rect;
|
||||
recbox.start = _trackview.session().transport_frame();
|
||||
recbox.length = 0;
|
||||
|
||||
rec_rects.push_back (recbox);
|
||||
|
||||
screen_update_connection.disconnect();
|
||||
screen_update_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (mem_fun (*this, &AudioStreamView::update_rec_box));
|
||||
rec_updating = true;
|
||||
rec_active = true;
|
||||
|
||||
} else if (rec_active &&
|
||||
(_trackview.session().record_status() != Session::Recording ||
|
||||
!_trackview.get_diskstream()->record_enabled())) {
|
||||
|
||||
screen_update_connection.disconnect();
|
||||
rec_active = false;
|
||||
rec_updating = false;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// cerr << "\tNOT rolling, rec_rects = " << rec_rects.size() << " rec_regions = " << rec_regions.size() << endl;
|
||||
|
||||
if (!rec_rects.empty() || !rec_regions.empty()) {
|
||||
|
||||
/* disconnect rapid update */
|
||||
screen_update_connection.disconnect();
|
||||
|
||||
for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) {
|
||||
(*prc).disconnect();
|
||||
}
|
||||
peak_ready_connections.clear();
|
||||
|
||||
rec_updating = false;
|
||||
rec_active = false;
|
||||
last_rec_peak_frame = 0;
|
||||
|
||||
/* remove temp regions */
|
||||
for (list<Region*>::iterator iter=rec_regions.begin(); iter != rec_regions.end(); )
|
||||
{
|
||||
list<Region*>::iterator tmp;
|
||||
|
||||
tmp = iter;
|
||||
++tmp;
|
||||
|
||||
/* this will trigger the remove_region_view */
|
||||
delete *iter;
|
||||
|
||||
iter = tmp;
|
||||
}
|
||||
|
||||
rec_regions.clear();
|
||||
|
||||
// cerr << "\tclear " << rec_rects.size() << " rec rects\n";
|
||||
|
||||
|
||||
/* transport stopped, clear boxes */
|
||||
for (vector<RecBoxInfo>::iterator iter=rec_rects.begin(); iter != rec_rects.end(); ++iter) {
|
||||
RecBoxInfo &rect = (*iter);
|
||||
delete rect.rectangle;
|
||||
}
|
||||
|
||||
rec_rects.clear();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::foreach_crossfadeview (void (CrossfadeView::*pmf)(void))
|
||||
{
|
||||
for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
((*i)->*pmf) ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, Source * src)
|
||||
{
|
||||
// this is called from the peak building thread
|
||||
|
||||
ENSURE_GUI_THREAD(bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), start, cnt, src));
|
||||
|
||||
if (rec_peak_ready_map.size() == 0 || start+cnt > last_rec_peak_frame) {
|
||||
last_rec_peak_frame = start + cnt;
|
||||
}
|
||||
|
||||
rec_peak_ready_map[src] = true;
|
||||
|
||||
if (rec_peak_ready_map.size() == _trackview.get_diskstream()->n_channels()) {
|
||||
this->update_rec_regions ();
|
||||
rec_peak_ready_map.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::update_rec_regions ()
|
||||
{
|
||||
if (use_rec_regions) {
|
||||
|
||||
uint32_t n = 0;
|
||||
|
||||
for (list<Region*>::iterator iter = rec_regions.begin(); iter != rec_regions.end(); n++) {
|
||||
|
||||
list<Region*>::iterator tmp;
|
||||
|
||||
tmp = iter;
|
||||
++tmp;
|
||||
|
||||
if (!canvas_item_visible (rec_rects[n].rectangle)) {
|
||||
/* rect already hidden, this region is done */
|
||||
iter = tmp;
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME
|
||||
AudioRegion * region = dynamic_cast<AudioRegion*>(*iter);
|
||||
assert(region);
|
||||
|
||||
jack_nframes_t origlen = region->length();
|
||||
|
||||
if (region == rec_regions.back() && rec_active) {
|
||||
|
||||
if (last_rec_peak_frame > region->start()) {
|
||||
|
||||
jack_nframes_t nlen = last_rec_peak_frame - region->start();
|
||||
|
||||
if (nlen != region->length()) {
|
||||
|
||||
region->freeze ();
|
||||
region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
|
||||
region->set_length (nlen, this);
|
||||
region->thaw ("updated");
|
||||
|
||||
if (origlen == 1) {
|
||||
/* our special initial length */
|
||||
add_region_view_internal (region, false);
|
||||
}
|
||||
|
||||
/* also update rect */
|
||||
ArdourCanvas::SimpleRect * rect = rec_rects[n].rectangle;
|
||||
gdouble xend = _trackview.editor.frame_to_pixel (region->position() + region->length());
|
||||
rect->property_x2() = xend;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
jack_nframes_t nlen = _trackview.get_diskstream()->get_captured_frames(n);
|
||||
|
||||
if (nlen != region->length()) {
|
||||
|
||||
if (region->source(0).length() >= region->start() + nlen) {
|
||||
|
||||
region->freeze ();
|
||||
region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
|
||||
region->set_length (nlen, this);
|
||||
region->thaw ("updated");
|
||||
|
||||
if (origlen == 1) {
|
||||
/* our special initial length */
|
||||
add_region_view_internal (region, false);
|
||||
}
|
||||
|
||||
/* also hide rect */
|
||||
ArdourCanvas::Item * rect = rec_rects[n].rectangle;
|
||||
rect->hide();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iter = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::show_all_xfades ()
|
||||
{
|
||||
foreach_crossfadeview (&CrossfadeView::show);
|
||||
crossfades_visible = true;
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::hide_all_xfades ()
|
||||
{
|
||||
foreach_crossfadeview (&CrossfadeView::hide);
|
||||
crossfades_visible = false;
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::hide_xfades_involving (AudioRegionView& rv)
|
||||
{
|
||||
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
if ((*i)->crossfade.involves (rv.audio_region())) {
|
||||
(*i)->fake_hide ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::reveal_xfades_involving (AudioRegionView& rv)
|
||||
{
|
||||
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
if ((*i)->crossfade.involves (rv.audio_region()) && (*i)->visible()) {
|
||||
(*i)->show ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamView::color_handler (ColorID id, uint32_t val)
|
||||
{
|
||||
switch (id) {
|
||||
case cAudioTrackBase:
|
||||
if (_trackview.is_audio_track()) {
|
||||
canvas_rect->property_fill_color_rgba() = val;
|
||||
}
|
||||
break;
|
||||
case cAudioBusBase:
|
||||
if (!_trackview.is_audio_track()) {
|
||||
canvas_rect->property_fill_color_rgba() = val;
|
||||
}
|
||||
break;
|
||||
case cAudioTrackOutline:
|
||||
canvas_rect->property_outline_color_rgba() = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
110
gtk2_ardour/audio_streamview.h
Normal file
110
gtk2_ardour/audio_streamview.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
Copyright (C) 2001, 2006 Paul Davis
|
||||
|
||||
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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ardour_audio_streamview_h__
|
||||
#define __ardour_audio_streamview_h__
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <cmath>
|
||||
|
||||
#include <ardour/location.h>
|
||||
#include "enums.h"
|
||||
#include "simplerect.h"
|
||||
#include "color.h"
|
||||
#include "streamview.h"
|
||||
|
||||
namespace Gdk {
|
||||
class Color;
|
||||
}
|
||||
|
||||
namespace ARDOUR {
|
||||
class Route;
|
||||
class Diskstream;
|
||||
class Crossfade;
|
||||
class PeakData;
|
||||
class AudioRegion;
|
||||
class Source;
|
||||
}
|
||||
|
||||
class PublicEditor;
|
||||
class Selectable;
|
||||
class AudioTimeAxisView;
|
||||
class AudioRegionView;
|
||||
class RegionSelection;
|
||||
class CrossfadeView;
|
||||
class Selection;
|
||||
|
||||
class AudioStreamView : public StreamView
|
||||
{
|
||||
public:
|
||||
AudioStreamView (AudioTimeAxisView&);
|
||||
~AudioStreamView ();
|
||||
|
||||
void set_waveform_shape (WaveformShape);
|
||||
|
||||
int set_height (gdouble h);
|
||||
int set_samples_per_unit (gdouble spp);
|
||||
|
||||
int set_amplitude_above_axis (gdouble app);
|
||||
gdouble get_amplitude_above_axis () { return _amplitude_above_axis; }
|
||||
|
||||
void set_show_waveforms (bool yn);
|
||||
void set_show_waveforms_recording (bool yn) { use_rec_regions = yn; }
|
||||
|
||||
void foreach_crossfadeview (void (CrossfadeView::*pmf)(void));
|
||||
|
||||
void show_all_xfades ();
|
||||
void hide_all_xfades ();
|
||||
void hide_xfades_involving (AudioRegionView&);
|
||||
void reveal_xfades_involving (AudioRegionView&);
|
||||
|
||||
private:
|
||||
void setup_rec_box ();
|
||||
void rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, ARDOUR::Source* src);
|
||||
void update_rec_regions ();
|
||||
|
||||
void add_region_view_internal (ARDOUR::Region*, bool wait_for_waves);
|
||||
void remove_region_view (ARDOUR::Region* );
|
||||
void remove_audio_region_view (ARDOUR::AudioRegion* );
|
||||
void remove_audio_rec_region (ARDOUR::AudioRegion*);
|
||||
|
||||
void undisplay_diskstream ();
|
||||
void redisplay_diskstream ();
|
||||
void playlist_modified ();
|
||||
void playlist_changed (ARDOUR::Diskstream *ds);
|
||||
|
||||
void add_crossfade (ARDOUR::Crossfade*);
|
||||
void remove_crossfade (ARDOUR::Crossfade*);
|
||||
|
||||
void color_handler (ColorID id, uint32_t val);
|
||||
|
||||
|
||||
double _amplitude_above_axis;
|
||||
|
||||
typedef list<CrossfadeView*> CrossfadeViewList;
|
||||
CrossfadeViewList crossfade_views;
|
||||
bool crossfades_visible;
|
||||
|
||||
list<sigc::connection> peak_ready_connections;
|
||||
jack_nframes_t last_rec_peak_frame;
|
||||
map<ARDOUR::Source*, bool> rec_peak_ready_map;
|
||||
|
||||
};
|
||||
|
||||
#endif /* __ardour_audio_streamview_h__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (C) 2000 Paul Davis
|
||||
Copyright (C) 2000-2006 Paul Davis
|
||||
|
||||
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
|
||||
@@ -18,8 +18,8 @@
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef __ardour_trackview_h__
|
||||
#define __ardour_trackview_h__
|
||||
#ifndef __ardour_audio_time_axis_h__
|
||||
#define __ardour_audio_time_axis_h__
|
||||
|
||||
#include <gtkmm/table.h>
|
||||
#include <gtkmm/button.h>
|
||||
@@ -33,19 +33,14 @@
|
||||
#include <list>
|
||||
|
||||
#include <ardour/types.h>
|
||||
#include <ardour/region.h>
|
||||
|
||||
#include "ardour_dialog.h"
|
||||
#include "route_ui.h"
|
||||
#include "enums.h"
|
||||
#include "time_axis_view.h"
|
||||
#include "route_time_axis.h"
|
||||
#include "canvas.h"
|
||||
#include "color.h"
|
||||
|
||||
namespace ALSA {
|
||||
class MultiChannelDevice;
|
||||
}
|
||||
|
||||
namespace ARDOUR {
|
||||
class Session;
|
||||
class AudioDiskstream;
|
||||
@@ -56,247 +51,58 @@ namespace ARDOUR {
|
||||
class AudioPlaylist;
|
||||
}
|
||||
|
||||
namespace LADSPA {
|
||||
class Manager;
|
||||
class Plugin;
|
||||
}
|
||||
|
||||
class PublicEditor;
|
||||
class AudioThing;
|
||||
class StreamView;
|
||||
class AudioStreamView;
|
||||
class Selection;
|
||||
class Selectable;
|
||||
class RegionView;
|
||||
class AudioRegionView;
|
||||
class AutomationLine;
|
||||
class AutomationGainLine;
|
||||
class AutomationPanLine;
|
||||
class RedirectAutomationLine;
|
||||
class TimeSelection;
|
||||
class AutomationTimeAxisView;
|
||||
|
||||
class AudioTimeAxisView : public RouteUI, public TimeAxisView
|
||||
class AudioTimeAxisView : public RouteTimeAxisView
|
||||
{
|
||||
public:
|
||||
AudioTimeAxisView (PublicEditor&, ARDOUR::Session&, boost::shared_ptr<ARDOUR::Route>, ArdourCanvas::Canvas& canvas);
|
||||
virtual ~AudioTimeAxisView ();
|
||||
|
||||
AudioStreamView* audio_view();
|
||||
|
||||
void show_selection (TimeSelection&);
|
||||
void automation_control_point_changed (ARDOUR::AutomationType);
|
||||
|
||||
void set_samples_per_unit (double);
|
||||
void set_height (TimeAxisView::TrackHeight);
|
||||
void set_show_waveforms (bool yn);
|
||||
void set_show_waveforms_recording (bool yn);
|
||||
void show_timestretch (jack_nframes_t start, jack_nframes_t end);
|
||||
void hide_timestretch ();
|
||||
void selection_click (GdkEventButton*);
|
||||
void set_selected_regionviews (AudioRegionSelection&);
|
||||
void set_selected_points (PointSelection&);
|
||||
void get_selectables (jack_nframes_t start, jack_nframes_t end, double top, double bot, list<Selectable *>&);
|
||||
void get_inverted_selectables (Selection&, list<Selectable*>&);
|
||||
void show_all_xfades ();
|
||||
void hide_all_xfades ();
|
||||
void hide_dependent_views (TimeAxisViewItem&);
|
||||
void reveal_dependent_views (TimeAxisViewItem&);
|
||||
|
||||
ARDOUR::Region* find_next_region (jack_nframes_t pos, ARDOUR::RegionPoint, int32_t dir);
|
||||
|
||||
string name() const;
|
||||
|
||||
ARDOUR::RouteGroup* edit_group() const;
|
||||
|
||||
void build_playlist_menu (Gtk::Menu *);
|
||||
ARDOUR::Playlist* playlist() const;
|
||||
|
||||
/* overridden from parent to store display state */
|
||||
/* Overridden from parent to store display state */
|
||||
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
|
||||
void hide ();
|
||||
|
||||
/* need accessors/mutators */
|
||||
|
||||
StreamView *view;
|
||||
|
||||
/* editing operations */
|
||||
|
||||
bool cut_copy_clear (Selection&, Editing::CutCopyOp);
|
||||
bool paste (jack_nframes_t, float times, Selection&, size_t nth);
|
||||
|
||||
list<TimeAxisView*>get_child_list();
|
||||
|
||||
void set_state (const XMLNode&);
|
||||
XMLNode* get_child_xml_node (const string & childname);
|
||||
|
||||
/* the editor calls these when mapping an operation across multiple tracks */
|
||||
|
||||
void use_new_playlist (bool prompt);
|
||||
void use_copy_playlist (bool prompt);
|
||||
void clear_playlist ();
|
||||
|
||||
private:
|
||||
friend class StreamView;
|
||||
friend class AudioStreamView;
|
||||
friend class AudioRegionView;
|
||||
|
||||
ArdourCanvas::Canvas& parent_canvas;
|
||||
|
||||
bool no_redraw;
|
||||
|
||||
AutomationTimeAxisView *gain_track;
|
||||
AutomationTimeAxisView *pan_track;
|
||||
|
||||
void update_automation_view (ARDOUR::AutomationType);
|
||||
void reset_redirect_automation_curves ();
|
||||
|
||||
Gtk::HBox other_button_hbox;
|
||||
|
||||
Gtk::Table button_table;
|
||||
|
||||
Gtk::Button redirect_button;
|
||||
Gtk::Button edit_group_button;
|
||||
Gtk::Button playlist_button;
|
||||
Gtk::Button size_button;
|
||||
Gtk::Button automation_button;
|
||||
Gtk::Button hide_button;
|
||||
Gtk::Button visual_button;
|
||||
|
||||
|
||||
void route_active_changed ();
|
||||
|
||||
void diskstream_changed (void *src);
|
||||
void update_diskstream_display ();
|
||||
void build_automation_action_menu ();
|
||||
void append_extra_display_menu_items ();
|
||||
|
||||
gint edit_click (GdkEventButton *);
|
||||
|
||||
// variables to get the context menu
|
||||
// automation buttons correctly initialized
|
||||
bool show_gain_automation;
|
||||
bool show_pan_automation;
|
||||
|
||||
void build_redirect_window ();
|
||||
void redirect_click ();
|
||||
void redirect_add ();
|
||||
void redirect_remove ();
|
||||
void redirect_edit ();
|
||||
void redirect_relist ();
|
||||
void redirect_row_selected (gint row, gint col, GdkEvent *ev);
|
||||
void add_to_redirect_display (boost::shared_ptr<ARDOUR::Redirect>);
|
||||
void redirects_changed (void *);
|
||||
|
||||
sigc::connection modified_connection;
|
||||
sigc::connection state_changed_connection;
|
||||
|
||||
void take_name_changed (void *);
|
||||
void route_name_changed (void *);
|
||||
void name_entry_changed ();
|
||||
|
||||
void on_area_realize ();
|
||||
|
||||
virtual void label_view ();
|
||||
|
||||
Gtk::Menu edit_group_menu;
|
||||
|
||||
void add_edit_group_menu_item (ARDOUR::RouteGroup *, Gtk::RadioMenuItem::Group*);
|
||||
void set_edit_group_from_menu (ARDOUR::RouteGroup *);
|
||||
|
||||
void reset_samples_per_unit ();
|
||||
|
||||
void select_track_color();
|
||||
|
||||
virtual void build_display_menu ();
|
||||
|
||||
Gtk::CheckMenuItem* waveform_item;
|
||||
Gtk::RadioMenuItem* traditional_item;
|
||||
Gtk::RadioMenuItem* rectified_item;
|
||||
|
||||
Gtk::RadioMenuItem* align_existing_item;
|
||||
Gtk::RadioMenuItem* align_capture_item;
|
||||
|
||||
void align_style_changed ();
|
||||
void set_align_style (ARDOUR::AlignStyle);
|
||||
|
||||
void toggle_show_waveforms ();
|
||||
|
||||
void set_waveform_shape (WaveformShape);
|
||||
void toggle_waveforms ();
|
||||
|
||||
Gtk::Menu *playlist_menu;
|
||||
Gtk::Menu *playlist_action_menu;
|
||||
Gtk::MenuItem *playlist_item;
|
||||
|
||||
/* playlist */
|
||||
|
||||
void set_playlist (ARDOUR::AudioPlaylist *);
|
||||
void playlist_click ();
|
||||
void show_playlist_selector ();
|
||||
|
||||
void playlist_changed ();
|
||||
void playlist_state_changed (ARDOUR::Change);
|
||||
void playlist_modified ();
|
||||
|
||||
void add_playlist_to_playlist_menu (ARDOUR::Playlist*);
|
||||
void rename_current_playlist ();
|
||||
|
||||
/* automation stuff */
|
||||
|
||||
Gtk::Menu* automation_action_menu;
|
||||
Gtk::CheckMenuItem* gain_automation_item;
|
||||
Gtk::CheckMenuItem* pan_automation_item;
|
||||
|
||||
void automation_click ();
|
||||
void clear_automation ();
|
||||
void hide_all_automation ();
|
||||
void show_all_automation ();
|
||||
void show_existing_automation ();
|
||||
void hide_all_automation ();
|
||||
|
||||
struct RedirectAutomationNode {
|
||||
uint32_t what;
|
||||
Gtk::CheckMenuItem* menu_item;
|
||||
AutomationTimeAxisView* view;
|
||||
AudioTimeAxisView& parent;
|
||||
|
||||
RedirectAutomationNode (uint32_t w, Gtk::CheckMenuItem* mitem, AudioTimeAxisView& p)
|
||||
: what (w), menu_item (mitem), view (0), parent (p) {}
|
||||
|
||||
~RedirectAutomationNode ();
|
||||
};
|
||||
|
||||
struct RedirectAutomationInfo {
|
||||
boost::shared_ptr<ARDOUR::Redirect> redirect;
|
||||
bool valid;
|
||||
Gtk::Menu* menu;
|
||||
vector<RedirectAutomationNode*> lines;
|
||||
|
||||
RedirectAutomationInfo (boost::shared_ptr<ARDOUR::Redirect> r)
|
||||
: redirect (r), valid (true) {}
|
||||
|
||||
~RedirectAutomationInfo ();
|
||||
};
|
||||
|
||||
list<RedirectAutomationInfo*> redirect_automation;
|
||||
RedirectAutomationNode* find_redirect_automation_node (boost::shared_ptr<ARDOUR::Redirect> redirect, uint32_t what);
|
||||
|
||||
Gtk::Menu subplugin_menu;
|
||||
void add_redirect_to_subplugin_menu (boost::shared_ptr<ARDOUR::Redirect>);
|
||||
|
||||
void remove_ran (RedirectAutomationNode* ran);
|
||||
|
||||
void redirect_menu_item_toggled (AudioTimeAxisView::RedirectAutomationInfo*,
|
||||
AudioTimeAxisView::RedirectAutomationNode*);
|
||||
void redirect_automation_track_hidden (RedirectAutomationNode*, boost::shared_ptr<ARDOUR::Redirect>);
|
||||
|
||||
vector<RedirectAutomationLine*> redirect_automation_curves;
|
||||
RedirectAutomationLine *find_redirect_automation_curve (boost::shared_ptr<ARDOUR::Redirect>,uint32_t);
|
||||
void add_redirect_automation_curve (boost::shared_ptr<ARDOUR::Redirect>, uint32_t);
|
||||
void add_existing_redirect_automation_curves (boost::shared_ptr<ARDOUR::Redirect>);
|
||||
|
||||
ArdourCanvas::SimpleRect *timestretch_rect;
|
||||
|
||||
void timestretch (jack_nframes_t start, jack_nframes_t end);
|
||||
|
||||
void visual_click ();
|
||||
void hide_click ();
|
||||
gint when_displayed (GdkEventAny*);
|
||||
|
||||
void speed_changed ();
|
||||
|
||||
void add_gain_automation_child ();
|
||||
void add_pan_automation_child ();
|
||||
void add_parameter_automation_child ();
|
||||
@@ -309,14 +115,19 @@ class AudioTimeAxisView : public RouteUI, public TimeAxisView
|
||||
|
||||
void update_pans ();
|
||||
|
||||
void region_view_added (AudioRegionView*);
|
||||
void add_ghost_to_redirect (AudioRegionView*, AutomationTimeAxisView*);
|
||||
AutomationTimeAxisView* gain_track;
|
||||
AutomationTimeAxisView* pan_track;
|
||||
|
||||
void map_frozen ();
|
||||
|
||||
void color_handler (ColorID, uint32_t);
|
||||
bool select_me (GdkEventButton*);
|
||||
// Set from XML so context menu automation buttons can be correctly initialized
|
||||
bool show_gain_automation;
|
||||
bool show_pan_automation;
|
||||
|
||||
Gtk::CheckMenuItem* waveform_item;
|
||||
Gtk::RadioMenuItem* traditional_item;
|
||||
Gtk::RadioMenuItem* rectified_item;
|
||||
Gtk::CheckMenuItem* gain_automation_item;
|
||||
Gtk::CheckMenuItem* pan_automation_item;
|
||||
};
|
||||
|
||||
#endif /* __ardour_trackview_h__ */
|
||||
#endif /* __ardour_audio_time_axis_h__ */
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace ARDOUR {
|
||||
|
||||
class PublicEditor;
|
||||
class TimeSelection;
|
||||
class AudioRegionSelection;
|
||||
class RegionSelection;
|
||||
class PointSelection;
|
||||
class AutomationLine;
|
||||
class GhostRegion;
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "rgb_macros.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "public_editor.h"
|
||||
#include "regionview.h"
|
||||
#include "audio_region_view.h"
|
||||
#include "utils.h"
|
||||
#include "canvas_impl.h"
|
||||
|
||||
@@ -43,7 +43,7 @@ using namespace Canvas;
|
||||
sigc::signal<void,CrossfadeView*> CrossfadeView::GoingAway;
|
||||
|
||||
CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent,
|
||||
AudioTimeAxisView &tv,
|
||||
RouteTimeAxisView &tv,
|
||||
Crossfade& xf,
|
||||
double spu,
|
||||
Gdk::Color& basic_color,
|
||||
@@ -227,7 +227,7 @@ CrossfadeView::set_valid (bool yn)
|
||||
AudioRegionView&
|
||||
CrossfadeView::upper_regionview () const
|
||||
{
|
||||
if (left_view.region.layer() > right_view.region.layer()) {
|
||||
if (left_view.region().layer() > right_view.region().layer()) {
|
||||
return left_view;
|
||||
} else {
|
||||
return right_view;
|
||||
|
||||
@@ -28,13 +28,13 @@
|
||||
|
||||
#include "time_axis_view_item.h"
|
||||
|
||||
class AudioTimeAxisView;
|
||||
class RouteTimeAxisView;
|
||||
class AudioRegionView;
|
||||
|
||||
struct CrossfadeView : public TimeAxisViewItem
|
||||
{
|
||||
CrossfadeView (ArdourCanvas::Group*,
|
||||
AudioTimeAxisView&,
|
||||
RouteTimeAxisView&,
|
||||
ARDOUR::Crossfade&,
|
||||
double initial_samples_per_unit,
|
||||
Gdk::Color& basic_color,
|
||||
|
||||
@@ -56,10 +56,10 @@
|
||||
#include "keyboard.h"
|
||||
#include "marker.h"
|
||||
#include "playlist_selector.h"
|
||||
#include "regionview.h"
|
||||
#include "audio_region_view.h"
|
||||
#include "rgb_macros.h"
|
||||
#include "selection.h"
|
||||
#include "streamview.h"
|
||||
#include "audio_streamview.h"
|
||||
#include "time_axis_view.h"
|
||||
#include "utils.h"
|
||||
#include "crossfade_view.h"
|
||||
@@ -101,8 +101,8 @@ static const int32_t slide_index = 0;
|
||||
static const int32_t splice_index = 1;
|
||||
|
||||
static const gchar *edit_mode_strings[] = {
|
||||
N_("Slide"),
|
||||
N_("Splice"),
|
||||
N_("Slide Edit"),
|
||||
N_("Splice Edit"),
|
||||
0
|
||||
};
|
||||
|
||||
@@ -131,17 +131,17 @@ static const gchar *snap_type_strings[] = {
|
||||
};
|
||||
|
||||
static const gchar *snap_mode_strings[] = {
|
||||
N_("Normal"),
|
||||
N_("Magnetic"),
|
||||
N_("Normal Snap"),
|
||||
N_("Magnetic Snap"),
|
||||
0
|
||||
};
|
||||
|
||||
static const gchar *zoom_focus_strings[] = {
|
||||
N_("Left"),
|
||||
N_("Right"),
|
||||
N_("Center"),
|
||||
N_("Playhead"),
|
||||
N_("Edit Cursor"),
|
||||
N_("Focus Left"),
|
||||
N_("Focus Right"),
|
||||
N_("Focus Center"),
|
||||
N_("Focus Play"),
|
||||
N_("Focus Edit"),
|
||||
0
|
||||
};
|
||||
|
||||
@@ -204,37 +204,20 @@ Editor::Editor (AudioEngine& eng)
|
||||
|
||||
/* tool bar related */
|
||||
|
||||
selection_start_clock (X_("SelectionStartClock"), true),
|
||||
selection_end_clock (X_("SelectionEndClock"), true),
|
||||
edit_cursor_clock (X_("EditCursorClock"), true),
|
||||
zoom_range_clock (X_("ZoomRangeClock"), true, true),
|
||||
|
||||
toolbar_selection_clock_table (2,3),
|
||||
|
||||
mouse_mode_button_table (2, 3),
|
||||
|
||||
mouse_select_button (_("range")),
|
||||
mouse_move_button (_("object")),
|
||||
mouse_gain_button (_("gain")),
|
||||
mouse_zoom_button (_("zoom")),
|
||||
mouse_timefx_button (_("timefx")),
|
||||
mouse_audition_button (_("listen")),
|
||||
|
||||
automation_mode_button (_("mode")),
|
||||
global_automation_button (_("automation")),
|
||||
|
||||
edit_mode_label (_("Edit Mode")),
|
||||
snap_type_label (_("Snap To")),
|
||||
snap_mode_label(_("Snap Mode")),
|
||||
zoom_focus_label (_("Zoom Focus")),
|
||||
|
||||
/* <CMT Additions> */
|
||||
image_socket_listener(0),
|
||||
/* </CMT Additions> */
|
||||
|
||||
/* nudge */
|
||||
|
||||
nudge_label (_("Nudge")),
|
||||
nudge_clock (X_("NudgeClock"), true, true)
|
||||
|
||||
{
|
||||
@@ -345,6 +328,7 @@ Editor::Editor (AudioEngine& eng)
|
||||
reset_hscrollbar_stepping ();
|
||||
|
||||
zoom_focus = ZoomFocusLeft;
|
||||
set_zoom_focus (ZoomFocusLeft);
|
||||
zoom_range_clock.ValueChanged.connect (mem_fun(*this, &Editor::zoom_adjustment_changed));
|
||||
|
||||
initialize_rulers ();
|
||||
@@ -465,36 +449,7 @@ Editor::Editor (AudioEngine& eng)
|
||||
|
||||
edit_packer.attach (edit_hscrollbar, 2, 3, 2, 3, FILL|EXPAND, FILL, 0, 0);
|
||||
|
||||
zoom_in_button.set_name ("EditorTimeButton");
|
||||
zoom_out_button.set_name ("EditorTimeButton");
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (zoom_in_button, _("Zoom in"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_button, _("Zoom out"));
|
||||
|
||||
zoom_out_full_button.set_name ("EditorTimeButton");
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_full_button, _("Zoom to session"));
|
||||
|
||||
zoom_in_button.add (*(manage (new Image (Stock::ZOOM_IN, ICON_SIZE_BUTTON))));
|
||||
zoom_out_button.add (*(manage (new Image (Stock::ZOOM_OUT, ICON_SIZE_BUTTON))));
|
||||
zoom_out_full_button.add (*(manage (new Image (Stock::ZOOM_FIT, ICON_SIZE_BUTTON))));
|
||||
|
||||
zoom_in_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), false));
|
||||
zoom_out_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), true));
|
||||
zoom_out_full_button.signal_clicked().connect (mem_fun(*this, &Editor::temporal_zoom_session));
|
||||
|
||||
zoom_indicator_box.pack_start (zoom_out_button, false, false);
|
||||
zoom_indicator_box.pack_start (zoom_in_button, false, false);
|
||||
zoom_indicator_box.pack_start (zoom_range_clock, false, false);
|
||||
zoom_indicator_box.pack_start (zoom_out_full_button, false, false);
|
||||
|
||||
zoom_indicator_label.set_text (_("Zoom Span"));
|
||||
zoom_indicator_label.set_name ("ToolBarLabel");
|
||||
|
||||
zoom_indicator_vbox.set_spacing (3);
|
||||
zoom_indicator_vbox.set_border_width (3);
|
||||
zoom_indicator_vbox.pack_start (zoom_indicator_label, false, false);
|
||||
zoom_indicator_vbox.pack_start (zoom_indicator_box, false, false);
|
||||
|
||||
bottom_hbox.set_border_width (3);
|
||||
bottom_hbox.set_border_width (2);
|
||||
bottom_hbox.set_spacing (3);
|
||||
|
||||
route_display_model = ListStore::create(route_display_columns);
|
||||
@@ -717,15 +672,15 @@ Editor::Editor (AudioEngine& eng)
|
||||
_playlist_selector = new PlaylistSelector();
|
||||
_playlist_selector->signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), static_cast<Window *> (_playlist_selector)));
|
||||
|
||||
AudioRegionView::AudioRegionViewGoingAway.connect (mem_fun(*this, &Editor::catch_vanishing_audio_regionview));
|
||||
RegionView::RegionViewGoingAway.connect (mem_fun(*this, &Editor::catch_vanishing_regionview));
|
||||
|
||||
/* nudge stuff */
|
||||
|
||||
nudge_forward_button.add (*(manage (new Image (get_xpm("right_arrow.xpm")))));
|
||||
nudge_backward_button.add (*(manage (new Image (get_xpm("left_arrow.xpm")))));
|
||||
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (nudge_forward_button, _("Nudge region/selection forwards"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (nudge_backward_button, _("Nudge region/selection backwards"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (nudge_forward_button, _("Nudge Region/Selection Forwards"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (nudge_backward_button, _("Nudge Region/Selection Backwards"));
|
||||
|
||||
nudge_forward_button.set_name ("TransportButton");
|
||||
nudge_backward_button.set_name ("TransportButton");
|
||||
@@ -775,7 +730,7 @@ Editor::add_toplevel_controls (Container& cont)
|
||||
}
|
||||
|
||||
void
|
||||
Editor::catch_vanishing_audio_regionview (AudioRegionView *rv)
|
||||
Editor::catch_vanishing_regionview (RegionView *rv)
|
||||
{
|
||||
/* note: the selection will take care of the vanishing
|
||||
audioregionview by itself.
|
||||
@@ -791,7 +746,7 @@ Editor::catch_vanishing_audio_regionview (AudioRegionView *rv)
|
||||
}
|
||||
|
||||
void
|
||||
Editor::set_entered_regionview (AudioRegionView* rv)
|
||||
Editor::set_entered_regionview (RegionView* rv)
|
||||
{
|
||||
if (rv == entered_regionview) {
|
||||
return;
|
||||
@@ -1221,7 +1176,7 @@ Editor::connect_to_session (Session *t)
|
||||
|
||||
session_connections.push_back (session->TransportStateChange.connect (mem_fun(*this, &Editor::map_transport_state)));
|
||||
session_connections.push_back (session->PositionChanged.connect (mem_fun(*this, &Editor::map_position_change)));
|
||||
session_connections.push_back (session->RouteAdded.connect (mem_fun(*this, &Editor::handle_new_route_p)));
|
||||
session_connections.push_back (session->RouteAdded.connect (mem_fun(*this, &Editor::handle_new_route)));
|
||||
session_connections.push_back (session->AudioRegionAdded.connect (mem_fun(*this, &Editor::handle_new_audio_region)));
|
||||
session_connections.push_back (session->AudioRegionRemoved.connect (mem_fun(*this, &Editor::handle_audio_region_removed)));
|
||||
session_connections.push_back (session->DurationChanged.connect (mem_fun(*this, &Editor::handle_new_duration)));
|
||||
@@ -1242,8 +1197,6 @@ Editor::connect_to_session (Session *t)
|
||||
edit_groups_changed ();
|
||||
|
||||
edit_cursor_clock.set_session (session);
|
||||
selection_start_clock.set_session (session);
|
||||
selection_end_clock.set_session (session);
|
||||
zoom_range_clock.set_session (session);
|
||||
_playlist_selector->set_session (session);
|
||||
nudge_clock.set_session (session);
|
||||
@@ -1447,7 +1400,7 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i
|
||||
switch (item_type) {
|
||||
case FadeInItem:
|
||||
case FadeInHandleItem:
|
||||
if (arv->region.fade_in_active()) {
|
||||
if (arv->audio_region().fade_in_active()) {
|
||||
items.push_back (MenuElem (_("Deactivate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_active), false)));
|
||||
} else {
|
||||
items.push_back (MenuElem (_("Activate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_active), true)));
|
||||
@@ -1455,16 +1408,16 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i
|
||||
|
||||
items.push_back (SeparatorElem());
|
||||
|
||||
items.push_back (MenuElem (_("Linear"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::Linear)));
|
||||
items.push_back (MenuElem (_("Slowest"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::LogB)));
|
||||
items.push_back (MenuElem (_("Slow"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::Fast)));
|
||||
items.push_back (MenuElem (_("Fast"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::LogA)));
|
||||
items.push_back (MenuElem (_("Fastest"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::Slow)));
|
||||
items.push_back (MenuElem (_("Linear"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::Linear)));
|
||||
items.push_back (MenuElem (_("Slowest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::LogB)));
|
||||
items.push_back (MenuElem (_("Slow"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::Fast)));
|
||||
items.push_back (MenuElem (_("Fast"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::LogA)));
|
||||
items.push_back (MenuElem (_("Fastest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::Slow)));
|
||||
break;
|
||||
|
||||
case FadeOutItem:
|
||||
case FadeOutHandleItem:
|
||||
if (arv->region.fade_out_active()) {
|
||||
if (arv->audio_region().fade_out_active()) {
|
||||
items.push_back (MenuElem (_("Deactivate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_active), false)));
|
||||
} else {
|
||||
items.push_back (MenuElem (_("Activate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_active), true)));
|
||||
@@ -1472,11 +1425,11 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i
|
||||
|
||||
items.push_back (SeparatorElem());
|
||||
|
||||
items.push_back (MenuElem (_("Linear"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::Linear)));
|
||||
items.push_back (MenuElem (_("Slowest"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::Fast)));
|
||||
items.push_back (MenuElem (_("Slow"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::LogB)));
|
||||
items.push_back (MenuElem (_("Fast"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::LogA)));
|
||||
items.push_back (MenuElem (_("Fastest"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::Slow)));
|
||||
items.push_back (MenuElem (_("Linear"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::Linear)));
|
||||
items.push_back (MenuElem (_("Slowest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::Fast)));
|
||||
items.push_back (MenuElem (_("Slow"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::LogB)));
|
||||
items.push_back (MenuElem (_("Fast"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::LogA)));
|
||||
items.push_back (MenuElem (_("Fastest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::Slow)));
|
||||
|
||||
break;
|
||||
default:
|
||||
@@ -1498,8 +1451,8 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type,
|
||||
|
||||
switch (item_type) {
|
||||
case RegionItem:
|
||||
case AudioRegionViewName:
|
||||
case AudioRegionViewNameHighlight:
|
||||
case RegionViewName:
|
||||
case RegionViewNameHighlight:
|
||||
if (with_selection) {
|
||||
build_menu_function = &Editor::build_track_selection_context_menu;
|
||||
} else {
|
||||
@@ -1539,25 +1492,26 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type,
|
||||
|
||||
switch (item_type) {
|
||||
case RegionItem:
|
||||
case AudioRegionViewName:
|
||||
case AudioRegionViewNameHighlight:
|
||||
case RegionViewName:
|
||||
case RegionViewNameHighlight:
|
||||
if (!with_selection) {
|
||||
if (region_edit_menu_split_item) {
|
||||
if (clicked_regionview && clicked_regionview->region.covers (edit_cursor->current_frame)) {
|
||||
if (clicked_regionview && clicked_regionview->region().covers (edit_cursor->current_frame)) {
|
||||
ActionManager::set_sensitive (ActionManager::edit_cursor_in_region_sensitive_actions, true);
|
||||
} else {
|
||||
ActionManager::set_sensitive (ActionManager::edit_cursor_in_region_sensitive_actions, false);
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (region_edit_menu_split_multichannel_item) {
|
||||
if (clicked_regionview && clicked_regionview->region.n_channels() > 1) {
|
||||
if (clicked_regionview && clicked_regionview->region().n_channels() > 1) {
|
||||
// GTK2FIX find the action, change its sensitivity
|
||||
// region_edit_menu_split_multichannel_item->set_sensitive (true);
|
||||
} else {
|
||||
// GTK2FIX see above
|
||||
// region_edit_menu_split_multichannel_item->set_sensitive (false);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1637,13 +1591,13 @@ Editor::build_track_region_context_menu (jack_nframes_t frame)
|
||||
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_trackview);
|
||||
|
||||
if (atv) {
|
||||
AudioDiskstream* ds;
|
||||
Diskstream* ds;
|
||||
Playlist* pl;
|
||||
|
||||
if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
|
||||
Playlist::RegionList* regions = pl->regions_at ((jack_nframes_t) floor ( (double)frame * ds->speed()));
|
||||
for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
|
||||
add_region_context_items (atv->view, (*i), edit_items);
|
||||
add_region_context_items (atv->audio_view(), (*i), edit_items);
|
||||
}
|
||||
delete regions;
|
||||
}
|
||||
@@ -1664,7 +1618,7 @@ Editor::build_track_crossfade_context_menu (jack_nframes_t frame)
|
||||
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_trackview);
|
||||
|
||||
if (atv) {
|
||||
AudioDiskstream* ds;
|
||||
Diskstream* ds;
|
||||
Playlist* pl;
|
||||
AudioPlaylist* apl;
|
||||
|
||||
@@ -1678,11 +1632,11 @@ Editor::build_track_crossfade_context_menu (jack_nframes_t frame)
|
||||
bool many = xfades.size() > 1;
|
||||
|
||||
for (AudioPlaylist::Crossfades::iterator i = xfades.begin(); i != xfades.end(); ++i) {
|
||||
add_crossfade_context_items (atv->view, (*i), edit_items, many);
|
||||
add_crossfade_context_items (atv->audio_view(), (*i), edit_items, many);
|
||||
}
|
||||
|
||||
for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
|
||||
add_region_context_items (atv->view, (*i), edit_items);
|
||||
add_region_context_items (atv->audio_view(), (*i), edit_items);
|
||||
}
|
||||
|
||||
delete regions;
|
||||
@@ -1748,7 +1702,7 @@ Editor::build_track_selection_context_menu (jack_nframes_t ignored)
|
||||
}
|
||||
|
||||
void
|
||||
Editor::add_crossfade_context_items (StreamView* view, Crossfade* xfade, Menu_Helpers::MenuList& edit_items, bool many)
|
||||
Editor::add_crossfade_context_items (AudioStreamView* view, Crossfade* xfade, Menu_Helpers::MenuList& edit_items, bool many)
|
||||
{
|
||||
using namespace Menu_Helpers;
|
||||
Menu *xfade_menu = manage (new Menu);
|
||||
@@ -1805,7 +1759,7 @@ Editor::xfade_edit_right_region ()
|
||||
}
|
||||
|
||||
void
|
||||
Editor::add_region_context_items (StreamView* sv, Region* region, Menu_Helpers::MenuList& edit_items)
|
||||
Editor::add_region_context_items (AudioStreamView* sv, Region* region, Menu_Helpers::MenuList& edit_items)
|
||||
{
|
||||
using namespace Menu_Helpers;
|
||||
Menu *region_menu = manage (new Menu);
|
||||
@@ -2584,30 +2538,56 @@ void
|
||||
Editor::setup_toolbar ()
|
||||
{
|
||||
string pixmap_path;
|
||||
|
||||
const guint32 FUDGE = 18; // Combo's are stupid - they steal space from the entry for the button
|
||||
|
||||
|
||||
/* Mode Buttons (tool selection) */
|
||||
|
||||
vector<ToggleButton *> mouse_mode_buttons;
|
||||
|
||||
mouse_move_button.add (*(manage (new Image (get_xpm("tool_object.xpm")))));
|
||||
mouse_move_button.set_relief(Gtk::RELIEF_NONE);
|
||||
mouse_mode_buttons.push_back (&mouse_move_button);
|
||||
mouse_select_button.add (*(manage (new Image (get_xpm("tool_range.xpm")))));
|
||||
mouse_select_button.set_relief(Gtk::RELIEF_NONE);
|
||||
mouse_mode_buttons.push_back (&mouse_select_button);
|
||||
mouse_gain_button.add (*(manage (new Image (get_xpm("tool_gain.xpm")))));
|
||||
mouse_gain_button.set_relief(Gtk::RELIEF_NONE);
|
||||
mouse_mode_buttons.push_back (&mouse_gain_button);
|
||||
mouse_zoom_button.add (*(manage (new Image (get_xpm("tool_zoom.xpm")))));
|
||||
mouse_zoom_button.set_relief(Gtk::RELIEF_NONE);
|
||||
mouse_mode_buttons.push_back (&mouse_zoom_button);
|
||||
mouse_timefx_button.add (*(manage (new Image (get_xpm("tool_stretch.xpm")))));
|
||||
mouse_timefx_button.set_relief(Gtk::RELIEF_NONE);
|
||||
mouse_mode_buttons.push_back (&mouse_timefx_button);
|
||||
mouse_audition_button.add (*(manage (new Image (get_xpm("tool_audition.xpm")))));
|
||||
mouse_audition_button.set_relief(Gtk::RELIEF_NONE);
|
||||
mouse_mode_buttons.push_back (&mouse_audition_button);
|
||||
|
||||
mouse_mode_button_set = new GroupedButtons (mouse_mode_buttons);
|
||||
|
||||
mouse_mode_button_table.set_homogeneous (true);
|
||||
mouse_mode_button_table.set_col_spacings (2);
|
||||
mouse_mode_button_table.set_row_spacings (2);
|
||||
mouse_mode_button_table.set_border_width (5);
|
||||
HBox* mode_box = manage(new HBox);
|
||||
mode_box->set_border_width (2);
|
||||
mode_box->set_spacing(4);
|
||||
mouse_mode_button_box.set_spacing(1);
|
||||
mouse_mode_button_box.pack_start(mouse_move_button, true, true);
|
||||
mouse_mode_button_box.pack_start(mouse_select_button, true, true);
|
||||
mouse_mode_button_box.pack_start(mouse_zoom_button, true, true);
|
||||
mouse_mode_button_box.pack_start(mouse_gain_button, true, true);
|
||||
mouse_mode_button_box.pack_start(mouse_timefx_button, true, true);
|
||||
mouse_mode_button_box.pack_start(mouse_audition_button, true, true);
|
||||
mouse_mode_button_box.set_homogeneous(true);
|
||||
|
||||
mouse_mode_button_table.attach (mouse_move_button, 0, 1, 0, 1);
|
||||
mouse_mode_button_table.attach (mouse_select_button, 1, 2, 0, 1);
|
||||
mouse_mode_button_table.attach (mouse_zoom_button, 2, 3, 0, 1);
|
||||
|
||||
mouse_mode_button_table.attach (mouse_gain_button, 0, 1, 1, 2);
|
||||
mouse_mode_button_table.attach (mouse_timefx_button, 1, 2, 1, 2);
|
||||
mouse_mode_button_table.attach (mouse_audition_button, 2, 3, 1, 2);
|
||||
edit_mode_selector.set_name ("EditModeSelector");
|
||||
Gtkmm2ext::set_size_request_to_display_given_text (edit_mode_selector, "Splice Edit", 2+FUDGE, 10);
|
||||
set_popdown_strings (edit_mode_selector, internationalize (edit_mode_strings));
|
||||
edit_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::edit_mode_selection_done));
|
||||
|
||||
mouse_mode_tearoff = manage (new TearOff (mouse_mode_button_table));
|
||||
mode_box->pack_start(edit_mode_selector);
|
||||
mode_box->pack_start(mouse_mode_button_box);
|
||||
|
||||
mouse_mode_tearoff = manage (new TearOff (*mode_box));
|
||||
mouse_mode_tearoff->set_name ("MouseModeBase");
|
||||
|
||||
mouse_mode_tearoff->Detach.connect (bind (mem_fun(*this, &Editor::detach_tearoff), static_cast<Box*>(&toolbar_hbox),
|
||||
@@ -2626,12 +2606,12 @@ Editor::setup_toolbar ()
|
||||
mouse_timefx_button.set_name ("MouseModeButton");
|
||||
mouse_audition_button.set_name ("MouseModeButton");
|
||||
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (mouse_move_button, _("select/move objects"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (mouse_select_button, _("select/move ranges"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (mouse_gain_button, _("draw gain automation"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (mouse_zoom_button, _("select zoom range"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (mouse_timefx_button, _("stretch/shrink regions"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (mouse_audition_button, _("listen to specific regions"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (mouse_move_button, _("Select/Move Objects"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (mouse_select_button, _("Select/Move Ranges"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (mouse_gain_button, _("Draw Gain Automation"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (mouse_zoom_button, _("Select Zoom Range"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (mouse_timefx_button, _("Stretch/Shrink Regions"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (mouse_audition_button, _("Listen to Specific Regions"));
|
||||
|
||||
mouse_move_button.unset_flags (CAN_FOCUS);
|
||||
mouse_select_button.unset_flags (CAN_FOCUS);
|
||||
@@ -2650,160 +2630,82 @@ Editor::setup_toolbar ()
|
||||
mouse_audition_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseAudition));
|
||||
|
||||
// mouse_move_button.set_active (true);
|
||||
|
||||
/* automation control */
|
||||
|
||||
global_automation_button.set_name ("MouseModeButton");
|
||||
automation_mode_button.set_name ("MouseModeButton");
|
||||
|
||||
automation_box.set_spacing (2);
|
||||
automation_box.set_border_width (2);
|
||||
automation_box.pack_start (global_automation_button, false, false);
|
||||
automation_box.pack_start (automation_mode_button, false, false);
|
||||
|
||||
/* Edit mode */
|
||||
|
||||
edit_mode_label.set_name ("ToolBarLabel");
|
||||
|
||||
edit_mode_selector.set_name ("EditModeSelector");
|
||||
|
||||
edit_mode_box.set_spacing (3);
|
||||
edit_mode_box.set_border_width (3);
|
||||
|
||||
/* XXX another disgusting hack because of the way combo boxes size themselves */
|
||||
|
||||
const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button
|
||||
Gtkmm2ext::set_size_request_to_display_given_text (edit_mode_selector, "EdgtMode", 2+FUDGE, 10);
|
||||
set_popdown_strings (edit_mode_selector, internationalize (edit_mode_strings));
|
||||
edit_mode_box.pack_start (edit_mode_label, false, false);
|
||||
edit_mode_box.pack_start (edit_mode_selector, false, false);
|
||||
|
||||
edit_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::edit_mode_selection_done));
|
||||
|
||||
/* Snap Type */
|
||||
|
||||
snap_type_label.set_name ("ToolBarLabel");
|
||||
|
||||
snap_type_selector.set_name ("SnapTypeSelector");
|
||||
|
||||
snap_type_box.set_spacing (3);
|
||||
snap_type_box.set_border_width (3);
|
||||
|
||||
/* XXX another disgusting hack because of the way combo boxes size themselves */
|
||||
|
||||
Gtkmm2ext::set_size_request_to_display_given_text (snap_type_selector, "SMPTE Seconds", 2+FUDGE, 10);
|
||||
set_popdown_strings (snap_type_selector, internationalize (snap_type_strings));
|
||||
|
||||
snap_type_box.pack_start (snap_type_label, false, false);
|
||||
snap_type_box.pack_start (snap_type_selector, false, false);
|
||||
|
||||
snap_type_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_type_selection_done));
|
||||
|
||||
/* Snap mode, not snap type */
|
||||
|
||||
snap_mode_label.set_name ("ToolBarLabel");
|
||||
|
||||
snap_mode_selector.set_name ("SnapModeSelector");
|
||||
|
||||
snap_mode_box.set_spacing (3);
|
||||
snap_mode_box.set_border_width (3);
|
||||
|
||||
Gtkmm2ext::set_size_request_to_display_given_text (snap_mode_selector, "SngpMode", 2+FUDGE, 10);
|
||||
set_popdown_strings (snap_mode_selector, internationalize (snap_mode_strings));
|
||||
/* Zoom */
|
||||
|
||||
zoom_box.set_spacing (1);
|
||||
zoom_box.set_border_width (2);
|
||||
|
||||
snap_mode_box.pack_start (snap_mode_label, false, false);
|
||||
snap_mode_box.pack_start (snap_mode_selector, false, false);
|
||||
|
||||
snap_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_mode_selection_done));
|
||||
|
||||
/* Zoom focus mode */
|
||||
|
||||
zoom_focus_label.set_name ("ToolBarLabel");
|
||||
zoom_in_button.set_name ("EditorTimeButton");
|
||||
zoom_in_button.add (*(manage (new Image (get_xpm("zoom_in.xpm")))));
|
||||
zoom_in_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), false));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (zoom_in_button, _("Zoom In"));
|
||||
|
||||
zoom_out_button.set_name ("EditorTimeButton");
|
||||
zoom_out_button.add (*(manage (new Image (get_xpm("zoom_out.xpm")))));
|
||||
zoom_out_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), true));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_button, _("Zoom Out"));
|
||||
|
||||
zoom_out_full_button.set_name ("EditorTimeButton");
|
||||
zoom_out_full_button.add (*(manage (new Image (get_xpm("zoom_full.xpm")))));
|
||||
zoom_out_full_button.signal_clicked().connect (mem_fun(*this, &Editor::temporal_zoom_session));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_full_button, _("Zoom to Session"));
|
||||
|
||||
zoom_box.pack_start (zoom_out_button, false, false);
|
||||
zoom_box.pack_start (zoom_in_button, false, false);
|
||||
zoom_box.pack_start (zoom_range_clock, false, false);
|
||||
zoom_box.pack_start (zoom_out_full_button, false, false);
|
||||
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (zoom_range_clock, _("Current Zoom Range\n(Width of visible area)"));
|
||||
|
||||
zoom_focus_selector.set_name ("ZoomFocusSelector");
|
||||
|
||||
zoom_focus_box.set_spacing (3);
|
||||
zoom_focus_box.set_border_width (3);
|
||||
|
||||
/* XXX another disgusting hack because of the way combo boxes size themselves */
|
||||
|
||||
Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, "Edgt Cursor", 2+FUDGE, 10);
|
||||
Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, "Focus Center", 2+FUDGE, 0);
|
||||
set_popdown_strings (zoom_focus_selector, internationalize (zoom_focus_strings));
|
||||
|
||||
zoom_focus_box.pack_start (zoom_focus_label, false, false);
|
||||
zoom_focus_box.pack_start (zoom_focus_selector, false, false);
|
||||
|
||||
zoom_focus_selector.signal_changed().connect (mem_fun(*this, &Editor::zoom_focus_selection_done));
|
||||
|
||||
/* selection/cursor clocks */
|
||||
zoom_box.pack_start (zoom_focus_selector, false, false);
|
||||
|
||||
toolbar_selection_cursor_label.set_name ("ToolBarLabel");
|
||||
selection_start_clock_label.set_name ("ToolBarLabel");
|
||||
selection_end_clock_label.set_name ("ToolBarLabel");
|
||||
edit_cursor_clock_label.set_name ("ToolBarLabel");
|
||||
|
||||
selection_start_clock_label.set_text (_("Start:"));
|
||||
selection_end_clock_label.set_text (_("End:"));
|
||||
edit_cursor_clock_label.set_text (_("Edit"));
|
||||
/* Edit Cursor / Snap */
|
||||
|
||||
/* the zoom in/out buttons are generally taller than the clocks, so
|
||||
put all the toolbar clocks into a size group with one of the
|
||||
buttons to make them all equal height.
|
||||
snap_box.set_spacing (1);
|
||||
snap_box.set_border_width (2);
|
||||
|
||||
this also applies to the various toolbar combos
|
||||
*/
|
||||
snap_type_selector.set_name ("SnapTypeSelector");
|
||||
Gtkmm2ext::set_size_request_to_display_given_text (snap_type_selector, "SMPTE Seconds", 2+FUDGE, 10);
|
||||
set_popdown_strings (snap_type_selector, internationalize (snap_type_strings));
|
||||
snap_type_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_type_selection_done));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (snap_type_selector, _("Unit to snap cursors and ranges to"));
|
||||
|
||||
RefPtr<SizeGroup> toolbar_clock_size_group = SizeGroup::create (SIZE_GROUP_VERTICAL);
|
||||
toolbar_clock_size_group->add_widget (zoom_out_button);
|
||||
toolbar_clock_size_group->add_widget (edit_cursor_clock);
|
||||
toolbar_clock_size_group->add_widget (zoom_range_clock);
|
||||
toolbar_clock_size_group->add_widget (nudge_clock);
|
||||
toolbar_clock_size_group->add_widget (edit_mode_selector);
|
||||
toolbar_clock_size_group->add_widget (snap_type_selector);
|
||||
toolbar_clock_size_group->add_widget (snap_mode_selector);
|
||||
toolbar_clock_size_group->add_widget (zoom_focus_selector);
|
||||
snap_mode_selector.set_name ("SnapModeSelector");
|
||||
Gtkmm2ext::set_size_request_to_display_given_text (snap_mode_selector, "Magnetic Snap", 2+FUDGE, 10);
|
||||
set_popdown_strings (snap_mode_selector, internationalize (snap_mode_strings));
|
||||
snap_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_mode_selection_done));
|
||||
|
||||
HBox* edit_clock_hbox = manage (new HBox());
|
||||
VBox* edit_clock_vbox = manage (new VBox());
|
||||
snap_box.pack_start (edit_cursor_clock, false, false);
|
||||
snap_box.pack_start (snap_mode_selector, false, false);
|
||||
snap_box.pack_start (snap_type_selector, false, false);
|
||||
|
||||
edit_clock_hbox->pack_start (edit_cursor_clock, false, false);
|
||||
|
||||
edit_clock_vbox->set_spacing (3);
|
||||
edit_clock_vbox->set_border_width (3);
|
||||
edit_clock_vbox->pack_start (edit_cursor_clock_label, false, false);
|
||||
edit_clock_vbox->pack_start (*edit_clock_hbox, false, false);
|
||||
/* Nudge */
|
||||
|
||||
HBox* hbox = new HBox;
|
||||
HBox *nudge_box = manage (new HBox);
|
||||
nudge_box->set_spacing(1);
|
||||
nudge_box->set_border_width (2);
|
||||
|
||||
hbox->pack_start (*edit_clock_vbox, false, false);
|
||||
hbox->pack_start (zoom_indicator_vbox, false, false);
|
||||
hbox->pack_start (zoom_focus_box, false, false);
|
||||
hbox->pack_start (snap_type_box, false, false);
|
||||
hbox->pack_start (snap_mode_box, false, false);
|
||||
hbox->pack_start (edit_mode_box, false, false);
|
||||
|
||||
VBox *vbox = manage (new VBox);
|
||||
|
||||
vbox->set_spacing (3);
|
||||
vbox->set_border_width (3);
|
||||
|
||||
HBox *nbox = manage (new HBox);
|
||||
|
||||
nudge_forward_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::nudge_forward), false));
|
||||
nudge_backward_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::nudge_backward), false));
|
||||
|
||||
nbox->pack_start (nudge_backward_button, false, false);
|
||||
nbox->pack_start (nudge_forward_button, false, false);
|
||||
nbox->pack_start (nudge_clock, false, false, 5);
|
||||
nudge_box->pack_start (nudge_backward_button, false, false);
|
||||
nudge_box->pack_start (nudge_forward_button, false, false);
|
||||
nudge_box->pack_start (nudge_clock, false, false);
|
||||
|
||||
nudge_label.set_name ("ToolBarLabel");
|
||||
|
||||
vbox->pack_start (nudge_label, false, false);
|
||||
vbox->pack_start (*nbox, false, false);
|
||||
/* Pack everything in... */
|
||||
|
||||
hbox->pack_start (*vbox, false, false);
|
||||
|
||||
hbox->show_all ();
|
||||
HBox* hbox = new HBox;
|
||||
hbox->set_spacing(10);
|
||||
|
||||
tools_tearoff = new TearOff (*hbox);
|
||||
tools_tearoff->set_name ("MouseModeBase");
|
||||
@@ -2817,11 +2719,18 @@ Editor::setup_toolbar ()
|
||||
tools_tearoff->Visible.connect (bind (mem_fun(*this, &Editor::reattach_tearoff), static_cast<Box*> (&toolbar_hbox),
|
||||
&tools_tearoff->tearoff_window(), 0));
|
||||
|
||||
toolbar_hbox.set_spacing (8);
|
||||
toolbar_hbox.set_border_width (2);
|
||||
toolbar_hbox.set_spacing (10);
|
||||
toolbar_hbox.set_border_width (1);
|
||||
|
||||
toolbar_hbox.pack_start (*tools_tearoff, false, false);
|
||||
toolbar_hbox.pack_start (*mouse_mode_tearoff, false, false);
|
||||
toolbar_hbox.pack_start (*tools_tearoff, false, false);
|
||||
|
||||
|
||||
hbox->pack_start (snap_box, false, false);
|
||||
hbox->pack_start (zoom_box, false, false);
|
||||
hbox->pack_start (*nudge_box, false, false);
|
||||
|
||||
hbox->show_all ();
|
||||
|
||||
toolbar_base.set_name ("ToolBarBase");
|
||||
toolbar_base.add (toolbar_hbox);
|
||||
@@ -3101,31 +3010,31 @@ Editor::mapover_audio_tracks (slot<void,AudioTimeAxisView&,uint32_t> sl)
|
||||
}
|
||||
|
||||
void
|
||||
Editor::mapped_set_selected_regionview_from_click (AudioTimeAxisView& atv, uint32_t ignored,
|
||||
AudioRegionView* basis, vector<AudioRegionView*>* all_equivs)
|
||||
Editor::mapped_set_selected_regionview_from_click (RouteTimeAxisView& tv, uint32_t ignored,
|
||||
RegionView* basis, vector<RegionView*>* all_equivs)
|
||||
{
|
||||
AudioPlaylist* pl;
|
||||
vector<AudioRegion*> results;
|
||||
AudioRegionView* marv;
|
||||
AudioDiskstream* ds;
|
||||
Playlist* pl;
|
||||
vector<Region*> results;
|
||||
RegionView* marv;
|
||||
Diskstream* ds;
|
||||
|
||||
if ((ds = atv.get_diskstream()) == 0) {
|
||||
if ((ds = tv.get_diskstream()) == 0) {
|
||||
/* bus */
|
||||
return;
|
||||
}
|
||||
|
||||
if (&atv == &basis->get_time_axis_view()) {
|
||||
if (&tv == &basis->get_time_axis_view()) {
|
||||
/* looking in same track as the original */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ((pl = ds->playlist()) != 0) {
|
||||
pl->get_equivalent_regions (basis->region, results);
|
||||
if ((pl = dynamic_cast<Playlist*>(ds->playlist())) != 0) {
|
||||
pl->get_equivalent_regions (basis->region(), results);
|
||||
}
|
||||
|
||||
for (vector<AudioRegion*>::iterator ir = results.begin(); ir != results.end(); ++ir) {
|
||||
if ((marv = atv.view->find_view (**ir)) != 0) {
|
||||
for (vector<Region*>::iterator ir = results.begin(); ir != results.end(); ++ir) {
|
||||
if ((marv = tv.view()->find_view (**ir)) != 0) {
|
||||
all_equivs->push_back (marv);
|
||||
}
|
||||
}
|
||||
@@ -3134,7 +3043,7 @@ Editor::mapped_set_selected_regionview_from_click (AudioTimeAxisView& atv, uint3
|
||||
bool
|
||||
Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, bool no_track_remove)
|
||||
{
|
||||
vector<AudioRegionView*> all_equivalent_regions;
|
||||
vector<RegionView*> all_equivalent_regions;
|
||||
bool commit = false;
|
||||
|
||||
if (!clicked_regionview || !clicked_audio_trackview) {
|
||||
@@ -3189,7 +3098,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
|
||||
commit = true;
|
||||
}
|
||||
|
||||
for (vector<AudioRegionView*>::iterator i = all_equivalent_regions.begin(); i != all_equivalent_regions.end(); ++i) {
|
||||
for (vector<RegionView*>::iterator i = all_equivalent_regions.begin(); i != all_equivalent_regions.end(); ++i) {
|
||||
selection->add (*i);
|
||||
}
|
||||
}
|
||||
@@ -3222,58 +3131,58 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
|
||||
last_frame = 0;
|
||||
first_frame = max_frames;
|
||||
|
||||
for (AudioRegionSelection::iterator x = selection->audio_regions.begin(); x != selection->audio_regions.end(); ++x) {
|
||||
for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
|
||||
if (&(*x)->get_time_axis_view() == &clicked_regionview->get_time_axis_view()) {
|
||||
|
||||
if ((*x)->region.last_frame() > last_frame) {
|
||||
last_frame = (*x)->region.last_frame();
|
||||
if ((*x)->region().last_frame() > last_frame) {
|
||||
last_frame = (*x)->region().last_frame();
|
||||
}
|
||||
|
||||
if ((*x)->region.first_frame() < first_frame) {
|
||||
first_frame = (*x)->region.first_frame();
|
||||
if ((*x)->region().first_frame() < first_frame) {
|
||||
first_frame = (*x)->region().first_frame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 2. figure out the boundaries for our search for new objects */
|
||||
|
||||
switch (clicked_regionview->region.coverage (first_frame, last_frame)) {
|
||||
switch (clicked_regionview->region().coverage (first_frame, last_frame)) {
|
||||
case OverlapNone:
|
||||
cerr << "no overlap, first = " << first_frame << " last = " << last_frame << " region = "
|
||||
<< clicked_regionview->region.first_frame() << " .. " << clicked_regionview->region.last_frame() << endl;
|
||||
<< clicked_regionview->region().first_frame() << " .. " << clicked_regionview->region().last_frame() << endl;
|
||||
|
||||
if (last_frame < clicked_regionview->region.first_frame()) {
|
||||
if (last_frame < clicked_regionview->region().first_frame()) {
|
||||
first_frame = last_frame;
|
||||
last_frame = clicked_regionview->region.last_frame();
|
||||
last_frame = clicked_regionview->region().last_frame();
|
||||
} else {
|
||||
last_frame = first_frame;
|
||||
first_frame = clicked_regionview->region.first_frame();
|
||||
first_frame = clicked_regionview->region().first_frame();
|
||||
}
|
||||
break;
|
||||
|
||||
case OverlapExternal:
|
||||
cerr << "external overlap, first = " << first_frame << " last = " << last_frame << " region = "
|
||||
<< clicked_regionview->region.first_frame() << " .. " << clicked_regionview->region.last_frame() << endl;
|
||||
<< clicked_regionview->region().first_frame() << " .. " << clicked_regionview->region().last_frame() << endl;
|
||||
|
||||
if (last_frame < clicked_regionview->region.first_frame()) {
|
||||
if (last_frame < clicked_regionview->region().first_frame()) {
|
||||
first_frame = last_frame;
|
||||
last_frame = clicked_regionview->region.last_frame();
|
||||
last_frame = clicked_regionview->region().last_frame();
|
||||
} else {
|
||||
last_frame = first_frame;
|
||||
first_frame = clicked_regionview->region.first_frame();
|
||||
first_frame = clicked_regionview->region().first_frame();
|
||||
}
|
||||
break;
|
||||
|
||||
case OverlapInternal:
|
||||
cerr << "internal overlap, first = " << first_frame << " last = " << last_frame << " region = "
|
||||
<< clicked_regionview->region.first_frame() << " .. " << clicked_regionview->region.last_frame() << endl;
|
||||
<< clicked_regionview->region().first_frame() << " .. " << clicked_regionview->region().last_frame() << endl;
|
||||
|
||||
if (last_frame < clicked_regionview->region.first_frame()) {
|
||||
if (last_frame < clicked_regionview->region().first_frame()) {
|
||||
first_frame = last_frame;
|
||||
last_frame = clicked_regionview->region.last_frame();
|
||||
last_frame = clicked_regionview->region().last_frame();
|
||||
} else {
|
||||
last_frame = first_frame;
|
||||
first_frame = clicked_regionview->region.first_frame();
|
||||
first_frame = clicked_regionview->region().first_frame();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -3299,18 +3208,18 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
|
||||
|
||||
/* 3. convert to a vector of audio regions */
|
||||
|
||||
vector<AudioRegionView*> audio_regions;
|
||||
vector<RegionView*> regions;
|
||||
|
||||
for (list<Selectable*>::iterator x = results.begin(); x != results.end(); ++x) {
|
||||
AudioRegionView* arv;
|
||||
RegionView* arv;
|
||||
|
||||
if ((arv = dynamic_cast<AudioRegionView*>(*x)) != 0) {
|
||||
audio_regions.push_back (arv);
|
||||
if ((arv = dynamic_cast<RegionView*>(*x)) != 0) {
|
||||
regions.push_back (arv);
|
||||
}
|
||||
}
|
||||
|
||||
if (!audio_regions.empty()) {
|
||||
selection->add (audio_regions);
|
||||
if (!regions.empty()) {
|
||||
selection->add (regions);
|
||||
commit = true;
|
||||
}
|
||||
}
|
||||
@@ -3320,37 +3229,32 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
|
||||
}
|
||||
|
||||
void
|
||||
Editor::set_selected_regionview_from_region_list (Region& r, Selection::Operation op)
|
||||
Editor::set_selected_regionview_from_region_list (Region& region, Selection::Operation op)
|
||||
{
|
||||
vector<AudioRegionView*> all_equivalent_regions;
|
||||
AudioRegion* region;
|
||||
|
||||
if ((region = dynamic_cast<AudioRegion*>(&r)) == 0) {
|
||||
return;
|
||||
}
|
||||
vector<RegionView*> all_equivalent_regions;
|
||||
|
||||
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
|
||||
|
||||
AudioTimeAxisView* tatv;
|
||||
RouteTimeAxisView* tatv;
|
||||
|
||||
if ((tatv = dynamic_cast<AudioTimeAxisView*> (*i)) != 0) {
|
||||
if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
|
||||
|
||||
AudioPlaylist* pl;
|
||||
vector<AudioRegion*> results;
|
||||
AudioRegionView* marv;
|
||||
AudioDiskstream* ds;
|
||||
Playlist* pl;
|
||||
vector<Region*> results;
|
||||
RegionView* marv;
|
||||
Diskstream* ds;
|
||||
|
||||
if ((ds = tatv->get_diskstream()) == 0) {
|
||||
/* bus */
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((pl = ds->playlist()) != 0) {
|
||||
pl->get_region_list_equivalent_regions (*region, results);
|
||||
if ((pl = dynamic_cast<Playlist*>(ds->playlist())) != 0) {
|
||||
pl->get_region_list_equivalent_regions (region, results);
|
||||
}
|
||||
|
||||
for (vector<AudioRegion*>::iterator ir = results.begin(); ir != results.end(); ++ir) {
|
||||
if ((marv = tatv->view->find_view (**ir)) != 0) {
|
||||
for (vector<Region*>::iterator ir = results.begin(); ir != results.end(); ++ir) {
|
||||
if ((marv = tatv->view()->find_view (**ir)) != 0) {
|
||||
all_equivalent_regions.push_back (marv);
|
||||
}
|
||||
}
|
||||
@@ -3379,10 +3283,10 @@ Editor::set_selected_regionview_from_region_list (Region& r, Selection::Operatio
|
||||
bool
|
||||
Editor::set_selected_regionview_from_map_event (GdkEventAny* ev, StreamView* sv, Region* r)
|
||||
{
|
||||
AudioRegionView* rv;
|
||||
AudioRegion* ar;
|
||||
RegionView* rv;
|
||||
Region* ar;
|
||||
|
||||
if ((ar = dynamic_cast<AudioRegion*> (r)) == 0) {
|
||||
if ((ar = dynamic_cast<Region*> (r)) == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -3394,7 +3298,7 @@ Editor::set_selected_regionview_from_map_event (GdkEventAny* ev, StreamView* sv,
|
||||
a single other region.
|
||||
*/
|
||||
|
||||
if (selection->audio_regions.size() > 1) {
|
||||
if (selection->regions.size() > 1) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -3559,7 +3463,7 @@ Editor::duplicate_dialog (bool dup_region)
|
||||
|
||||
if (sscanf (text.c_str(), "%f", ×) == 1) {
|
||||
if (dup_region) {
|
||||
AudioRegionSelection regions;
|
||||
RegionSelection regions;
|
||||
regions.add (clicked_regionview);
|
||||
duplicate_some_regions (regions, times);
|
||||
} else {
|
||||
@@ -3610,9 +3514,9 @@ Editor::edit_mode_selection_done ()
|
||||
string choice = edit_mode_selector.get_active_text();
|
||||
EditMode mode = Slide;
|
||||
|
||||
if (choice == _("Splice")) {
|
||||
if (choice == _("Splice Edit")) {
|
||||
mode = Splice;
|
||||
} else if (choice == _("Slide")) {
|
||||
} else if (choice == _("Slide Edit")) {
|
||||
mode = Slide;
|
||||
}
|
||||
|
||||
@@ -3628,18 +3532,18 @@ Editor::snap_type_selection_done ()
|
||||
|
||||
string choice = snap_type_selector.get_active_text();
|
||||
SnapType snaptype = SnapToFrame;
|
||||
|
||||
|
||||
if (choice == _("Beats/3")) {
|
||||
snaptype = SnapToAThirdBeat;
|
||||
} else if (choice == _("Beats/4")) {
|
||||
snaptype = SnapToAQuarterBeat;
|
||||
} else if (choice == _("Beats/8")) {
|
||||
snaptype = SnapToAEighthBeat;
|
||||
} else if (choice == _("Beats/16")) {
|
||||
snaptype = SnapToASixteenthBeat;
|
||||
} else if (choice == _("Beats/32")) {
|
||||
snaptype = SnapToAThirtysecondBeat;
|
||||
} else if (choice == _("Beats")) {
|
||||
snaptype = SnapToAThirdBeat;
|
||||
} else if (choice == _("Beats/4")) {
|
||||
snaptype = SnapToAQuarterBeat;
|
||||
} else if (choice == _("Beats/8")) {
|
||||
snaptype = SnapToAEighthBeat;
|
||||
} else if (choice == _("Beats/16")) {
|
||||
snaptype = SnapToASixteenthBeat;
|
||||
} else if (choice == _("Beats/32")) {
|
||||
snaptype = SnapToAThirtysecondBeat;
|
||||
} else if (choice == _("Beats")) {
|
||||
snaptype = SnapToBeat;
|
||||
} else if (choice == _("Bars")) {
|
||||
snaptype = SnapToBar;
|
||||
@@ -3667,10 +3571,10 @@ Editor::snap_type_selection_done ()
|
||||
snaptype = SnapToSeconds;
|
||||
} else if (choice == _("Minutes")) {
|
||||
snaptype = SnapToMinutes;
|
||||
} else if (choice == _("None")) {
|
||||
} else if (choice == _("None")) {
|
||||
snaptype = SnapToFrame;
|
||||
}
|
||||
|
||||
|
||||
set_snap_to (snaptype);
|
||||
}
|
||||
|
||||
@@ -3684,9 +3588,9 @@ Editor::snap_mode_selection_done ()
|
||||
string choice = snap_mode_selector.get_active_text();
|
||||
SnapMode mode = SnapNormal;
|
||||
|
||||
if (choice == _("Normal")) {
|
||||
if (choice == _("Normal Snap")) {
|
||||
mode = SnapNormal;
|
||||
} else if (choice == _("Magnetic")) {
|
||||
} else if (choice == _("Magnetic Snap")) {
|
||||
mode = SnapMagnetic;
|
||||
}
|
||||
|
||||
@@ -3703,15 +3607,15 @@ Editor::zoom_focus_selection_done ()
|
||||
string choice = zoom_focus_selector.get_active_text();
|
||||
ZoomFocus focus_type = ZoomFocusLeft;
|
||||
|
||||
if (choice == _("Left")) {
|
||||
if (choice == _("Focus Left")) {
|
||||
focus_type = ZoomFocusLeft;
|
||||
} else if (choice == _("Right")) {
|
||||
} else if (choice == _("Focus Right")) {
|
||||
focus_type = ZoomFocusRight;
|
||||
} else if (choice == _("Center")) {
|
||||
} else if (choice == _("Focus Center")) {
|
||||
focus_type = ZoomFocusCenter;
|
||||
} else if (choice == _("Playhead")) {
|
||||
} else if (choice == _("Focus Playhead")) {
|
||||
focus_type = ZoomFocusPlayhead;
|
||||
} else if (choice == _("Edit Cursor")) {
|
||||
} else if (choice == _("Focus Edit Cursor")) {
|
||||
focus_type = ZoomFocusEdit;
|
||||
}
|
||||
|
||||
@@ -3781,7 +3685,7 @@ void
|
||||
Editor::region_selection_changed ()
|
||||
{
|
||||
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
|
||||
(*i)->set_selected_regionviews (selection->audio_regions);
|
||||
(*i)->set_selected_regionviews (selection->regions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4051,8 +3955,8 @@ Editor::playlist_deletion_dialog (Playlist* pl)
|
||||
bool
|
||||
Editor::audio_region_selection_covers (jack_nframes_t where)
|
||||
{
|
||||
for (AudioRegionSelection::iterator a = selection->audio_regions.begin(); a != selection->audio_regions.end(); ++a) {
|
||||
if ((*a)->region.covers (where)) {
|
||||
for (RegionSelection::iterator a = selection->regions.begin(); a != selection->regions.end(); ++a) {
|
||||
if ((*a)->region().covers (where)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4063,10 +3967,10 @@ Editor::audio_region_selection_covers (jack_nframes_t where)
|
||||
void
|
||||
Editor::prepare_for_cleanup ()
|
||||
{
|
||||
cut_buffer->clear_audio_regions ();
|
||||
cut_buffer->clear_regions ();
|
||||
cut_buffer->clear_playlists ();
|
||||
|
||||
selection->clear_audio_regions ();
|
||||
selection->clear_regions ();
|
||||
selection->clear_playlists ();
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ namespace ARDOUR {
|
||||
class AudioDiskstream;
|
||||
class RouteGroup;
|
||||
class Playlist;
|
||||
class AudioPlaylist;
|
||||
class Region;
|
||||
class Location;
|
||||
class TempoSection;
|
||||
@@ -83,6 +84,7 @@ namespace LADSPA {
|
||||
}
|
||||
|
||||
class TimeAxisView;
|
||||
class RouteTimeAxisView;
|
||||
class AudioTimeAxisView;
|
||||
class AutomationTimeAxisView;
|
||||
class AudioRegionView;
|
||||
@@ -100,6 +102,7 @@ class TrackSelection;
|
||||
class AutomationSelection;
|
||||
class MixerStrip;
|
||||
class StreamView;
|
||||
class AudioStreamView;
|
||||
class ControlPoint;
|
||||
#ifdef FFT_ANALYSIS
|
||||
class AnalysisWindow;
|
||||
@@ -405,8 +408,8 @@ class Editor : public PublicEditor
|
||||
|
||||
TimeAxisView* clicked_trackview;
|
||||
AudioTimeAxisView* clicked_audio_trackview;
|
||||
AudioRegionView* clicked_regionview;
|
||||
AudioRegionView* latest_regionview;
|
||||
RegionView* clicked_regionview;
|
||||
RegionView* latest_regionview;
|
||||
uint32_t clicked_selection;
|
||||
CrossfadeView* clicked_crossfadeview;
|
||||
ControlPoint* clicked_control_point;
|
||||
@@ -416,7 +419,7 @@ class Editor : public PublicEditor
|
||||
|
||||
/* functions to be passed to mapover_audio_tracks(), possibly with sigc::bind()-supplied arguments */
|
||||
|
||||
void mapped_set_selected_regionview_from_click (AudioTimeAxisView&, uint32_t, AudioRegionView*, vector<AudioRegionView*>*);
|
||||
void mapped_set_selected_regionview_from_click (RouteTimeAxisView&, uint32_t, RegionView*, vector<RegionView*>*);
|
||||
void mapped_use_new_playlist (AudioTimeAxisView&, uint32_t);
|
||||
void mapped_use_copy_playlist (AudioTimeAxisView&, uint32_t);
|
||||
void mapped_clear_playlist (AudioTimeAxisView&, uint32_t);
|
||||
@@ -426,7 +429,7 @@ class Editor : public PublicEditor
|
||||
void button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type);
|
||||
bool button_release_can_deselect;
|
||||
|
||||
void catch_vanishing_audio_regionview (AudioRegionView *);
|
||||
void catch_vanishing_regionview (RegionView *);
|
||||
|
||||
bool set_selected_control_point_from_click (bool press, Selection::Operation op = Selection::Set, bool with_undo = true, bool no_remove=false);
|
||||
bool set_selected_track_from_click (bool press, Selection::Operation op = Selection::Set, bool with_undo = true, bool no_remove=false);
|
||||
@@ -434,7 +437,7 @@ class Editor : public PublicEditor
|
||||
|
||||
void set_selected_regionview_from_region_list (ARDOUR::Region& region, Selection::Operation op = Selection::Set);
|
||||
bool set_selected_regionview_from_map_event (GdkEventAny*, StreamView*, ARDOUR::Region*);
|
||||
void collect_new_region_view (AudioRegionView *);
|
||||
void collect_new_region_view (RegionView *);
|
||||
|
||||
Gtk::Menu track_context_menu;
|
||||
Gtk::Menu track_region_context_menu;
|
||||
@@ -455,12 +458,11 @@ class Editor : public PublicEditor
|
||||
Gtk::Menu* build_track_selection_context_menu (jack_nframes_t);
|
||||
void add_dstream_context_items (Gtk::Menu_Helpers::MenuList&);
|
||||
void add_bus_context_items (Gtk::Menu_Helpers::MenuList&);
|
||||
void add_region_context_items (StreamView*, ARDOUR::Region*, Gtk::Menu_Helpers::MenuList&);
|
||||
void add_crossfade_context_items (StreamView*, ARDOUR::Crossfade*, Gtk::Menu_Helpers::MenuList&, bool many);
|
||||
void add_region_context_items (AudioStreamView*, ARDOUR::Region*, Gtk::Menu_Helpers::MenuList&);
|
||||
void add_crossfade_context_items (AudioStreamView*, ARDOUR::Crossfade*, Gtk::Menu_Helpers::MenuList&, bool many);
|
||||
void add_selection_context_items (Gtk::Menu_Helpers::MenuList&);
|
||||
|
||||
void handle_new_route (boost::shared_ptr<ARDOUR::Route>);
|
||||
void handle_new_route_p (boost::shared_ptr<ARDOUR::Route>);
|
||||
void remove_route (TimeAxisView *);
|
||||
bool route_removal;
|
||||
|
||||
@@ -854,7 +856,7 @@ class Editor : public PublicEditor
|
||||
void lower_region_to_bottom ();
|
||||
void split_region ();
|
||||
void split_region_at (jack_nframes_t);
|
||||
void split_regions_at (jack_nframes_t, AudioRegionSelection&);
|
||||
void split_regions_at (jack_nframes_t, RegionSelection&);
|
||||
void crop_region_to_selection ();
|
||||
void set_a_regions_sync_position (ARDOUR::Region&, jack_nframes_t);
|
||||
void set_region_sync_from_edit_cursor ();
|
||||
@@ -867,13 +869,13 @@ class Editor : public PublicEditor
|
||||
void remove_clicked_region ();
|
||||
void destroy_clicked_region ();
|
||||
void edit_region ();
|
||||
void duplicate_some_regions (AudioRegionSelection&, float times);
|
||||
void duplicate_some_regions (RegionSelection&, float times);
|
||||
void duplicate_selection (float times);
|
||||
void region_fill_selection ();
|
||||
|
||||
void region_fill_track ();
|
||||
void audition_playlist_region_standalone (ARDOUR::AudioRegion&);
|
||||
void audition_playlist_region_via_route (ARDOUR::AudioRegion&, ARDOUR::Route&);
|
||||
void audition_playlist_region_standalone (ARDOUR::Region&);
|
||||
void audition_playlist_region_via_route (ARDOUR::Region&, ARDOUR::Route&);
|
||||
void split_multichannel_region();
|
||||
void reverse_region ();
|
||||
void normalize_region ();
|
||||
@@ -1020,7 +1022,7 @@ class Editor : public PublicEditor
|
||||
bool have_pending_keyboard_selection;
|
||||
jack_nframes_t pending_keyboard_selection_start;
|
||||
|
||||
ARDOUR::AudioRegion* select_region_for_operation (int dir, TimeAxisView **tv);
|
||||
ARDOUR::Region* select_region_for_operation (int dir, TimeAxisView **tv);
|
||||
void extend_selection_to_end_of_region (bool next);
|
||||
void extend_selection_to_start_of_region (bool previous);
|
||||
|
||||
@@ -1094,7 +1096,7 @@ class Editor : public PublicEditor
|
||||
void remove_gain_control_point (ArdourCanvas::Item*, GdkEvent*);
|
||||
void remove_control_point (ArdourCanvas::Item*, GdkEvent*);
|
||||
|
||||
void mouse_brush_insert_region (AudioRegionView*, jack_nframes_t pos);
|
||||
void mouse_brush_insert_region (RegionView*, jack_nframes_t pos);
|
||||
void brush (jack_nframes_t);
|
||||
|
||||
void show_verbose_time_cursor (jack_nframes_t frame, double offset = 0, double xpos=-1, double ypos=-1);
|
||||
@@ -1112,10 +1114,10 @@ class Editor : public PublicEditor
|
||||
bool canvas_fade_in_handle_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
|
||||
bool canvas_fade_out_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
|
||||
bool canvas_fade_out_handle_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
|
||||
bool canvas_region_view_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
|
||||
bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
|
||||
bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
|
||||
bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, AudioTimeAxisView*);
|
||||
bool canvas_region_view_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
|
||||
bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
|
||||
bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
|
||||
bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, RouteTimeAxisView*);
|
||||
bool canvas_marker_event (GdkEvent* event,ArdourCanvas::Item*, Marker*);
|
||||
bool canvas_zoom_rect_event (GdkEvent* event,ArdourCanvas::Item*);
|
||||
bool canvas_tempo_marker_event (GdkEvent* event,ArdourCanvas::Item*, TempoMarker*);
|
||||
@@ -1263,12 +1265,7 @@ class Editor : public PublicEditor
|
||||
|
||||
void editor_mixer_button_toggled ();
|
||||
|
||||
AudioClock selection_start_clock;
|
||||
Gtk::Label selection_start_clock_label;
|
||||
AudioClock selection_end_clock;
|
||||
Gtk::Label selection_end_clock_label;
|
||||
AudioClock edit_cursor_clock;
|
||||
Gtk::Label edit_cursor_clock_label;
|
||||
AudioClock zoom_range_clock;
|
||||
Gtk::Button zoom_in_button;
|
||||
Gtk::Button zoom_out_button;
|
||||
@@ -1280,8 +1277,8 @@ class Editor : public PublicEditor
|
||||
Gtk::Table toolbar_selection_clock_table;
|
||||
Gtk::Label toolbar_selection_cursor_label;
|
||||
|
||||
Gtk::Table mouse_mode_button_table;
|
||||
Gtkmm2ext::TearOff* mouse_mode_tearoff;
|
||||
Gtk::HBox mouse_mode_button_box;
|
||||
Gtkmm2ext::TearOff* mouse_mode_tearoff;
|
||||
Gtk::ToggleButton mouse_select_button;
|
||||
Gtk::ToggleButton mouse_move_button;
|
||||
Gtk::ToggleButton mouse_gain_button;
|
||||
@@ -1299,32 +1296,23 @@ class Editor : public PublicEditor
|
||||
Gtk::ToggleButton global_automation_button;
|
||||
|
||||
Gtk::ComboBoxText edit_mode_selector;
|
||||
Gtk::Label edit_mode_label;
|
||||
Gtk::VBox edit_mode_box;
|
||||
Gtk::VBox edit_mode_box;
|
||||
|
||||
void edit_mode_selection_done ();
|
||||
|
||||
Gtk::ComboBoxText snap_type_selector;
|
||||
Gtk::Label snap_type_label;
|
||||
Gtk::VBox snap_type_box;
|
||||
Gtk::ComboBoxText snap_mode_selector;
|
||||
Gtk::HBox snap_box;
|
||||
|
||||
void snap_type_selection_done ();
|
||||
|
||||
Gtk::ComboBoxText snap_mode_selector;
|
||||
Gtk::Label snap_mode_label;
|
||||
Gtk::VBox snap_mode_box;
|
||||
|
||||
void snap_mode_selection_done ();
|
||||
|
||||
Gtk::ComboBoxText zoom_focus_selector;
|
||||
Gtk::Label zoom_focus_label;
|
||||
Gtk::VBox zoom_focus_box;
|
||||
|
||||
void zoom_focus_selection_done ();
|
||||
|
||||
Gtk::Label zoom_indicator_label;
|
||||
Gtk::HBox zoom_indicator_box;
|
||||
Gtk::VBox zoom_indicator_vbox;
|
||||
Gtk::HBox zoom_box;
|
||||
|
||||
void update_zoom_indicator ();
|
||||
void zoom_adjustment_changed();
|
||||
@@ -1533,12 +1521,12 @@ class Editor : public PublicEditor
|
||||
void start_trim (ArdourCanvas::Item*, GdkEvent*);
|
||||
void point_trim (GdkEvent*);
|
||||
void trim_motion_callback (ArdourCanvas::Item*, GdkEvent*);
|
||||
void single_contents_trim (AudioRegionView&, jack_nframes_t, bool, bool, bool);
|
||||
void single_start_trim (AudioRegionView&, jack_nframes_t, bool, bool);
|
||||
void single_end_trim (AudioRegionView&, jack_nframes_t, bool, bool);
|
||||
void single_contents_trim (RegionView&, jack_nframes_t, bool, bool, bool);
|
||||
void single_start_trim (RegionView&, jack_nframes_t, bool, bool);
|
||||
void single_end_trim (RegionView&, jack_nframes_t, bool, bool);
|
||||
|
||||
void trim_finished_callback (ArdourCanvas::Item*, GdkEvent*);
|
||||
void thaw_region_after_trim (AudioRegionView& rv);
|
||||
void thaw_region_after_trim (RegionView& rv);
|
||||
|
||||
void trim_region_to_edit_cursor ();
|
||||
void trim_region_from_edit_cursor ();
|
||||
@@ -1592,7 +1580,7 @@ class Editor : public PublicEditor
|
||||
void export_range (jack_nframes_t start, jack_nframes_t end);
|
||||
void export_range_markers ();
|
||||
|
||||
int write_region_selection(AudioRegionSelection&);
|
||||
int write_region_selection(RegionSelection&);
|
||||
bool write_region (string path, ARDOUR::AudioRegion&);
|
||||
void export_region ();
|
||||
void bounce_region_selection ();
|
||||
@@ -1600,7 +1588,7 @@ class Editor : public PublicEditor
|
||||
void external_edit_region ();
|
||||
|
||||
int write_audio_selection (TimeSelection&);
|
||||
bool write_audio_range (ARDOUR::Playlist&, uint32_t channels, list<ARDOUR::AudioRange>&);
|
||||
bool write_audio_range (ARDOUR::AudioPlaylist&, uint32_t channels, list<ARDOUR::AudioRange>&);
|
||||
|
||||
void write_selection ();
|
||||
|
||||
@@ -1670,7 +1658,7 @@ class Editor : public PublicEditor
|
||||
struct TimeStretchDialog : public ArdourDialog {
|
||||
ARDOUR::Session::TimeStretchRequest request;
|
||||
Editor& editor;
|
||||
AudioRegionSelection regions;
|
||||
RegionSelection regions;
|
||||
Gtk::ProgressBar progress_bar;
|
||||
Gtk::ToggleButton quick_button;
|
||||
Gtk::ToggleButton antialias_button;
|
||||
@@ -1696,7 +1684,7 @@ class Editor : public PublicEditor
|
||||
TimeStretchDialog* current_timestretch;
|
||||
|
||||
static void* timestretch_thread (void *arg);
|
||||
int run_timestretch (AudioRegionSelection&, float fraction);
|
||||
int run_timestretch (RegionSelection&, float fraction);
|
||||
void do_timestretch (TimeStretchDialog&);
|
||||
|
||||
/* editor-mixer strip */
|
||||
@@ -1775,7 +1763,6 @@ class Editor : public PublicEditor
|
||||
Gtk::Button nudge_backward_button;
|
||||
Gtk::HBox nudge_hbox;
|
||||
Gtk::VBox nudge_vbox;
|
||||
Gtk::Label nudge_label;
|
||||
AudioClock nudge_clock;
|
||||
|
||||
jack_nframes_t get_nudge_distance (jack_nframes_t pos, jack_nframes_t& next);
|
||||
@@ -1798,11 +1785,11 @@ class Editor : public PublicEditor
|
||||
sigc::connection step_timeout;
|
||||
|
||||
TimeAxisView* entered_track;
|
||||
AudioRegionView* entered_regionview;
|
||||
RegionView* entered_regionview;
|
||||
bool clear_entered_track;
|
||||
gint left_track_canvas (GdkEventCrossing*);
|
||||
void set_entered_track (TimeAxisView*);
|
||||
void set_entered_regionview (AudioRegionView*);
|
||||
void set_entered_regionview (RegionView*);
|
||||
gint left_automation_track ();
|
||||
|
||||
bool _new_regionviews_show_envelope;
|
||||
|
||||
@@ -316,7 +316,7 @@ Editor::finish_bringing_in_audio (AudioRegion& region, uint32_t in_chans, uint32
|
||||
|
||||
case ImportToTrack:
|
||||
if (track) {
|
||||
Playlist* playlist = track->disk_stream().playlist();
|
||||
Playlist* playlist = track->diskstream().playlist();
|
||||
|
||||
AudioRegion* copy = new AudioRegion (region);
|
||||
begin_reversible_command (_("insert sndfile"));
|
||||
@@ -333,7 +333,7 @@ Editor::finish_bringing_in_audio (AudioRegion& region, uint32_t in_chans, uint32
|
||||
{
|
||||
boost::shared_ptr<AudioTrack> at (session->new_audio_track (in_chans, out_chans, Normal));
|
||||
copy = new AudioRegion (region);
|
||||
at->disk_stream().playlist()->add_region (*copy, pos);
|
||||
at->diskstream().playlist()->add_region (*copy, pos);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -341,7 +341,7 @@ Editor::finish_bringing_in_audio (AudioRegion& region, uint32_t in_chans, uint32
|
||||
{
|
||||
boost::shared_ptr<AudioTrack> at (session->new_audio_track (in_chans, out_chans, Destructive));
|
||||
copy = new AudioRegion (region);
|
||||
at->disk_stream().playlist()->add_region (*copy, pos);
|
||||
at->diskstream().playlist()->add_region (*copy, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "editor.h"
|
||||
#include "editing.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "regionview.h"
|
||||
#include "region_view.h"
|
||||
#include "selection.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
|
||||
#include "editor.h"
|
||||
#include "public_editor.h"
|
||||
#include "regionview.h"
|
||||
#include "streamview.h"
|
||||
#include "audio_region_view.h"
|
||||
#include "audio_streamview.h"
|
||||
#include "crossfade_view.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "region_gain_line.h"
|
||||
@@ -212,7 +212,7 @@ Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
|
||||
}
|
||||
|
||||
bool
|
||||
Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
|
||||
Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv)
|
||||
{
|
||||
gint ret = FALSE;
|
||||
|
||||
@@ -251,7 +251,7 @@ Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, Aud
|
||||
}
|
||||
|
||||
bool
|
||||
Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioTimeAxisView *tv)
|
||||
Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv)
|
||||
{
|
||||
bool ret = FALSE;
|
||||
|
||||
@@ -262,7 +262,7 @@ Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, Aud
|
||||
clicked_regionview = 0;
|
||||
clicked_control_point = 0;
|
||||
clicked_trackview = tv;
|
||||
clicked_audio_trackview = tv;
|
||||
clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(tv);
|
||||
ret = button_press_handler (item, event, StreamItem);
|
||||
break;
|
||||
|
||||
@@ -512,22 +512,25 @@ Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item,
|
||||
if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
|
||||
|
||||
if (atv->is_audio_track()) {
|
||||
|
||||
AudioPlaylist* pl = atv->get_diskstream()->playlist();
|
||||
Playlist::RegionList* rl = pl->regions_at (event_frame (event));
|
||||
|
||||
if (!rl->empty()) {
|
||||
DescendingRegionLayerSorter cmp;
|
||||
rl->sort (cmp);
|
||||
AudioPlaylist* pl;
|
||||
if ((pl = dynamic_cast<AudioPlaylist*> (atv->get_diskstream()->playlist())) != 0) {
|
||||
|
||||
AudioRegionView* arv = atv->view->find_view (*(dynamic_cast<AudioRegion*> (rl->front())));
|
||||
Playlist::RegionList* rl = pl->regions_at (event_frame (event));
|
||||
|
||||
/* proxy */
|
||||
|
||||
delete rl;
|
||||
if (!rl->empty()) {
|
||||
DescendingRegionLayerSorter cmp;
|
||||
rl->sort (cmp);
|
||||
|
||||
return canvas_region_view_event (event, arv->get_canvas_group(), arv);
|
||||
}
|
||||
RegionView* rv = atv->view()->find_view (*rl->front());
|
||||
|
||||
/* proxy */
|
||||
|
||||
delete rl;
|
||||
|
||||
return canvas_region_view_event (event, rv->get_canvas_group(), rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -696,7 +699,7 @@ Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* it
|
||||
|
||||
|
||||
bool
|
||||
Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, AudioRegionView* rv)
|
||||
Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
@@ -708,20 +711,20 @@ Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::
|
||||
clicked_control_point = 0;
|
||||
clicked_trackview = &clicked_regionview->get_time_axis_view();
|
||||
clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
|
||||
ret = button_press_handler (item, event, AudioRegionViewNameHighlight);
|
||||
ret = button_press_handler (item, event, RegionViewNameHighlight);
|
||||
break;
|
||||
case GDK_BUTTON_RELEASE:
|
||||
ret = button_release_handler (item, event, AudioRegionViewNameHighlight);
|
||||
ret = button_release_handler (item, event, RegionViewNameHighlight);
|
||||
break;
|
||||
case GDK_MOTION_NOTIFY:
|
||||
ret = motion_handler (item, event, AudioRegionViewNameHighlight);
|
||||
ret = motion_handler (item, event, RegionViewNameHighlight);
|
||||
break;
|
||||
case GDK_ENTER_NOTIFY:
|
||||
ret = enter_handler (item, event, AudioRegionViewNameHighlight);
|
||||
ret = enter_handler (item, event, RegionViewNameHighlight);
|
||||
break;
|
||||
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
ret = leave_handler (item, event, AudioRegionViewNameHighlight);
|
||||
ret = leave_handler (item, event, RegionViewNameHighlight);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -732,7 +735,7 @@ Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::
|
||||
}
|
||||
|
||||
bool
|
||||
Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView* rv)
|
||||
Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView* rv)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
@@ -744,20 +747,20 @@ Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item
|
||||
clicked_control_point = 0;
|
||||
clicked_trackview = &clicked_regionview->get_time_axis_view();
|
||||
clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
|
||||
ret = button_press_handler (item, event, AudioRegionViewName);
|
||||
ret = button_press_handler (item, event, RegionViewName);
|
||||
break;
|
||||
case GDK_BUTTON_RELEASE:
|
||||
ret = button_release_handler (item, event, AudioRegionViewName);
|
||||
ret = button_release_handler (item, event, RegionViewName);
|
||||
break;
|
||||
case GDK_MOTION_NOTIFY:
|
||||
ret = motion_handler (item, event, AudioRegionViewName);
|
||||
ret = motion_handler (item, event, RegionViewName);
|
||||
break;
|
||||
case GDK_ENTER_NOTIFY:
|
||||
ret = enter_handler (item, event, AudioRegionViewName);
|
||||
ret = enter_handler (item, event, RegionViewName);
|
||||
break;
|
||||
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
ret = leave_handler (item, event, AudioRegionViewName);
|
||||
ret = leave_handler (item, event, RegionViewName);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "selection.h"
|
||||
#include "time_axis_view.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "regionview.h"
|
||||
#include "audio_region_view.h"
|
||||
|
||||
#include <pbd/pthread_utils.h>
|
||||
#include <ardour/types.h>
|
||||
@@ -92,12 +92,12 @@ Editor::export_region ()
|
||||
return;
|
||||
}
|
||||
|
||||
ExportDialog* dialog = new ExportRegionDialog (*this, &clicked_regionview->region);
|
||||
ExportDialog* dialog = new ExportRegionDialog (*this, &clicked_regionview->region());
|
||||
|
||||
dialog->connect_to_session (session);
|
||||
dialog->set_range (
|
||||
clicked_regionview->region.first_frame(),
|
||||
clicked_regionview->region.last_frame());
|
||||
clicked_regionview->region().first_frame(),
|
||||
clicked_regionview->region().last_frame());
|
||||
dialog->start_export();
|
||||
}
|
||||
|
||||
@@ -123,24 +123,26 @@ Editor::export_range_markers ()
|
||||
}
|
||||
|
||||
int
|
||||
Editor::write_region_selection (AudioRegionSelection& regions)
|
||||
Editor::write_region_selection (RegionSelection& regions)
|
||||
{
|
||||
for (AudioRegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
|
||||
if (write_region ("", (*i)->region) == false) {
|
||||
return -1;
|
||||
}
|
||||
for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
|
||||
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*i);
|
||||
if (arv)
|
||||
if (write_region ("", arv->audio_region()) == false)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Editor::bounce_region_selection ()
|
||||
{
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
|
||||
AudioRegion& region ((*i)->region);
|
||||
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(&(*i)->get_time_axis_view());
|
||||
AudioTrack* track = dynamic_cast<AudioTrack*>(atv->route().get());
|
||||
Region& region ((*i)->region());
|
||||
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(&(*i)->get_time_axis_view());
|
||||
Track* track = dynamic_cast<Track*>(rtv->route().get());
|
||||
|
||||
InterThreadInfo itt;
|
||||
|
||||
@@ -287,7 +289,7 @@ Editor::write_audio_selection (TimeSelection& ts)
|
||||
|
||||
if (atv->is_audio_track()) {
|
||||
|
||||
Playlist* playlist = atv->get_diskstream()->playlist();
|
||||
AudioPlaylist* playlist = dynamic_cast<AudioPlaylist*>(atv->get_diskstream()->playlist());
|
||||
|
||||
if (playlist && write_audio_range (*playlist, atv->get_diskstream()->n_channels(), ts) == 0) {
|
||||
ret = -1;
|
||||
@@ -300,7 +302,7 @@ Editor::write_audio_selection (TimeSelection& ts)
|
||||
}
|
||||
|
||||
bool
|
||||
Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRange>& range)
|
||||
Editor::write_audio_range (AudioPlaylist& playlist, uint32_t channels, list<AudioRange>& range)
|
||||
{
|
||||
AudioFileSource* fs;
|
||||
const jack_nframes_t chunk_size = 4096;
|
||||
@@ -435,7 +437,7 @@ Editor::write_selection ()
|
||||
{
|
||||
if (!selection->time.empty()) {
|
||||
write_audio_selection (selection->time);
|
||||
} else if (!selection->audio_regions.empty()) {
|
||||
write_region_selection (selection->audio_regions);
|
||||
} else if (!selection->regions.empty()) {
|
||||
write_region_selection (selection->regions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ enum ItemType {
|
||||
TempoMarkerItem,
|
||||
MeterBarItem,
|
||||
TempoBarItem,
|
||||
AudioRegionViewNameHighlight,
|
||||
AudioRegionViewName,
|
||||
RegionViewNameHighlight,
|
||||
RegionViewName,
|
||||
StartSelectionTrimItem,
|
||||
EndSelectionTrimItem,
|
||||
AutomationTrackItem,
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <ardour/playlist.h>
|
||||
|
||||
#include "editor.h"
|
||||
#include "regionview.h"
|
||||
#include "region_view.h"
|
||||
#include "selection.h"
|
||||
|
||||
#include "i18n.h"
|
||||
@@ -81,10 +81,10 @@ Editor::kbd_do_split (GdkEvent* ev)
|
||||
jack_nframes_t where = event_frame (ev);
|
||||
|
||||
if (entered_regionview) {
|
||||
if (selection->audio_regions.find (entered_regionview) != selection->audio_regions.end()) {
|
||||
split_regions_at (where, selection->audio_regions);
|
||||
if (selection->regions.find (entered_regionview) != selection->regions.end()) {
|
||||
split_regions_at (where, selection->regions);
|
||||
} else {
|
||||
AudioRegionSelection s;
|
||||
RegionSelection s;
|
||||
s.add (entered_regionview);
|
||||
split_regions_at (where, s);
|
||||
}
|
||||
@@ -102,11 +102,11 @@ Editor::kbd_mute_unmute_region ()
|
||||
{
|
||||
if (entered_regionview) {
|
||||
begin_reversible_command (_("mute region"));
|
||||
session->add_undo (entered_regionview->region.playlist()->get_memento());
|
||||
session->add_undo (entered_regionview->region().playlist()->get_memento());
|
||||
|
||||
entered_regionview->region.set_muted (!entered_regionview->region.muted());
|
||||
entered_regionview->region().set_muted (!entered_regionview->region().muted());
|
||||
|
||||
session->add_redo_no_execute (entered_regionview->region.playlist()->get_memento());
|
||||
session->add_redo_no_execute (entered_regionview->region().playlist()->get_memento());
|
||||
commit_reversible_command();
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@ Editor::kbd_do_set_sync_position (GdkEvent* ev)
|
||||
snap_to (where);
|
||||
|
||||
if (entered_regionview) {
|
||||
set_a_regions_sync_position (entered_regionview->region, where);
|
||||
set_a_regions_sync_position (entered_regionview->region(), where);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "ardour_ui.h"
|
||||
#include "editor.h"
|
||||
#include "time_axis_view.h"
|
||||
#include "regionview.h"
|
||||
#include "region_view.h"
|
||||
#include "selection.h"
|
||||
|
||||
#include "i18n.h"
|
||||
@@ -66,7 +66,7 @@ Editor::keyboard_selection_begin ()
|
||||
void
|
||||
Editor::keyboard_duplicate_region ()
|
||||
{
|
||||
if (selection->audio_regions.empty()) {
|
||||
if (selection->regions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -74,9 +74,9 @@ Editor::keyboard_duplicate_region ()
|
||||
bool was_floating;
|
||||
|
||||
if (get_prefix (prefix, was_floating) == 0) {
|
||||
duplicate_some_regions (selection->audio_regions, prefix);
|
||||
duplicate_some_regions (selection->regions, prefix);
|
||||
} else {
|
||||
duplicate_some_regions (selection->audio_regions, 1);
|
||||
duplicate_some_regions (selection->regions, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -714,9 +714,9 @@ Editor::marker_menu_set_from_selection ()
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!selection->audio_regions.empty()) {
|
||||
l->set_start (selection->audio_regions.start());
|
||||
l->set_end (selection->audio_regions.end_frame());
|
||||
if (!selection->regions.empty()) {
|
||||
l->set_start (selection->regions.start());
|
||||
l->set_end (selection->regions.end_frame());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,8 +270,6 @@ Editor::session_going_away ()
|
||||
group_model->clear ();
|
||||
|
||||
edit_cursor_clock.set_session (0);
|
||||
selection_start_clock.set_session (0);
|
||||
selection_end_clock.set_session (0);
|
||||
zoom_range_clock.set_session (0);
|
||||
nudge_clock.set_session (0);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <stdint.h>
|
||||
#include <cmath>
|
||||
@@ -32,7 +33,7 @@
|
||||
#include "editor.h"
|
||||
#include "time_axis_view.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "regionview.h"
|
||||
#include "audio_region_view.h"
|
||||
#include "marker.h"
|
||||
#include "streamview.h"
|
||||
#include "region_gain_line.h"
|
||||
@@ -182,7 +183,7 @@ Editor::set_mouse_mode (MouseMode m, bool force)
|
||||
show the object (region) selection.
|
||||
*/
|
||||
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
(*i)->set_should_show_selection (true);
|
||||
}
|
||||
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
|
||||
@@ -319,8 +320,8 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it
|
||||
commit = (c1 || c2);
|
||||
break;
|
||||
|
||||
case AudioRegionViewNameHighlight:
|
||||
case AudioRegionViewName:
|
||||
case RegionViewNameHighlight:
|
||||
case RegionViewName:
|
||||
c1 = set_selected_track_from_click (press, op, true, true);
|
||||
c2 = set_selected_regionview_from_click (press, op, true);
|
||||
commit = (c1 || c2);
|
||||
@@ -521,12 +522,12 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
|
||||
}
|
||||
break;
|
||||
|
||||
case AudioRegionViewNameHighlight:
|
||||
case RegionViewNameHighlight:
|
||||
start_trim (item, event);
|
||||
return true;
|
||||
break;
|
||||
|
||||
case AudioRegionViewName:
|
||||
case RegionViewName:
|
||||
/* rename happens on edit clicks */
|
||||
start_trim (clicked_regionview->get_name_highlight(), event);
|
||||
return true;
|
||||
@@ -692,12 +693,12 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
|
||||
|
||||
|
||||
switch (item_type) {
|
||||
case AudioRegionViewNameHighlight:
|
||||
case RegionViewNameHighlight:
|
||||
start_trim (item, event);
|
||||
return true;
|
||||
break;
|
||||
|
||||
case AudioRegionViewName:
|
||||
case RegionViewName:
|
||||
start_trim (clicked_regionview->get_name_highlight(), event);
|
||||
return true;
|
||||
break;
|
||||
@@ -853,7 +854,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||
edit_meter_marker (item);
|
||||
break;
|
||||
|
||||
case AudioRegionViewName:
|
||||
case RegionViewName:
|
||||
if (clicked_regionview->name_active()) {
|
||||
return mouse_rename_region (item, event);
|
||||
}
|
||||
@@ -888,8 +889,8 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||
break;
|
||||
|
||||
case RegionItem:
|
||||
case AudioRegionViewNameHighlight:
|
||||
case AudioRegionViewName:
|
||||
case RegionViewNameHighlight:
|
||||
case RegionViewName:
|
||||
popup_track_context_menu (1, event->button.time, item_type, false, where);
|
||||
break;
|
||||
|
||||
@@ -1047,9 +1048,13 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||
break;
|
||||
|
||||
case MouseGain:
|
||||
// Gain only makes sense for audio regions
|
||||
if ( ! dynamic_cast<AudioRegionView*>(clicked_regionview))
|
||||
break;
|
||||
|
||||
switch (item_type) {
|
||||
case RegionItem:
|
||||
clicked_regionview->add_gain_point_event (item, event);
|
||||
dynamic_cast<AudioRegionView*>(clicked_regionview)->add_gain_point_event (item, event);
|
||||
return true;
|
||||
break;
|
||||
|
||||
@@ -1203,7 +1208,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
||||
}
|
||||
break;
|
||||
|
||||
case AudioRegionViewNameHighlight:
|
||||
case RegionViewNameHighlight:
|
||||
if (is_drawable() && mouse_mode == MouseObject) {
|
||||
track_canvas.get_window()->set_cursor (*trimmer_cursor);
|
||||
}
|
||||
@@ -1230,11 +1235,11 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
||||
}
|
||||
break;
|
||||
|
||||
case AudioRegionViewName:
|
||||
case RegionViewName:
|
||||
|
||||
/* when the name is not an active item, the entire name highlight is for trimming */
|
||||
|
||||
if (!reinterpret_cast<AudioRegionView *> (item->get_data ("regionview"))->name_active()) {
|
||||
if (!reinterpret_cast<RegionView *> (item->get_data ("regionview"))->name_active()) {
|
||||
if (mouse_mode == MouseObject && is_drawable()) {
|
||||
track_canvas.get_window()->set_cursor (*trimmer_cursor);
|
||||
}
|
||||
@@ -1339,7 +1344,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
||||
ControlPoint* cp;
|
||||
Marker *marker;
|
||||
Location *loc;
|
||||
AudioRegionView* rv;
|
||||
RegionView* rv;
|
||||
bool is_start;
|
||||
|
||||
switch (item_type) {
|
||||
@@ -1361,7 +1366,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
||||
hide_verbose_canvas_cursor ();
|
||||
break;
|
||||
|
||||
case AudioRegionViewNameHighlight:
|
||||
case RegionViewNameHighlight:
|
||||
case StartSelectionTrimItem:
|
||||
case EndSelectionTrimItem:
|
||||
case EditCursorItem:
|
||||
@@ -1392,9 +1397,9 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
||||
}
|
||||
break;
|
||||
|
||||
case AudioRegionViewName:
|
||||
case RegionViewName:
|
||||
/* see enter_handler() for notes */
|
||||
if (!reinterpret_cast<AudioRegionView *> (item->get_data ("regionview"))->name_active()) {
|
||||
if (!reinterpret_cast<RegionView *> (item->get_data ("regionview"))->name_active()) {
|
||||
if (is_drawable() && mouse_mode == MouseObject) {
|
||||
track_canvas.get_window()->set_cursor (*current_canvas_cursor);
|
||||
}
|
||||
@@ -1429,7 +1434,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
|
||||
|
||||
case FadeInHandleItem:
|
||||
case FadeOutHandleItem:
|
||||
rv = static_cast<AudioRegionView*>(item->get_data ("regionview"));
|
||||
rv = static_cast<RegionView*>(item->get_data ("regionview"));
|
||||
{
|
||||
ArdourCanvas::SimpleRect *rect = dynamic_cast<ArdourCanvas::SimpleRect *> (item);
|
||||
if (rect) {
|
||||
@@ -1524,7 +1529,7 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
|
||||
case PanAutomationControlPointItem:
|
||||
case TempoMarkerItem:
|
||||
case MeterMarkerItem:
|
||||
case AudioRegionViewNameHighlight:
|
||||
case RegionViewNameHighlight:
|
||||
case StartSelectionTrimItem:
|
||||
case EndSelectionTrimItem:
|
||||
case SelectionItem:
|
||||
@@ -1745,7 +1750,7 @@ Editor::start_fade_in_grab (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
|
||||
AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
|
||||
|
||||
drag_info.pointer_frame_offset = drag_info.grab_frame - ((jack_nframes_t) arv->region.fade_in().back()->when + arv->region.position());
|
||||
drag_info.pointer_frame_offset = drag_info.grab_frame - ((jack_nframes_t) arv->audio_region().fade_in().back()->when + arv->region().position());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1766,17 +1771,17 @@ Editor::fade_in_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
snap_to (pos);
|
||||
}
|
||||
|
||||
if (pos < (arv->region.position() + 64)) {
|
||||
if (pos < (arv->region().position() + 64)) {
|
||||
fade_length = 64; // this should be a minimum defined somewhere
|
||||
} else if (pos > arv->region.last_frame()) {
|
||||
fade_length = arv->region.length();
|
||||
} else if (pos > arv->region().last_frame()) {
|
||||
fade_length = arv->region().length();
|
||||
} else {
|
||||
fade_length = pos - arv->region.position();
|
||||
fade_length = pos - arv->region().position();
|
||||
}
|
||||
|
||||
arv->reset_fade_in_shape_width (fade_length);
|
||||
|
||||
show_verbose_duration_cursor (arv->region.position(), arv->region.position() + fade_length, 10);
|
||||
show_verbose_duration_cursor (arv->region().position(), arv->region().position() + fade_length, 10);
|
||||
|
||||
drag_info.first_move = false;
|
||||
}
|
||||
@@ -1801,20 +1806,20 @@ Editor::fade_in_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* even
|
||||
snap_to (pos);
|
||||
}
|
||||
|
||||
if (pos < (arv->region.position() + 64)) {
|
||||
if (pos < (arv->region().position() + 64)) {
|
||||
fade_length = 64; // this should be a minimum defined somewhere
|
||||
}
|
||||
else if (pos > arv->region.last_frame()) {
|
||||
fade_length = arv->region.length();
|
||||
else if (pos > arv->region().last_frame()) {
|
||||
fade_length = arv->region().length();
|
||||
}
|
||||
else {
|
||||
fade_length = pos - arv->region.position();
|
||||
fade_length = pos - arv->region().position();
|
||||
}
|
||||
|
||||
begin_reversible_command (_("change fade in length"));
|
||||
session->add_undo (arv->region.get_memento());
|
||||
arv->region.set_fade_in_length (fade_length);
|
||||
session->add_redo_no_execute (arv->region.get_memento());
|
||||
session->add_undo (arv->region().get_memento());
|
||||
arv->audio_region().set_fade_in_length (fade_length);
|
||||
session->add_redo_no_execute (arv->region().get_memento());
|
||||
commit_reversible_command ();
|
||||
fade_in_drag_motion_callback (item, event);
|
||||
}
|
||||
@@ -1835,7 +1840,7 @@ Editor::start_fade_out_grab (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
|
||||
AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
|
||||
|
||||
drag_info.pointer_frame_offset = drag_info.grab_frame - (arv->region.length() - (jack_nframes_t) arv->region.fade_out().back()->when + arv->region.position());
|
||||
drag_info.pointer_frame_offset = drag_info.grab_frame - (arv->region().length() - (jack_nframes_t) arv->audio_region().fade_out().back()->when + arv->region().position());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1856,19 +1861,19 @@ Editor::fade_out_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event
|
||||
snap_to (pos);
|
||||
}
|
||||
|
||||
if (pos > (arv->region.last_frame() - 64)) {
|
||||
if (pos > (arv->region().last_frame() - 64)) {
|
||||
fade_length = 64; // this should really be a minimum fade defined somewhere
|
||||
}
|
||||
else if (pos < arv->region.position()) {
|
||||
fade_length = arv->region.length();
|
||||
else if (pos < arv->region().position()) {
|
||||
fade_length = arv->region().length();
|
||||
}
|
||||
else {
|
||||
fade_length = arv->region.last_frame() - pos;
|
||||
fade_length = arv->region().last_frame() - pos;
|
||||
}
|
||||
|
||||
arv->reset_fade_out_shape_width (fade_length);
|
||||
|
||||
show_verbose_duration_cursor (arv->region.last_frame() - fade_length, arv->region.last_frame(), 10);
|
||||
show_verbose_duration_cursor (arv->region().last_frame() - fade_length, arv->region().last_frame(), 10);
|
||||
|
||||
drag_info.first_move = false;
|
||||
}
|
||||
@@ -1893,20 +1898,20 @@ Editor::fade_out_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* eve
|
||||
snap_to (pos);
|
||||
}
|
||||
|
||||
if (pos > (arv->region.last_frame() - 64)) {
|
||||
if (pos > (arv->region().last_frame() - 64)) {
|
||||
fade_length = 64; // this should really be a minimum fade defined somewhere
|
||||
}
|
||||
else if (pos < arv->region.position()) {
|
||||
fade_length = arv->region.length();
|
||||
else if (pos < arv->region().position()) {
|
||||
fade_length = arv->region().length();
|
||||
}
|
||||
else {
|
||||
fade_length = arv->region.last_frame() - pos;
|
||||
fade_length = arv->region().last_frame() - pos;
|
||||
}
|
||||
|
||||
begin_reversible_command (_("change fade out length"));
|
||||
session->add_undo (arv->region.get_memento());
|
||||
arv->region.set_fade_out_length (fade_length);
|
||||
session->add_redo_no_execute (arv->region.get_memento());
|
||||
session->add_undo (arv->region().get_memento());
|
||||
arv->audio_region().set_fade_out_length (fade_length);
|
||||
session->add_redo_no_execute (arv->region().get_memento());
|
||||
commit_reversible_command ();
|
||||
|
||||
fade_out_drag_motion_callback (item, event);
|
||||
@@ -2551,7 +2556,8 @@ Editor::start_line_grab_from_regionview (ArdourCanvas::Item* item, GdkEvent* eve
|
||||
{
|
||||
switch (mouse_mode) {
|
||||
case MouseGain:
|
||||
start_line_grab (clicked_regionview->get_gain_line(), event);
|
||||
assert(dynamic_cast<AudioRegionView*>(clicked_regionview));
|
||||
start_line_grab (dynamic_cast<AudioRegionView*>(clicked_regionview)->get_gain_line(), event);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -2645,7 +2651,7 @@ Editor::line_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
void
|
||||
Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
{
|
||||
if (selection->audio_regions.empty() || clicked_regionview == 0) {
|
||||
if (selection->regions.empty() || clicked_regionview == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2659,13 +2665,13 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
|
||||
double speed = 1.0;
|
||||
TimeAxisView* tvp = clicked_trackview;
|
||||
AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp);
|
||||
RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp);
|
||||
|
||||
if (tv && tv->is_audio_track()) {
|
||||
speed = tv->get_diskstream()->speed();
|
||||
}
|
||||
|
||||
drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region.position() / speed);
|
||||
drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region().position() / speed);
|
||||
drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
|
||||
drag_info.last_trackview = &clicked_regionview->get_time_axis_view();
|
||||
// we want a move threshold
|
||||
@@ -2679,7 +2685,7 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
void
|
||||
Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
{
|
||||
if (selection->audio_regions.empty() || clicked_regionview == 0) {
|
||||
if (selection->regions.empty() || clicked_regionview == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2690,7 +2696,7 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
start_grab(event);
|
||||
|
||||
TimeAxisView* tv = &clicked_regionview->get_time_axis_view();
|
||||
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(tv);
|
||||
RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(tv);
|
||||
double speed = 1.0;
|
||||
|
||||
if (atv && atv->is_audio_track()) {
|
||||
@@ -2698,7 +2704,7 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
}
|
||||
|
||||
drag_info.last_trackview = &clicked_regionview->get_time_axis_view();
|
||||
drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region.position() / speed);
|
||||
drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region().position() / speed);
|
||||
drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
|
||||
// we want a move threshold
|
||||
drag_info.want_move_threshold = true;
|
||||
@@ -2709,7 +2715,7 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
void
|
||||
Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
{
|
||||
if (selection->audio_regions.empty() || clicked_regionview == 0) {
|
||||
if (selection->regions.empty() || clicked_regionview == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2723,13 +2729,13 @@ Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
|
||||
double speed = 1.0;
|
||||
TimeAxisView* tvp = clicked_trackview;
|
||||
AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp);
|
||||
RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp);
|
||||
|
||||
if (tv && tv->is_audio_track()) {
|
||||
speed = tv->get_diskstream()->speed();
|
||||
}
|
||||
|
||||
drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region.position() / speed);
|
||||
drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region().position() / speed);
|
||||
drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
|
||||
drag_info.last_trackview = &clicked_regionview->get_time_axis_view();
|
||||
// we want a move threshold
|
||||
@@ -2744,7 +2750,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
{
|
||||
double x_delta;
|
||||
double y_delta = 0;
|
||||
AudioRegionView *rv = reinterpret_cast<AudioRegionView*> (drag_info.data);
|
||||
RegionView* rv = reinterpret_cast<RegionView*> (drag_info.data);
|
||||
jack_nframes_t pending_region_position = 0;
|
||||
int32_t pointer_y_span = 0, canvas_pointer_y_span = 0, original_pointer_order;
|
||||
int32_t visible_y_high = 0, visible_y_low = 512; //high meaning higher numbered.. not the height on the screen
|
||||
@@ -2764,18 +2770,18 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
|
||||
/* duplicate the region(s) */
|
||||
|
||||
vector<AudioRegionView*> new_regionviews;
|
||||
vector<RegionView*> new_regionviews;
|
||||
|
||||
set<Playlist*> affected_playlists;
|
||||
pair<set<Playlist*>::iterator,bool> insert_result;
|
||||
|
||||
for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
|
||||
AudioRegionView* rv;
|
||||
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
|
||||
RegionView* rv;
|
||||
|
||||
rv = (*i);
|
||||
|
||||
Playlist* to_playlist = rv->region.playlist();
|
||||
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(&rv->get_time_axis_view());
|
||||
Playlist* to_playlist = rv->region().playlist();
|
||||
RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(&rv->get_time_axis_view());
|
||||
|
||||
insert_result = affected_playlists.insert (to_playlist);
|
||||
if (insert_result.second) {
|
||||
@@ -2784,18 +2790,21 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
|
||||
latest_regionview = 0;
|
||||
|
||||
sigc::connection c = atv->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
|
||||
sigc::connection c = atv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
|
||||
|
||||
/* create a new region with the same name.
|
||||
*/
|
||||
|
||||
AudioRegion* newregion = new AudioRegion (rv->region);
|
||||
/* create a new region with the same name. */
|
||||
|
||||
// FIXME: ew. need a (virtual) Region::duplicate() or something?
|
||||
Region* newregion = NULL;
|
||||
if (dynamic_cast<AudioRegion*>(&rv->region()))
|
||||
newregion = new AudioRegion (dynamic_cast<AudioRegion&>(rv->region()));
|
||||
assert(newregion);
|
||||
|
||||
/* if the original region was locked, we don't care */
|
||||
|
||||
newregion->set_locked (false);
|
||||
|
||||
to_playlist->add_region (*newregion, (jack_nframes_t) (rv->region.position() * atv->get_diskstream()->speed()));
|
||||
to_playlist->add_region (*newregion, (jack_nframes_t) (rv->region().position() * atv->get_diskstream()->speed()));
|
||||
|
||||
c.disconnect ();
|
||||
|
||||
@@ -2907,16 +2916,15 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
|
||||
AudioRegionView* rv2;
|
||||
rv2 = (*i);
|
||||
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
|
||||
RegionView* rv2 = (*i);
|
||||
double ix1, ix2, iy1, iy2;
|
||||
int32_t n = 0;
|
||||
|
||||
rv2->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
|
||||
rv2->get_canvas_group()->i2w (ix1, iy1);
|
||||
TimeAxisView* tvp2 = trackview_by_y_position (iy1);
|
||||
AudioTimeAxisView* atv2 = dynamic_cast<AudioTimeAxisView*>(tvp2);
|
||||
RouteTimeAxisView* atv2 = dynamic_cast<RouteTimeAxisView*>(tvp2);
|
||||
|
||||
if (atv2->order != original_pointer_order) {
|
||||
/* this isn't the pointer track */
|
||||
@@ -3011,8 +3019,8 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
|
||||
pending_region_position = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
|
||||
|
||||
sync_offset = rv->region.sync_offset (sync_dir);
|
||||
sync_frame = rv->region.adjust_to_sync (pending_region_position);
|
||||
sync_offset = rv->region().sync_offset (sync_dir);
|
||||
sync_frame = rv->region().adjust_to_sync (pending_region_position);
|
||||
|
||||
/* we snap if the snap modifier is not enabled.
|
||||
*/
|
||||
@@ -3031,7 +3039,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
pending_region_position = 0;
|
||||
}
|
||||
|
||||
if (pending_region_position > max_frames - rv->region.length()) {
|
||||
if (pending_region_position > max_frames - rv->region().length()) {
|
||||
pending_region_position = drag_info.last_frame_position;
|
||||
}
|
||||
|
||||
@@ -3073,14 +3081,11 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
}
|
||||
|
||||
if (x_delta < 0) {
|
||||
for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
|
||||
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
|
||||
|
||||
AudioRegionView* rv2;
|
||||
rv2 = (*i);
|
||||
RegionView* rv2 = (*i);
|
||||
|
||||
/* if any regionview is at zero, we need to know so we can
|
||||
stop further leftward motion.
|
||||
*/
|
||||
// If any regionview is at zero, we need to know so we can stop further leftward motion.
|
||||
|
||||
double ix1, ix2, iy1, iy2;
|
||||
rv2->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
|
||||
@@ -3098,12 +3103,11 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
************************************************************/
|
||||
|
||||
pair<set<Playlist*>::iterator,bool> insert_result;
|
||||
const list<AudioRegionView*>& layered_regions = selection->audio_regions.by_layer();
|
||||
const list<RegionView*>& layered_regions = selection->regions.by_layer();
|
||||
|
||||
for (list<AudioRegionView*>::const_iterator i = layered_regions.begin(); i != layered_regions.end(); ++i) {
|
||||
for (list<RegionView*>::const_iterator i = layered_regions.begin(); i != layered_regions.end(); ++i) {
|
||||
|
||||
AudioRegionView* rv;
|
||||
rv = (*i);
|
||||
RegionView* rv = (*i);
|
||||
double ix1, ix2, iy1, iy2;
|
||||
int32_t temp_pointer_y_span = pointer_y_span;
|
||||
|
||||
@@ -3184,8 +3188,8 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
if (-x_delta > ix1) {
|
||||
x_delta = -ix1;
|
||||
}
|
||||
} else if ((x_delta > 0) &&(rv->region.last_frame() > max_frames - x_delta)) {
|
||||
x_delta = max_frames - rv->region.last_frame();
|
||||
} else if ((x_delta > 0) &&(rv->region().last_frame() > max_frames - x_delta)) {
|
||||
x_delta = max_frames - rv->region().last_frame();
|
||||
}
|
||||
|
||||
if (drag_info.first_move) {
|
||||
@@ -3210,7 +3214,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
|
||||
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&rv->get_time_axis_view());
|
||||
if (atv && atv->is_audio_track()) {
|
||||
AudioPlaylist* pl = atv->get_diskstream()->playlist();
|
||||
AudioPlaylist* pl = dynamic_cast<AudioPlaylist*>(atv->get_diskstream()->playlist());
|
||||
if (pl) {
|
||||
/* only freeze and capture state once */
|
||||
|
||||
@@ -3246,11 +3250,11 @@ void
|
||||
Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
{
|
||||
jack_nframes_t where;
|
||||
AudioRegionView* rv = reinterpret_cast<AudioRegionView *> (drag_info.data);
|
||||
RegionView* rv = reinterpret_cast<RegionView *> (drag_info.data);
|
||||
pair<set<Playlist*>::iterator,bool> insert_result;
|
||||
bool nocommit = true;
|
||||
double speed;
|
||||
AudioTimeAxisView* atv;
|
||||
RouteTimeAxisView* atv;
|
||||
bool regionview_y_movement;
|
||||
bool regionview_x_movement;
|
||||
|
||||
@@ -3284,7 +3288,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
|
||||
speed = atv->get_diskstream()->speed();
|
||||
}
|
||||
|
||||
regionview_x_movement = (drag_info.last_frame_position != (jack_nframes_t) (rv->region.position()/speed));
|
||||
regionview_x_movement = (drag_info.last_frame_position != (jack_nframes_t) (rv->region().position()/speed));
|
||||
regionview_y_movement = (drag_info.last_trackview != &rv->get_time_axis_view());
|
||||
|
||||
//printf ("last_frame: %s position is %lu %g\n", rv->get_time_axis_view().name().c_str(), drag_info.last_frame_position, speed);
|
||||
@@ -3294,13 +3298,13 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
|
||||
|
||||
/* motion between tracks */
|
||||
|
||||
list<AudioRegionView*> new_selection;
|
||||
list<RegionView*> new_selection;
|
||||
|
||||
/* moved to a different audio track. */
|
||||
|
||||
for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ) {
|
||||
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ) {
|
||||
|
||||
AudioRegionView* rv2 = (*i);
|
||||
RegionView* rv2 = (*i);
|
||||
|
||||
/* the region that used to be in the old playlist is not
|
||||
moved to the new one - we make a copy of it. as a result,
|
||||
@@ -3317,7 +3321,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
|
||||
|
||||
/* first, freeze the target tracks */
|
||||
|
||||
for (list<AudioRegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) {
|
||||
for (list<RegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) {
|
||||
|
||||
Playlist* from_playlist;
|
||||
Playlist* to_playlist;
|
||||
@@ -3329,7 +3333,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
|
||||
TimeAxisView* tvp2 = trackview_by_y_position (iy1);
|
||||
AudioTimeAxisView* atv2 = dynamic_cast<AudioTimeAxisView*>(tvp2);
|
||||
|
||||
from_playlist = (*i)->region.playlist();
|
||||
from_playlist = (*i)->region().playlist();
|
||||
to_playlist = atv2->playlist();
|
||||
|
||||
/* the from_playlist was frozen in the "first_move" case
|
||||
@@ -3352,7 +3356,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
|
||||
|
||||
/* now do it again with the actual operations */
|
||||
|
||||
for (list<AudioRegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) {
|
||||
for (list<RegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) {
|
||||
|
||||
Playlist* from_playlist;
|
||||
Playlist* to_playlist;
|
||||
@@ -3364,17 +3368,17 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
|
||||
TimeAxisView* tvp2 = trackview_by_y_position (iy1);
|
||||
AudioTimeAxisView* atv2 = dynamic_cast<AudioTimeAxisView*>(tvp2);
|
||||
|
||||
from_playlist = (*i)->region.playlist();
|
||||
from_playlist = (*i)->region().playlist();
|
||||
to_playlist = atv2->playlist();
|
||||
|
||||
latest_regionview = 0;
|
||||
|
||||
where = (jack_nframes_t) (unit_to_frame (ix1) * speed);
|
||||
Region* new_region = createRegion ((*i)->region);
|
||||
Region* new_region = createRegion ((*i)->region());
|
||||
|
||||
from_playlist->remove_region (&((*i)->region));
|
||||
from_playlist->remove_region (&((*i)->region()));
|
||||
|
||||
sigc::connection c = atv2->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
|
||||
sigc::connection c = atv2->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
|
||||
to_playlist->add_region (*new_region, where);
|
||||
c.disconnect ();
|
||||
|
||||
@@ -3387,11 +3391,11 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
|
||||
|
||||
/* motion within a single track */
|
||||
|
||||
for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
|
||||
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
|
||||
|
||||
rv = (*i);
|
||||
|
||||
if (rv->region.locked()) {
|
||||
if (rv->region().locked()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3413,14 +3417,14 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
|
||||
|
||||
} else {
|
||||
|
||||
where = rv->region.position();
|
||||
where = rv->region().position();
|
||||
}
|
||||
|
||||
rv->get_time_axis_view().reveal_dependent_views (*rv);
|
||||
|
||||
/* no need to add an undo here, we did that when we added this playlist to motion_frozen playlists */
|
||||
|
||||
rv->region.set_position (where, (void *) this);
|
||||
rv->region().set_position (where, (void *) this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3454,15 +3458,15 @@ Editor::region_view_item_click (AudioRegionView& rv, GdkEventButton* event)
|
||||
|
||||
if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Alt))) {
|
||||
|
||||
align_region (rv.region, SyncPoint, (jack_nframes_t) (edit_cursor->current_frame * speed));
|
||||
align_region (rv.region(), SyncPoint, (jack_nframes_t) (edit_cursor->current_frame * speed));
|
||||
|
||||
} else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) {
|
||||
|
||||
align_region (rv.region, End, (jack_nframes_t) (edit_cursor->current_frame * speed));
|
||||
align_region (rv.region(), End, (jack_nframes_t) (edit_cursor->current_frame * speed));
|
||||
|
||||
} else {
|
||||
|
||||
align_region (rv.region, Start, (jack_nframes_t) (edit_cursor->current_frame * speed));
|
||||
align_region (rv.region(), Start, (jack_nframes_t) (edit_cursor->current_frame * speed));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3579,7 +3583,7 @@ Editor::show_verbose_duration_cursor (jack_nframes_t start, jack_nframes_t end,
|
||||
}
|
||||
|
||||
void
|
||||
Editor::collect_new_region_view (AudioRegionView* rv)
|
||||
Editor::collect_new_region_view (RegionView* rv)
|
||||
{
|
||||
latest_regionview = rv;
|
||||
}
|
||||
@@ -3612,7 +3616,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
*/
|
||||
|
||||
latest_regionview = 0;
|
||||
sigc::connection c = clicked_audio_trackview->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
|
||||
sigc::connection c = clicked_audio_trackview->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
|
||||
|
||||
/* A selection grab currently creates two undo/redo operations, one for
|
||||
creating the new region and another for moving it.
|
||||
@@ -3647,7 +3651,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
start_grab (event);
|
||||
|
||||
drag_info.last_trackview = clicked_trackview;
|
||||
drag_info.last_frame_position = latest_regionview->region.position();
|
||||
drag_info.last_frame_position = latest_regionview->region().position();
|
||||
drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
|
||||
|
||||
show_verbose_time_cursor (drag_info.last_frame_position, 10);
|
||||
@@ -3888,9 +3892,9 @@ Editor::start_trim (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
speed = tv->get_diskstream()->speed();
|
||||
}
|
||||
|
||||
jack_nframes_t region_start = (jack_nframes_t) (clicked_regionview->region.position() / speed);
|
||||
jack_nframes_t region_end = (jack_nframes_t) (clicked_regionview->region.last_frame() / speed);
|
||||
jack_nframes_t region_length = (jack_nframes_t) (clicked_regionview->region.length() / speed);
|
||||
jack_nframes_t region_start = (jack_nframes_t) (clicked_regionview->region().position() / speed);
|
||||
jack_nframes_t region_end = (jack_nframes_t) (clicked_regionview->region().last_frame() / speed);
|
||||
jack_nframes_t region_length = (jack_nframes_t) (clicked_regionview->region().length() / speed);
|
||||
|
||||
motion_frozen_playlists.clear();
|
||||
|
||||
@@ -3930,7 +3934,7 @@ Editor::start_trim (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
void
|
||||
Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
{
|
||||
AudioRegionView* rv = clicked_regionview;
|
||||
RegionView* rv = clicked_regionview;
|
||||
jack_nframes_t frame_delta = 0;
|
||||
bool left_direction;
|
||||
bool obey_snap = !Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier());
|
||||
@@ -3942,7 +3946,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
|
||||
double speed = 1.0;
|
||||
TimeAxisView* tvp = clicked_trackview;
|
||||
AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp);
|
||||
RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp);
|
||||
pair<set<Playlist*>::iterator,bool> insert_result;
|
||||
|
||||
if (tv && tv->is_audio_track()) {
|
||||
@@ -3981,11 +3985,14 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
|
||||
begin_reversible_command (trim_type);
|
||||
|
||||
for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
|
||||
(*i)->region.freeze ();
|
||||
(*i)->temporarily_hide_envelope ();
|
||||
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
|
||||
(*i)->region().freeze ();
|
||||
|
||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
|
||||
if (arv)
|
||||
arv->temporarily_hide_envelope ();
|
||||
|
||||
Playlist * pl = (*i)->region.playlist();
|
||||
Playlist * pl = (*i)->region().playlist();
|
||||
insert_result = motion_frozen_playlists.insert (pl);
|
||||
if (insert_result.second) {
|
||||
session->add_undo (pl->get_memento());
|
||||
@@ -4001,20 +4008,20 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
|
||||
switch (trim_op) {
|
||||
case StartTrim:
|
||||
if ((left_direction == false) && (drag_info.current_pointer_frame <= rv->region.first_frame()/speed)) {
|
||||
if ((left_direction == false) && (drag_info.current_pointer_frame <= rv->region().first_frame()/speed)) {
|
||||
break;
|
||||
} else {
|
||||
for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
|
||||
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
|
||||
single_start_trim (**i, frame_delta, left_direction, obey_snap);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case EndTrim:
|
||||
if ((left_direction == true) && (drag_info.current_pointer_frame > (jack_nframes_t) (rv->region.last_frame()/speed))) {
|
||||
if ((left_direction == true) && (drag_info.current_pointer_frame > (jack_nframes_t) (rv->region().last_frame()/speed))) {
|
||||
break;
|
||||
} else {
|
||||
for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
|
||||
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
|
||||
single_end_trim (**i, frame_delta, left_direction, obey_snap);
|
||||
}
|
||||
break;
|
||||
@@ -4028,8 +4035,8 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
swap_direction = true;
|
||||
}
|
||||
|
||||
for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin();
|
||||
i != selection->audio_regions.by_layer().end(); ++i)
|
||||
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin();
|
||||
i != selection->regions.by_layer().end(); ++i)
|
||||
{
|
||||
single_contents_trim (**i, frame_delta, left_direction, swap_direction, obey_snap);
|
||||
}
|
||||
@@ -4039,10 +4046,10 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
|
||||
switch (trim_op) {
|
||||
case StartTrim:
|
||||
show_verbose_time_cursor((jack_nframes_t) (rv->region.position()/speed), 10);
|
||||
show_verbose_time_cursor((jack_nframes_t) (rv->region().position()/speed), 10);
|
||||
break;
|
||||
case EndTrim:
|
||||
show_verbose_time_cursor((jack_nframes_t) (rv->region.last_frame()/speed), 10);
|
||||
show_verbose_time_cursor((jack_nframes_t) (rv->region().last_frame()/speed), 10);
|
||||
break;
|
||||
case ContentsTrim:
|
||||
show_verbose_time_cursor(drag_info.current_pointer_frame, 10);
|
||||
@@ -4054,9 +4061,9 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
}
|
||||
|
||||
void
|
||||
Editor::single_contents_trim (AudioRegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool swap_direction, bool obey_snap)
|
||||
Editor::single_contents_trim (RegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool swap_direction, bool obey_snap)
|
||||
{
|
||||
Region& region (rv.region);
|
||||
Region& region (rv.region());
|
||||
|
||||
if (region.locked()) {
|
||||
return;
|
||||
@@ -4066,7 +4073,7 @@ Editor::single_contents_trim (AudioRegionView& rv, jack_nframes_t frame_delta, b
|
||||
|
||||
double speed = 1.0;
|
||||
TimeAxisView* tvp = clicked_trackview;
|
||||
AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp);
|
||||
RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp);
|
||||
|
||||
if (tv && tv->is_audio_track()) {
|
||||
speed = tv->get_diskstream()->speed();
|
||||
@@ -4094,9 +4101,9 @@ Editor::single_contents_trim (AudioRegionView& rv, jack_nframes_t frame_delta, b
|
||||
}
|
||||
|
||||
void
|
||||
Editor::single_start_trim (AudioRegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool obey_snap)
|
||||
Editor::single_start_trim (RegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool obey_snap)
|
||||
{
|
||||
Region& region (rv.region);
|
||||
Region& region (rv.region());
|
||||
|
||||
if (region.locked()) {
|
||||
return;
|
||||
@@ -4128,9 +4135,9 @@ Editor::single_start_trim (AudioRegionView& rv, jack_nframes_t frame_delta, bool
|
||||
}
|
||||
|
||||
void
|
||||
Editor::single_end_trim (AudioRegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool obey_snap)
|
||||
Editor::single_end_trim (RegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool obey_snap)
|
||||
{
|
||||
Region& region (rv.region);
|
||||
Region& region (rv.region());
|
||||
|
||||
if (region.locked()) {
|
||||
return;
|
||||
@@ -4169,8 +4176,8 @@ Editor::trim_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
thaw_region_after_trim (*clicked_regionview);
|
||||
} else {
|
||||
|
||||
for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin();
|
||||
i != selection->audio_regions.by_layer().end(); ++i)
|
||||
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin();
|
||||
i != selection->regions.by_layer().end(); ++i)
|
||||
{
|
||||
thaw_region_after_trim (**i);
|
||||
}
|
||||
@@ -4193,7 +4200,7 @@ Editor::trim_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
void
|
||||
Editor::point_trim (GdkEvent* event)
|
||||
{
|
||||
AudioRegionView* rv = clicked_regionview;
|
||||
RegionView* rv = clicked_regionview;
|
||||
jack_nframes_t new_bound = drag_info.current_pointer_frame;
|
||||
|
||||
if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
|
||||
@@ -4208,22 +4215,22 @@ Editor::point_trim (GdkEvent* event)
|
||||
|
||||
if (rv->get_selected()) {
|
||||
|
||||
for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin();
|
||||
i != selection->audio_regions.by_layer().end(); ++i)
|
||||
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin();
|
||||
i != selection->regions.by_layer().end(); ++i)
|
||||
{
|
||||
if (!(*i)->region.locked()) {
|
||||
session->add_undo ((*i)->region.playlist()->get_memento());
|
||||
(*i)->region.trim_front (new_bound, this);
|
||||
session->add_redo_no_execute ((*i)->region.playlist()->get_memento());
|
||||
if (!(*i)->region().locked()) {
|
||||
session->add_undo ((*i)->region().playlist()->get_memento());
|
||||
(*i)->region().trim_front (new_bound, this);
|
||||
session->add_redo_no_execute ((*i)->region().playlist()->get_memento());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (!rv->region.locked()) {
|
||||
session->add_undo (rv->region.playlist()->get_memento());
|
||||
rv->region.trim_front (new_bound, this);
|
||||
session->add_redo_no_execute (rv->region.playlist()->get_memento());
|
||||
if (!rv->region().locked()) {
|
||||
session->add_undo (rv->region().playlist()->get_memento());
|
||||
rv->region().trim_front (new_bound, this);
|
||||
session->add_redo_no_execute (rv->region().playlist()->get_memento());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4236,21 +4243,21 @@ Editor::point_trim (GdkEvent* event)
|
||||
|
||||
if (rv->get_selected()) {
|
||||
|
||||
for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i)
|
||||
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i)
|
||||
{
|
||||
if (!(*i)->region.locked()) {
|
||||
session->add_undo ((*i)->region.playlist()->get_memento());
|
||||
(*i)->region.trim_end (new_bound, this);
|
||||
session->add_redo_no_execute ((*i)->region.playlist()->get_memento());
|
||||
if (!(*i)->region().locked()) {
|
||||
session->add_undo ((*i)->region().playlist()->get_memento());
|
||||
(*i)->region().trim_end (new_bound, this);
|
||||
session->add_redo_no_execute ((*i)->region().playlist()->get_memento());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (!rv->region.locked()) {
|
||||
session->add_undo (rv->region.playlist()->get_memento());
|
||||
rv->region.trim_end (new_bound, this);
|
||||
session->add_redo_no_execute (rv->region.playlist()->get_memento());
|
||||
if (!rv->region().locked()) {
|
||||
session->add_undo (rv->region().playlist()->get_memento());
|
||||
rv->region().trim_end (new_bound, this);
|
||||
session->add_redo_no_execute (rv->region().playlist()->get_memento());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4263,9 +4270,9 @@ Editor::point_trim (GdkEvent* event)
|
||||
}
|
||||
|
||||
void
|
||||
Editor::thaw_region_after_trim (AudioRegionView& rv)
|
||||
Editor::thaw_region_after_trim (RegionView& rv)
|
||||
{
|
||||
Region& region (rv.region);
|
||||
Region& region (rv.region());
|
||||
|
||||
if (region.locked()) {
|
||||
return;
|
||||
@@ -4274,7 +4281,9 @@ Editor::thaw_region_after_trim (AudioRegionView& rv)
|
||||
region.thaw (_("trimmed region"));
|
||||
session->add_redo_no_execute (region.playlist()->get_memento());
|
||||
|
||||
rv.unhide_envelope ();
|
||||
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(&rv);
|
||||
if (arv)
|
||||
arv->unhide_envelope ();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4664,7 +4673,7 @@ Editor::end_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
}
|
||||
|
||||
} else {
|
||||
selection->clear_audio_regions();
|
||||
selection->clear_regions();
|
||||
selection->clear_points ();
|
||||
selection->clear_lines ();
|
||||
}
|
||||
@@ -4681,7 +4690,7 @@ Editor::mouse_rename_region (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
ArdourPrompter prompter (false);
|
||||
|
||||
prompter.set_prompt (_("Name for region:"));
|
||||
prompter.set_initial_text (clicked_regionview->region.name());
|
||||
prompter.set_initial_text (clicked_regionview->region().name());
|
||||
prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT);
|
||||
prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
|
||||
prompter.show_all ();
|
||||
@@ -4690,7 +4699,7 @@ Editor::mouse_rename_region (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
string str;
|
||||
prompter.get_result(str);
|
||||
if (str.length()) {
|
||||
clicked_regionview->region.set_name (str);
|
||||
clicked_regionview->region().set_name (str);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -4712,7 +4721,7 @@ Editor::start_time_fx (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
void
|
||||
Editor::time_fx_motion (ArdourCanvas::Item *item, GdkEvent* event)
|
||||
{
|
||||
AudioRegionView* rv = clicked_regionview;
|
||||
RegionView* rv = clicked_regionview;
|
||||
|
||||
if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
|
||||
snap_to (drag_info.current_pointer_frame);
|
||||
@@ -4722,8 +4731,8 @@ Editor::time_fx_motion (ArdourCanvas::Item *item, GdkEvent* event)
|
||||
return;
|
||||
}
|
||||
|
||||
if (drag_info.current_pointer_frame > rv->region.position()) {
|
||||
rv->get_time_axis_view().show_timestretch (rv->region.position(), drag_info.current_pointer_frame);
|
||||
if (drag_info.current_pointer_frame > rv->region().position()) {
|
||||
rv->get_time_axis_view().show_timestretch (rv->region().position(), drag_info.current_pointer_frame);
|
||||
}
|
||||
|
||||
drag_info.last_pointer_frame = drag_info.current_pointer_frame;
|
||||
@@ -4741,21 +4750,25 @@ Editor::end_time_fx (ArdourCanvas::Item* item, GdkEvent* event)
|
||||
return;
|
||||
}
|
||||
|
||||
jack_nframes_t newlen = drag_info.last_pointer_frame - clicked_regionview->region.position();
|
||||
float percentage = (float) ((double) newlen - (double) clicked_regionview->region.length()) / ((double) newlen) * 100.0f;
|
||||
jack_nframes_t newlen = drag_info.last_pointer_frame - clicked_regionview->region().position();
|
||||
float percentage = (float) ((double) newlen - (double) clicked_regionview->region().length()) / ((double) newlen) * 100.0f;
|
||||
|
||||
begin_reversible_command (_("timestretch"));
|
||||
|
||||
if (run_timestretch (selection->audio_regions, percentage) == 0) {
|
||||
if (run_timestretch (selection->regions, percentage) == 0) {
|
||||
session->commit_reversible_command ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Editor::mouse_brush_insert_region (AudioRegionView* rv, jack_nframes_t pos)
|
||||
Editor::mouse_brush_insert_region (RegionView* rv, jack_nframes_t pos)
|
||||
{
|
||||
/* no brushing without a useful snap setting */
|
||||
|
||||
// FIXME
|
||||
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(rv);
|
||||
assert(arv);
|
||||
|
||||
switch (snap_mode) {
|
||||
case SnapMagnetic:
|
||||
return; /* can't work because it allows region to be placed anywhere */
|
||||
@@ -4775,11 +4788,11 @@ Editor::mouse_brush_insert_region (AudioRegionView* rv, jack_nframes_t pos)
|
||||
|
||||
/* don't brush a copy over the original */
|
||||
|
||||
if (pos == rv->region.position()) {
|
||||
if (pos == rv->region().position()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(&rv->get_time_axis_view());
|
||||
RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(&arv->get_time_axis_view());
|
||||
|
||||
if (atv == 0 || !atv->is_audio_track()) {
|
||||
return;
|
||||
@@ -4789,7 +4802,7 @@ Editor::mouse_brush_insert_region (AudioRegionView* rv, jack_nframes_t pos)
|
||||
double speed = atv->get_diskstream()->speed();
|
||||
|
||||
session->add_undo (playlist->get_memento());
|
||||
playlist->add_region (*(new AudioRegion (rv->region)), (jack_nframes_t) (pos * speed));
|
||||
playlist->add_region (*(new AudioRegion (arv->audio_region())), (jack_nframes_t) (pos * speed));
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
|
||||
// playlist is frozen, so we have to update manually
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
#include "audio_time_axis.h"
|
||||
#include "automation_time_axis.h"
|
||||
#include "streamview.h"
|
||||
#include "regionview.h"
|
||||
#include "audio_region_view.h"
|
||||
#include "rgb_macros.h"
|
||||
#include "selection_templates.h"
|
||||
#include "selection.h"
|
||||
@@ -186,29 +186,31 @@ Editor::split_region ()
|
||||
void
|
||||
Editor::split_region_at (jack_nframes_t where)
|
||||
{
|
||||
split_regions_at (where, selection->audio_regions);
|
||||
split_regions_at (where, selection->regions);
|
||||
}
|
||||
|
||||
void
|
||||
Editor::split_regions_at (jack_nframes_t where, AudioRegionSelection& regions)
|
||||
Editor::split_regions_at (jack_nframes_t where, RegionSelection& regions)
|
||||
{
|
||||
begin_reversible_command (_("split"));
|
||||
|
||||
snap_to (where);
|
||||
for (AudioRegionSelection::iterator a = regions.begin(); a != regions.end(); ) {
|
||||
for (RegionSelection::iterator a = regions.begin(); a != regions.end(); ) {
|
||||
|
||||
AudioRegionSelection::iterator tmp;
|
||||
RegionSelection::iterator tmp;
|
||||
|
||||
tmp = a;
|
||||
++tmp;
|
||||
|
||||
Playlist* pl = (*a)->region.playlist();
|
||||
Playlist* pl = (*a)->region().playlist();
|
||||
|
||||
_new_regionviews_show_envelope = (*a)->envelope_visible();
|
||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*a);
|
||||
if (arv)
|
||||
_new_regionviews_show_envelope = arv->envelope_visible();
|
||||
|
||||
if (pl) {
|
||||
session->add_undo (pl->get_memento());
|
||||
pl->split_region ((*a)->region, where);
|
||||
pl->split_region ((*a)->region(), where);
|
||||
session->add_redo_no_execute (pl->get_memento());
|
||||
}
|
||||
|
||||
@@ -230,7 +232,7 @@ Editor::remove_clicked_region ()
|
||||
|
||||
begin_reversible_command (_("remove region"));
|
||||
session->add_undo (playlist->get_memento());
|
||||
playlist->remove_region (&clicked_regionview->region);
|
||||
playlist->remove_region (&clicked_regionview->region());
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
commit_reversible_command ();
|
||||
}
|
||||
@@ -238,7 +240,7 @@ Editor::remove_clicked_region ()
|
||||
void
|
||||
Editor::destroy_clicked_region ()
|
||||
{
|
||||
int32_t selected = selection->audio_regions.size();
|
||||
int32_t selected = selection->regions.size();
|
||||
|
||||
if (!session || clicked_regionview == 0 && selected == 0) {
|
||||
return;
|
||||
@@ -270,29 +272,29 @@ Do you really want to destroy %1 ?"),
|
||||
if (selected > 0) {
|
||||
list<Region*> r;
|
||||
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
r.push_back (&(*i)->region);
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
r.push_back (&(*i)->region());
|
||||
}
|
||||
|
||||
session->destroy_regions (r);
|
||||
|
||||
} else if (clicked_regionview) {
|
||||
session->destroy_region (&clicked_regionview->region);
|
||||
session->destroy_region (&clicked_regionview->region());
|
||||
}
|
||||
}
|
||||
|
||||
AudioRegion *
|
||||
Region *
|
||||
Editor::select_region_for_operation (int dir, TimeAxisView **tv)
|
||||
{
|
||||
AudioRegionView* rv;
|
||||
AudioRegion *region;
|
||||
RegionView* rv;
|
||||
Region *region;
|
||||
jack_nframes_t start = 0;
|
||||
|
||||
if (selection->time.start () == selection->time.end_frame ()) {
|
||||
|
||||
/* no current selection-> is there a selected regionview? */
|
||||
|
||||
if (selection->audio_regions.empty()) {
|
||||
if (selection->regions.empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -300,26 +302,26 @@ Editor::select_region_for_operation (int dir, TimeAxisView **tv)
|
||||
|
||||
region = 0;
|
||||
|
||||
if (!selection->audio_regions.empty()) {
|
||||
if (!selection->regions.empty()) {
|
||||
|
||||
rv = *(selection->audio_regions.begin());
|
||||
rv = *(selection->regions.begin());
|
||||
(*tv) = &rv->get_time_axis_view();
|
||||
region = &rv->region;
|
||||
region = &rv->region();
|
||||
|
||||
} else if (!selection->tracks.empty()) {
|
||||
|
||||
(*tv) = selection->tracks.front();
|
||||
|
||||
AudioTimeAxisView* atv;
|
||||
RouteTimeAxisView* rtv;
|
||||
|
||||
if ((atv = dynamic_cast<AudioTimeAxisView*> (*tv)) != 0) {
|
||||
if ((rtv = dynamic_cast<RouteTimeAxisView*> (*tv)) != 0) {
|
||||
Playlist *pl;
|
||||
|
||||
if ((pl = atv->playlist()) == 0) {
|
||||
if ((pl = rtv->playlist()) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
region = dynamic_cast<AudioRegion*> (pl->top_region_at (start));
|
||||
region = pl->top_region_at (start);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,12 +393,12 @@ Editor::nudge_forward (bool next)
|
||||
|
||||
if (!session) return;
|
||||
|
||||
if (!selection->audio_regions.empty()) {
|
||||
if (!selection->regions.empty()) {
|
||||
|
||||
begin_reversible_command (_("nudge forward"));
|
||||
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
AudioRegion& r ((*i)->region);
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
Region& r ((*i)->region());
|
||||
|
||||
distance = get_nudge_distance (r.position(), next_distance);
|
||||
|
||||
@@ -425,12 +427,12 @@ Editor::nudge_backward (bool next)
|
||||
|
||||
if (!session) return;
|
||||
|
||||
if (!selection->audio_regions.empty()) {
|
||||
if (!selection->regions.empty()) {
|
||||
|
||||
begin_reversible_command (_("nudge forward"));
|
||||
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
AudioRegion& r ((*i)->region);
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
Region& r ((*i)->region());
|
||||
|
||||
distance = get_nudge_distance (r.position(), next_distance);
|
||||
|
||||
@@ -469,14 +471,14 @@ Editor::nudge_forward_capture_offset ()
|
||||
|
||||
if (!session) return;
|
||||
|
||||
if (!selection->audio_regions.empty()) {
|
||||
if (!selection->regions.empty()) {
|
||||
|
||||
begin_reversible_command (_("nudge forward"));
|
||||
|
||||
distance = session->worst_output_latency();
|
||||
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
AudioRegion& r ((*i)->region);
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
Region& r ((*i)->region());
|
||||
|
||||
session->add_undo (r.playlist()->get_memento());
|
||||
r.set_position (r.position() + distance, this);
|
||||
@@ -495,14 +497,14 @@ Editor::nudge_backward_capture_offset ()
|
||||
|
||||
if (!session) return;
|
||||
|
||||
if (!selection->audio_regions.empty()) {
|
||||
if (!selection->regions.empty()) {
|
||||
|
||||
begin_reversible_command (_("nudge forward"));
|
||||
|
||||
distance = session->worst_output_latency();
|
||||
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
AudioRegion& r ((*i)->region);
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
Region& r ((*i)->region());
|
||||
|
||||
session->add_undo (r.playlist()->get_memento());
|
||||
|
||||
@@ -782,8 +784,8 @@ Editor::cursor_to_selection_start (Cursor *cursor)
|
||||
jack_nframes_t pos = 0;
|
||||
switch (mouse_mode) {
|
||||
case MouseObject:
|
||||
if (!selection->audio_regions.empty()) {
|
||||
pos = selection->audio_regions.start();
|
||||
if (!selection->regions.empty()) {
|
||||
pos = selection->regions.start();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -811,8 +813,8 @@ Editor::cursor_to_selection_end (Cursor *cursor)
|
||||
|
||||
switch (mouse_mode) {
|
||||
case MouseObject:
|
||||
if (!selection->audio_regions.empty()) {
|
||||
pos = selection->audio_regions.end_frame();
|
||||
if (!selection->regions.empty()) {
|
||||
pos = selection->regions.end_frame();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1310,12 +1312,12 @@ Editor::add_location_from_playhead_cursor ()
|
||||
void
|
||||
Editor::add_location_from_audio_region ()
|
||||
{
|
||||
if (selection->audio_regions.empty()) {
|
||||
if (selection->regions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AudioRegionView* rv = *(selection->audio_regions.begin());
|
||||
Region& region = rv->region;
|
||||
RegionView* rv = *(selection->regions.begin());
|
||||
Region& region = rv->region();
|
||||
|
||||
Location *location = new Location (region.position(), region.last_frame(), region.name());
|
||||
session->begin_reversible_command (_("add marker"));
|
||||
@@ -1442,12 +1444,12 @@ Editor::select_all_within (jack_nframes_t start, jack_nframes_t end, double top,
|
||||
void
|
||||
Editor::set_selection_from_audio_region ()
|
||||
{
|
||||
if (selection->audio_regions.empty()) {
|
||||
if (selection->regions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AudioRegionView* rv = *(selection->audio_regions.begin());
|
||||
Region& region = rv->region;
|
||||
RegionView* rv = *(selection->regions.begin());
|
||||
Region& region = rv->region();
|
||||
|
||||
begin_reversible_command (_("set selection from region"));
|
||||
selection->set (0, region.position(), region.last_frame());
|
||||
@@ -1827,13 +1829,13 @@ Editor::insert_region_list_drag (AudioRegion& region, int x, int y)
|
||||
void
|
||||
Editor::insert_region_list_selection (float times)
|
||||
{
|
||||
AudioTimeAxisView *tv = 0;
|
||||
RouteTimeAxisView *tv = 0;
|
||||
Playlist *playlist;
|
||||
|
||||
if (clicked_audio_trackview != 0) {
|
||||
tv = clicked_audio_trackview;
|
||||
} else if (!selection->tracks.empty()) {
|
||||
if ((tv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.front())) == 0) {
|
||||
if ((tv = dynamic_cast<RouteTimeAxisView*>(selection->tracks.front())) == 0) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -1928,23 +1930,23 @@ Editor::play_selection ()
|
||||
void
|
||||
Editor::play_selected_region ()
|
||||
{
|
||||
if (!selection->audio_regions.empty()) {
|
||||
AudioRegionView *rv = *(selection->audio_regions.begin());
|
||||
if (!selection->regions.empty()) {
|
||||
RegionView *rv = *(selection->regions.begin());
|
||||
|
||||
session->request_bounded_roll (rv->region.position(), rv->region.last_frame());
|
||||
session->request_bounded_roll (rv->region().position(), rv->region().last_frame());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Editor::loop_selected_region ()
|
||||
{
|
||||
if (!selection->audio_regions.empty()) {
|
||||
AudioRegionView *rv = *(selection->audio_regions.begin());
|
||||
if (!selection->regions.empty()) {
|
||||
RegionView *rv = *(selection->regions.begin());
|
||||
Location* tll;
|
||||
|
||||
if ((tll = transport_loop_location()) != 0) {
|
||||
|
||||
tll->set (rv->region.position(), rv->region.last_frame());
|
||||
tll->set (rv->region().position(), rv->region().last_frame());
|
||||
|
||||
// enable looping, reposition and start rolling
|
||||
|
||||
@@ -1987,10 +1989,10 @@ void
|
||||
Editor::toggle_region_mute ()
|
||||
{
|
||||
if (clicked_regionview) {
|
||||
clicked_regionview->region.set_muted (!clicked_regionview->region.muted());
|
||||
} else if (!selection->audio_regions.empty()) {
|
||||
bool yn = ! (*selection->audio_regions.begin())->region.muted();
|
||||
selection->foreach_audio_region (&AudioRegion::set_muted, yn);
|
||||
clicked_regionview->region().set_muted (!clicked_regionview->region().muted());
|
||||
} else if (!selection->regions.empty()) {
|
||||
bool yn = ! (*selection->regions.begin())->region().muted();
|
||||
selection->foreach_region (&Region::set_muted, yn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1998,35 +2000,35 @@ void
|
||||
Editor::toggle_region_opaque ()
|
||||
{
|
||||
if (clicked_regionview) {
|
||||
clicked_regionview->region.set_opaque (!clicked_regionview->region.opaque());
|
||||
} else if (!selection->audio_regions.empty()) {
|
||||
bool yn = ! (*selection->audio_regions.begin())->region.opaque();
|
||||
selection->foreach_audio_region (&Region::set_opaque, yn);
|
||||
clicked_regionview->region().set_opaque (!clicked_regionview->region().opaque());
|
||||
} else if (!selection->regions.empty()) {
|
||||
bool yn = ! (*selection->regions.begin())->region().opaque();
|
||||
selection->foreach_region (&Region::set_opaque, yn);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Editor::raise_region ()
|
||||
{
|
||||
selection->foreach_audio_region (&Region::raise);
|
||||
selection->foreach_region (&Region::raise);
|
||||
}
|
||||
|
||||
void
|
||||
Editor::raise_region_to_top ()
|
||||
{
|
||||
selection->foreach_audio_region (&Region::raise_to_top);
|
||||
selection->foreach_region (&Region::raise_to_top);
|
||||
}
|
||||
|
||||
void
|
||||
Editor::lower_region ()
|
||||
{
|
||||
selection->foreach_audio_region (&Region::lower);
|
||||
selection->foreach_region (&Region::lower);
|
||||
}
|
||||
|
||||
void
|
||||
Editor::lower_region_to_bottom ()
|
||||
{
|
||||
selection->foreach_audio_region (&Region::lower_to_bottom);
|
||||
selection->foreach_region (&Region::lower_to_bottom);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2047,7 +2049,7 @@ Editor::rename_region ()
|
||||
Button ok_button (_("OK"));
|
||||
Button cancel_button (_("Cancel"));
|
||||
|
||||
if (selection->audio_regions.empty()) {
|
||||
if (selection->regions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2078,7 +2080,7 @@ Editor::rename_region ()
|
||||
Main::run ();
|
||||
|
||||
if (region_renamed) {
|
||||
(*selection->audio_regions.begin())->region.set_name (entry.get_text());
|
||||
(*selection->regions.begin())->region().set_name (entry.get_text());
|
||||
redisplay_regions ();
|
||||
}
|
||||
}
|
||||
@@ -2092,7 +2094,7 @@ Editor::rename_region_finished (bool status)
|
||||
}
|
||||
|
||||
void
|
||||
Editor::audition_playlist_region_via_route (AudioRegion& region, Route& route)
|
||||
Editor::audition_playlist_region_via_route (Region& region, Route& route)
|
||||
{
|
||||
if (session->is_auditioning()) {
|
||||
session->cancel_audition ();
|
||||
@@ -2113,14 +2115,14 @@ Editor::audition_playlist_region_via_route (AudioRegion& region, Route& route)
|
||||
void
|
||||
Editor::audition_selected_region ()
|
||||
{
|
||||
if (!selection->audio_regions.empty()) {
|
||||
AudioRegionView* rv = *(selection->audio_regions.begin());
|
||||
session->audition_region (rv->region);
|
||||
if (!selection->regions.empty()) {
|
||||
RegionView* rv = *(selection->regions.begin());
|
||||
session->audition_region (rv->region());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Editor::audition_playlist_region_standalone (AudioRegion& region)
|
||||
Editor::audition_playlist_region_standalone (Region& region)
|
||||
{
|
||||
session->audition_region (region);
|
||||
}
|
||||
@@ -2170,7 +2172,6 @@ Editor::region_from_selection ()
|
||||
jack_nframes_t selection_cnt = end - start + 1;
|
||||
|
||||
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
|
||||
|
||||
AudioRegion *region;
|
||||
AudioRegion *current;
|
||||
Region* current_r;
|
||||
@@ -2187,7 +2188,9 @@ Editor::region_from_selection ()
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((current = dynamic_cast<AudioRegion*> (current_r)) != 0) {
|
||||
current = dynamic_cast<AudioRegion*> (current_r);
|
||||
// FIXME: audio only
|
||||
if (current != 0) {
|
||||
internal_start = start - current->position();
|
||||
session->region_name (new_name, current->name(), true);
|
||||
region = new AudioRegion (*current, internal_start, selection_cnt, new_name);
|
||||
@@ -2237,11 +2240,13 @@ Editor::split_multichannel_region ()
|
||||
{
|
||||
vector<AudioRegion*> v;
|
||||
|
||||
if (!clicked_regionview || clicked_regionview->region.n_channels() < 2) {
|
||||
AudioRegionView* clicked_arv = dynamic_cast<AudioRegionView*>(clicked_regionview);
|
||||
|
||||
if (!clicked_arv || clicked_arv->audio_region().n_channels() < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
clicked_regionview->region.separate_by_channel (*session, v);
|
||||
clicked_arv->audio_region().separate_by_channel (*session, v);
|
||||
|
||||
/* nothing else to do, really */
|
||||
}
|
||||
@@ -2419,7 +2424,7 @@ Editor::region_fill_track ()
|
||||
{
|
||||
jack_nframes_t end;
|
||||
|
||||
if (!session || selection->audio_regions.empty()) {
|
||||
if (!session || selection->regions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2427,9 +2432,15 @@ Editor::region_fill_track ()
|
||||
|
||||
begin_reversible_command (_("region fill"));
|
||||
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
|
||||
Region& region ((*i)->region());
|
||||
|
||||
// FIXME
|
||||
AudioRegion* const ar = dynamic_cast<AudioRegion*>(®ion);
|
||||
if (!ar)
|
||||
continue;
|
||||
|
||||
AudioRegion& region ((*i)->region);
|
||||
Playlist* pl = region.playlist();
|
||||
|
||||
if (end <= region.last_frame()) {
|
||||
@@ -2443,7 +2454,7 @@ Editor::region_fill_track ()
|
||||
}
|
||||
|
||||
session->add_undo (pl->get_memento());
|
||||
pl->add_region (*(new AudioRegion (region)), region.last_frame(), times);
|
||||
pl->add_region (*(new AudioRegion (*ar)), ar->last_frame(), times);
|
||||
session->add_redo_no_execute (pl->get_memento());
|
||||
}
|
||||
|
||||
@@ -2522,12 +2533,12 @@ Editor::set_region_sync_from_edit_cursor ()
|
||||
return;
|
||||
}
|
||||
|
||||
if (!clicked_regionview->region.covers (edit_cursor->current_frame)) {
|
||||
if (!clicked_regionview->region().covers (edit_cursor->current_frame)) {
|
||||
error << _("Place the edit cursor at the desired sync point") << endmsg;
|
||||
return;
|
||||
}
|
||||
|
||||
Region& region (clicked_regionview->region);
|
||||
Region& region (clicked_regionview->region());
|
||||
begin_reversible_command (_("set sync from edit cursor"));
|
||||
session->add_undo (region.playlist()->get_memento());
|
||||
region.set_sync_position (edit_cursor->current_frame);
|
||||
@@ -2539,7 +2550,7 @@ void
|
||||
Editor::remove_region_sync ()
|
||||
{
|
||||
if (clicked_regionview) {
|
||||
Region& region (clicked_regionview->region);
|
||||
Region& region (clicked_regionview->region());
|
||||
begin_reversible_command (_("remove sync"));
|
||||
session->add_undo (region.playlist()->get_memento());
|
||||
region.clear_sync_position ();
|
||||
@@ -2551,14 +2562,14 @@ Editor::remove_region_sync ()
|
||||
void
|
||||
Editor::naturalize ()
|
||||
{
|
||||
if (selection->audio_regions.empty()) {
|
||||
if (selection->regions.empty()) {
|
||||
return;
|
||||
}
|
||||
begin_reversible_command (_("naturalize"));
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
session->add_undo ((*i)->region.get_memento());
|
||||
(*i)->region.move_to_natural_position (this);
|
||||
session->add_redo_no_execute ((*i)->region.get_memento());
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
session->add_undo ((*i)->region().get_memento());
|
||||
(*i)->region().move_to_natural_position (this);
|
||||
session->add_redo_no_execute ((*i)->region().get_memento());
|
||||
}
|
||||
commit_reversible_command ();
|
||||
}
|
||||
@@ -2577,14 +2588,14 @@ Editor::align_relative (RegionPoint what)
|
||||
|
||||
struct RegionSortByTime {
|
||||
bool operator() (const AudioRegionView* a, const AudioRegionView* b) {
|
||||
return a->region.position() < b->region.position();
|
||||
return a->region().position() < b->region().position();
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
Editor::align_selection_relative (RegionPoint point, jack_nframes_t position)
|
||||
{
|
||||
if (selection->audio_regions.empty()) {
|
||||
if (selection->regions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2592,9 +2603,9 @@ Editor::align_selection_relative (RegionPoint point, jack_nframes_t position)
|
||||
jack_nframes_t pos = 0;
|
||||
int dir;
|
||||
|
||||
list<AudioRegionView*> sorted;
|
||||
selection->audio_regions.by_position (sorted);
|
||||
Region& r ((*sorted.begin())->region);
|
||||
list<RegionView*> sorted;
|
||||
selection->regions.by_position (sorted);
|
||||
Region& r ((*sorted.begin())->region());
|
||||
|
||||
switch (point) {
|
||||
case Start:
|
||||
@@ -2620,9 +2631,9 @@ Editor::align_selection_relative (RegionPoint point, jack_nframes_t position)
|
||||
|
||||
begin_reversible_command (_("align selection (relative)"));
|
||||
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
|
||||
Region& region ((*i)->region);
|
||||
Region& region ((*i)->region());
|
||||
|
||||
session->add_undo (region.playlist()->get_memento());
|
||||
|
||||
@@ -2642,14 +2653,14 @@ Editor::align_selection_relative (RegionPoint point, jack_nframes_t position)
|
||||
void
|
||||
Editor::align_selection (RegionPoint point, jack_nframes_t position)
|
||||
{
|
||||
if (selection->audio_regions.empty()) {
|
||||
if (selection->regions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
begin_reversible_command (_("align selection"));
|
||||
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
align_region_internal ((*i)->region, point, position);
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
align_region_internal ((*i)->region(), point, position);
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
@@ -2694,7 +2705,7 @@ Editor::trim_region_to_edit_cursor ()
|
||||
return;
|
||||
}
|
||||
|
||||
Region& region (clicked_regionview->region);
|
||||
Region& region (clicked_regionview->region());
|
||||
|
||||
float speed = 1.0f;
|
||||
AudioTimeAxisView *atav;
|
||||
@@ -2719,7 +2730,7 @@ Editor::trim_region_from_edit_cursor ()
|
||||
return;
|
||||
}
|
||||
|
||||
Region& region (clicked_regionview->region);
|
||||
Region& region (clicked_regionview->region());
|
||||
|
||||
float speed = 1.0f;
|
||||
AudioTimeAxisView *atav;
|
||||
@@ -2890,16 +2901,16 @@ Editor::cut_copy (CutCopyOp op)
|
||||
|
||||
switch (current_mouse_mode()) {
|
||||
case MouseObject:
|
||||
if (!selection->audio_regions.empty() || !selection->points.empty()) {
|
||||
if (!selection->regions.empty() || !selection->points.empty()) {
|
||||
|
||||
begin_reversible_command (opname + _(" objects"));
|
||||
|
||||
if (!selection->audio_regions.empty()) {
|
||||
if (!selection->regions.empty()) {
|
||||
|
||||
cut_copy_regions (op);
|
||||
|
||||
if (op == Cut) {
|
||||
selection->clear_audio_regions ();
|
||||
selection->clear_regions ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2956,11 +2967,11 @@ Editor::cut_copy_regions (CutCopyOp op)
|
||||
set<Playlist*> freezelist;
|
||||
pair<set<Playlist*>::iterator,bool> insert_result;
|
||||
|
||||
for (AudioRegionSelection::iterator x = selection->audio_regions.begin(); x != selection->audio_regions.end(); ++x) {
|
||||
first_position = min ((*x)->region.position(), first_position);
|
||||
for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
|
||||
first_position = min ((*x)->region().position(), first_position);
|
||||
|
||||
if (op == Cut || op == Clear) {
|
||||
AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region.playlist());
|
||||
AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region().playlist());
|
||||
if (pl) {
|
||||
insert_result = freezelist.insert (pl);
|
||||
if (insert_result.second) {
|
||||
@@ -2971,11 +2982,11 @@ Editor::cut_copy_regions (CutCopyOp op)
|
||||
}
|
||||
}
|
||||
|
||||
for (AudioRegionSelection::iterator x = selection->audio_regions.begin(); x != selection->audio_regions.end(); ) {
|
||||
for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ) {
|
||||
|
||||
AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region.playlist());
|
||||
AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region().playlist());
|
||||
AudioPlaylist* npl;
|
||||
AudioRegionSelection::iterator tmp;
|
||||
RegionSelection::iterator tmp;
|
||||
|
||||
tmp = x;
|
||||
++tmp;
|
||||
@@ -2992,18 +3003,24 @@ Editor::cut_copy_regions (CutCopyOp op)
|
||||
npl = pi->second;
|
||||
}
|
||||
|
||||
// FIXME
|
||||
AudioRegion* const ar = dynamic_cast<AudioRegion*>(&(*x)->region());
|
||||
switch (op) {
|
||||
case Cut:
|
||||
npl->add_region (*(new AudioRegion ((*x)->region)), (*x)->region.position() - first_position);
|
||||
pl->remove_region (&((*x)->region));
|
||||
if (!ar) break;
|
||||
|
||||
npl->add_region (*(new AudioRegion (*ar)), (*x)->region().position() - first_position);
|
||||
pl->remove_region (&((*x)->region()));
|
||||
break;
|
||||
|
||||
case Copy:
|
||||
npl->add_region (*(new AudioRegion ((*x)->region)), (*x)->region.position() - first_position);
|
||||
if (!ar) break;
|
||||
|
||||
npl->add_region (*(new AudioRegion (*ar)), (*x)->region().position() - first_position);
|
||||
break;
|
||||
|
||||
case Clear:
|
||||
pl->remove_region (&((*x)->region));
|
||||
pl->remove_region (&((*x)->region()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3149,24 +3166,24 @@ Editor::paste_named_selection (float times)
|
||||
}
|
||||
|
||||
void
|
||||
Editor::duplicate_some_regions (AudioRegionSelection& regions, float times)
|
||||
Editor::duplicate_some_regions (RegionSelection& regions, float times)
|
||||
{
|
||||
Playlist *playlist;
|
||||
AudioRegionSelection sel = regions; // clear (below) will clear the argument list
|
||||
RegionSelection sel = regions; // clear (below) will clear the argument list
|
||||
|
||||
begin_reversible_command (_("duplicate region"));
|
||||
|
||||
selection->clear_audio_regions ();
|
||||
selection->clear_regions ();
|
||||
|
||||
for (AudioRegionSelection::iterator i = sel.begin(); i != sel.end(); ++i) {
|
||||
for (RegionSelection::iterator i = sel.begin(); i != sel.end(); ++i) {
|
||||
|
||||
Region& r ((*i)->region);
|
||||
Region& r ((*i)->region());
|
||||
|
||||
TimeAxisView& tv = (*i)->get_time_axis_view();
|
||||
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&tv);
|
||||
sigc::connection c = atv->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
|
||||
sigc::connection c = atv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
|
||||
|
||||
playlist = (*i)->region.playlist();
|
||||
playlist = (*i)->region().playlist();
|
||||
session->add_undo (playlist->get_memento());
|
||||
playlist->duplicate (r, r.last_frame(), times);
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
@@ -3336,7 +3353,7 @@ Editor::normalize_region ()
|
||||
return;
|
||||
}
|
||||
|
||||
if (selection->audio_regions.empty()) {
|
||||
if (selection->regions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3345,10 +3362,13 @@ Editor::normalize_region ()
|
||||
track_canvas.get_window()->set_cursor (*wait_cursor);
|
||||
gdk_flush ();
|
||||
|
||||
for (AudioRegionSelection::iterator r = selection->audio_regions.begin(); r != selection->audio_regions.end(); ++r) {
|
||||
session->add_undo ((*r)->region.get_memento());
|
||||
(*r)->region.normalize_to (0.0f);
|
||||
session->add_redo_no_execute ((*r)->region.get_memento());
|
||||
for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ++r) {
|
||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
|
||||
if (!arv)
|
||||
continue;
|
||||
session->add_undo (arv->region().get_memento());
|
||||
arv->audio_region().normalize_to (0.0f);
|
||||
session->add_redo_no_execute (arv->region().get_memento());
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
@@ -3363,16 +3383,19 @@ Editor::denormalize_region ()
|
||||
return;
|
||||
}
|
||||
|
||||
if (selection->audio_regions.empty()) {
|
||||
if (selection->regions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
begin_reversible_command ("denormalize");
|
||||
|
||||
for (AudioRegionSelection::iterator r = selection->audio_regions.begin(); r != selection->audio_regions.end(); ++r) {
|
||||
session->add_undo ((*r)->region.get_memento());
|
||||
(*r)->region.set_scale_amplitude (1.0f);
|
||||
session->add_redo_no_execute ((*r)->region.get_memento());
|
||||
for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ++r) {
|
||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
|
||||
if (!arv)
|
||||
continue;
|
||||
session->add_undo (arv->region().get_memento());
|
||||
arv->audio_region().set_scale_amplitude (1.0f);
|
||||
session->add_redo_no_execute (arv->region().get_memento());
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
@@ -3393,7 +3416,7 @@ Editor::reverse_region ()
|
||||
void
|
||||
Editor::apply_filter (AudioFilter& filter, string command)
|
||||
{
|
||||
if (selection->audio_regions.empty()) {
|
||||
if (selection->regions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3402,20 +3425,22 @@ Editor::apply_filter (AudioFilter& filter, string command)
|
||||
track_canvas.get_window()->set_cursor (*wait_cursor);
|
||||
gdk_flush ();
|
||||
|
||||
for (AudioRegionSelection::iterator r = selection->audio_regions.begin(); r != selection->audio_regions.end(); ) {
|
||||
for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ) {
|
||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
|
||||
if (!arv)
|
||||
continue;
|
||||
|
||||
AudioRegion& region ((*r)->region);
|
||||
Playlist* playlist = region.playlist();
|
||||
Playlist* playlist = arv->region().playlist();
|
||||
|
||||
AudioRegionSelection::iterator tmp;
|
||||
RegionSelection::iterator tmp;
|
||||
|
||||
tmp = r;
|
||||
++tmp;
|
||||
|
||||
if (region.apply (filter) == 0) {
|
||||
if (arv->audio_region().apply (filter) == 0) {
|
||||
|
||||
session->add_undo (playlist->get_memento());
|
||||
playlist->replace_region (region, *(filter.results.front()), region.position());
|
||||
playlist->replace_region (arv->region(), *(filter.results.front()), arv->region().position());
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
} else {
|
||||
goto out;
|
||||
@@ -3425,7 +3450,7 @@ Editor::apply_filter (AudioFilter& filter, string command)
|
||||
}
|
||||
|
||||
commit_reversible_command ();
|
||||
selection->audio_regions.clear ();
|
||||
selection->regions.clear ();
|
||||
|
||||
out:
|
||||
track_canvas.get_window()->set_cursor (*current_canvas_cursor);
|
||||
@@ -3434,8 +3459,8 @@ Editor::apply_filter (AudioFilter& filter, string command)
|
||||
void
|
||||
Editor::region_selection_op (void (Region::*pmf)(void))
|
||||
{
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
((*i)->region.*pmf)();
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
((*i)->region().*pmf)();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3443,16 +3468,16 @@ Editor::region_selection_op (void (Region::*pmf)(void))
|
||||
void
|
||||
Editor::region_selection_op (void (Region::*pmf)(void*), void *arg)
|
||||
{
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
((*i)->region.*pmf)(arg);
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
((*i)->region().*pmf)(arg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Editor::region_selection_op (void (Region::*pmf)(bool), bool yn)
|
||||
{
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
((*i)->region.*pmf)(yn);
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
((*i)->region().*pmf)(yn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3469,20 +3494,20 @@ Editor::external_edit_region ()
|
||||
void
|
||||
Editor::brush (jack_nframes_t pos)
|
||||
{
|
||||
AudioRegionSelection sel;
|
||||
RegionSelection sel;
|
||||
snap_to (pos);
|
||||
|
||||
if (selection->audio_regions.empty()) {
|
||||
if (selection->regions.empty()) {
|
||||
/* XXX get selection from region list */
|
||||
} else {
|
||||
sel = selection->audio_regions;
|
||||
sel = selection->regions;
|
||||
}
|
||||
|
||||
if (sel.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
mouse_brush_insert_region ((*i), pos);
|
||||
}
|
||||
}
|
||||
@@ -3490,18 +3515,19 @@ Editor::brush (jack_nframes_t pos)
|
||||
void
|
||||
Editor::toggle_gain_envelope_visibility ()
|
||||
{
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
(*i)->set_envelope_visible (!(*i)->envelope_visible());
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
|
||||
if (arv)
|
||||
arv->set_envelope_visible (!arv->envelope_visible());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Editor::toggle_gain_envelope_active ()
|
||||
{
|
||||
for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
|
||||
AudioRegion* ar = dynamic_cast<AudioRegion*>(&(*i)->region);
|
||||
if (ar) {
|
||||
ar->set_envelope_active (true);
|
||||
}
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
|
||||
if (arv)
|
||||
arv->audio_region().set_envelope_active (true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,16 +38,11 @@ using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
using namespace Gtk;
|
||||
|
||||
void
|
||||
Editor::handle_new_route_p (boost::shared_ptr<Route> route)
|
||||
{
|
||||
ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_new_route_p), route));
|
||||
handle_new_route (route);
|
||||
}
|
||||
|
||||
void
|
||||
Editor::handle_new_route (boost::shared_ptr<Route> route)
|
||||
{
|
||||
ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_new_route), route));
|
||||
|
||||
TimeAxisView *tv;
|
||||
AudioTimeAxisView *atv;
|
||||
TreeModel::Row parent;
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include "editor.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "regionview.h"
|
||||
#include "audio_region_view.h"
|
||||
#include "region_selection.h"
|
||||
|
||||
#include <ardour/session.h>
|
||||
@@ -100,7 +100,7 @@ Editor::TimeStretchDialog::delete_timestretch_in_progress (GdkEventAny* ev)
|
||||
}
|
||||
|
||||
int
|
||||
Editor::run_timestretch (AudioRegionSelection& regions, float fraction)
|
||||
Editor::run_timestretch (RegionSelection& regions, float fraction)
|
||||
{
|
||||
pthread_t thread;
|
||||
|
||||
@@ -157,39 +157,42 @@ Editor::run_timestretch (AudioRegionSelection& regions, float fraction)
|
||||
void
|
||||
Editor::do_timestretch (TimeStretchDialog& dialog)
|
||||
{
|
||||
AudioTrack* at;
|
||||
Track* t;
|
||||
Playlist* playlist;
|
||||
AudioRegion* new_region;
|
||||
Region* new_region;
|
||||
|
||||
|
||||
for (AudioRegionSelection::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ) {
|
||||
for (RegionSelection::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ) {
|
||||
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*i);
|
||||
if (!arv)
|
||||
continue;
|
||||
|
||||
AudioRegion& aregion ((*i)->region);
|
||||
TimeAxisView* tv = &(*i)->get_time_axis_view();
|
||||
AudioTimeAxisView* atv;
|
||||
AudioRegionSelection::iterator tmp;
|
||||
AudioRegion& region (arv->audio_region());
|
||||
TimeAxisView* tv = &(arv->get_time_axis_view());
|
||||
RouteTimeAxisView* rtv;
|
||||
RegionSelection::iterator tmp;
|
||||
|
||||
cerr << "stretch " << aregion.name() << endl;
|
||||
cerr << "stretch " << region.name() << endl;
|
||||
|
||||
tmp = i;
|
||||
++tmp;
|
||||
|
||||
if ((atv = dynamic_cast<AudioTimeAxisView*> (tv)) == 0) {
|
||||
if ((rtv = dynamic_cast<RouteTimeAxisView*> (tv)) == 0) {
|
||||
i = tmp;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((at = atv->audio_track()) == 0) {
|
||||
if ((t = dynamic_cast<Track*> (rtv->route().get())) == 0) {
|
||||
i = tmp;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((playlist = at->disk_stream().playlist()) == 0) {
|
||||
if ((playlist = t->diskstream().playlist()) == 0) {
|
||||
i = tmp;
|
||||
continue;
|
||||
}
|
||||
|
||||
dialog.request.region = &aregion;
|
||||
dialog.request.region = ®ion;
|
||||
|
||||
if (!dialog.request.running) {
|
||||
/* we were cancelled */
|
||||
@@ -204,7 +207,7 @@ Editor::do_timestretch (TimeStretchDialog& dialog)
|
||||
}
|
||||
|
||||
session->add_undo (playlist->get_memento());
|
||||
playlist->replace_region (aregion, *new_region, aregion.position());
|
||||
playlist->replace_region (region, *new_region, region.position());
|
||||
session->add_redo_no_execute (playlist->get_memento());
|
||||
|
||||
i = tmp;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <pbd/pthread_utils.h>
|
||||
#include <ardour/audioregion.h>
|
||||
|
||||
@@ -26,11 +28,13 @@
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
ExportRegionDialog::ExportRegionDialog (PublicEditor& editor, ARDOUR::AudioRegion* region)
|
||||
ExportRegionDialog::ExportRegionDialog (PublicEditor& editor, ARDOUR::Region* region)
|
||||
: ExportDialog(editor)
|
||||
{
|
||||
audio_region = region;
|
||||
|
||||
// FIXME
|
||||
ARDOUR::AudioRegion* audio_region = dynamic_cast<ARDOUR::AudioRegion*>(region);
|
||||
assert(audio_region);
|
||||
|
||||
do_not_allow_track_and_master_selection();
|
||||
do_not_allow_channel_count_selection();
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
class ExportRegionDialog : public ExportDialog
|
||||
{
|
||||
public:
|
||||
ExportRegionDialog (PublicEditor&, ARDOUR::AudioRegion*);
|
||||
ExportRegionDialog (PublicEditor&, ARDOUR::Region*);
|
||||
|
||||
static void* _export_region_thread (void *);
|
||||
void export_region ();
|
||||
|
||||
@@ -290,8 +290,8 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr<Route> rt
|
||||
_route->panner().Changed.connect (mem_fun(*this, &MixerStrip::connect_to_pan));
|
||||
|
||||
if (is_audio_track()) {
|
||||
audio_track()->diskstream_changed.connect (mem_fun(*this, &MixerStrip::diskstream_changed));
|
||||
get_diskstream()->speed_changed.connect (mem_fun(*this, &MixerStrip::speed_changed));
|
||||
audio_track()->DiskstreamChanged.connect (mem_fun(*this, &MixerStrip::diskstream_changed));
|
||||
get_diskstream()->SpeedChanged.connect (mem_fun(*this, &MixerStrip::speed_changed));
|
||||
}
|
||||
|
||||
_route->name_changed.connect (mem_fun(*this, &RouteUI::name_changed));
|
||||
@@ -558,11 +558,6 @@ MixerStrip::input_press (GdkEventButton *ev)
|
||||
|
||||
case 1:
|
||||
|
||||
#if ADVANCED_ROUTE_DISKSTREAM_CONNECTIVITY
|
||||
if (is_audio_track()) {
|
||||
citems.push_back (MenuElem (_("Track"), mem_fun(*this, &MixerStrip::select_stream_input)));
|
||||
}
|
||||
#endif
|
||||
citems.push_back (MenuElem (_("Edit"), mem_fun(*this, &MixerStrip::edit_input_configuration)));
|
||||
citems.push_back (SeparatorElem());
|
||||
citems.push_back (MenuElem (_("Disconnect"), mem_fun (*(static_cast<RouteUI*>(this)), &RouteUI::disconnect_input)));
|
||||
@@ -659,42 +654,6 @@ MixerStrip::add_connection_to_output_menu (ARDOUR::Connection* c)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MixerStrip::select_stream_input ()
|
||||
{
|
||||
using namespace Menu_Helpers;
|
||||
|
||||
Menu *stream_menu = manage (new Menu);
|
||||
MenuList& items = stream_menu->items();
|
||||
stream_menu->set_name ("ArdourContextMenu");
|
||||
|
||||
Session::AudioDiskstreamList streams = _session.audio_disk_streams();
|
||||
|
||||
for (Session::AudioDiskstreamList::iterator i = streams.begin(); i != streams.end(); ++i) {
|
||||
|
||||
if (!(*i)->hidden()) {
|
||||
|
||||
items.push_back (CheckMenuElem ((*i)->name(), bind (mem_fun(*this, &MixerStrip::stream_input_chosen), *i)));
|
||||
|
||||
if (get_diskstream() == *i) {
|
||||
ignore_toggle = true;
|
||||
static_cast<CheckMenuItem *> (&items.back())->set_active (true);
|
||||
ignore_toggle = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stream_menu->popup (1, 0);
|
||||
}
|
||||
|
||||
void
|
||||
MixerStrip::stream_input_chosen (AudioDiskstream *stream)
|
||||
{
|
||||
if (is_audio_track()) {
|
||||
audio_track()->set_diskstream (*stream, this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MixerStrip::update_diskstream_display ()
|
||||
{
|
||||
@@ -785,7 +744,7 @@ MixerStrip::fast_update ()
|
||||
}
|
||||
|
||||
void
|
||||
MixerStrip::diskstream_changed (void *src)
|
||||
MixerStrip::diskstream_changed ()
|
||||
{
|
||||
Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &MixerStrip::update_diskstream_display));
|
||||
}
|
||||
@@ -1181,7 +1140,7 @@ MixerStrip::route_active_changed ()
|
||||
gpm.set_meter_strip_name ("AudioTrackStripBaseInactive");
|
||||
}
|
||||
gpm.set_fader_name ("AudioTrackFader");
|
||||
} else {
|
||||
} else { // FIXME: assumed audio bus
|
||||
if (_route->active()) {
|
||||
set_name ("AudioBusStripBase");
|
||||
gpm.set_meter_strip_name ("AudioBusStripBase");
|
||||
|
||||
@@ -179,7 +179,7 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
|
||||
void edit_input_configuration ();
|
||||
void edit_output_configuration ();
|
||||
|
||||
void diskstream_changed (void *src);
|
||||
void diskstream_changed ();
|
||||
|
||||
Gtk::Menu *send_action_menu;
|
||||
void build_send_action_menu ();
|
||||
|
||||
19
gtk2_ardour/pixmaps/tool_audition.xpm
Normal file
19
gtk2_ardour/pixmaps/tool_audition.xpm
Normal file
@@ -0,0 +1,19 @@
|
||||
/* XPM */
|
||||
static char * tool_audition_xpm[] = {
|
||||
"16 12 4 1",
|
||||
" c None",
|
||||
". c #000000",
|
||||
"+ c #ECECEC",
|
||||
"@ c #FFFFFF",
|
||||
" .. ",
|
||||
" .+. . ",
|
||||
" .++. .@. ",
|
||||
"....+@+... .@. ",
|
||||
".+++@@+..@. .@.",
|
||||
".+@@@@+. .@. .@.",
|
||||
".+@@@@+. .@. .@.",
|
||||
".+++@@+..@. .@.",
|
||||
"....+@+... .@. ",
|
||||
" .++. .@. ",
|
||||
" .+. . ",
|
||||
" .. "};
|
||||
18
gtk2_ardour/pixmaps/tool_gain.xpm
Normal file
18
gtk2_ardour/pixmaps/tool_gain.xpm
Normal file
@@ -0,0 +1,18 @@
|
||||
/* XPM */
|
||||
static char * tool_gain_xpm[] = {
|
||||
"16 12 3 1",
|
||||
" c None",
|
||||
". c #000000",
|
||||
"+ c #FFFFFF",
|
||||
"... ",
|
||||
".++.. ",
|
||||
"...++. ",
|
||||
" ..+. ",
|
||||
" .+. ",
|
||||
" .+. ",
|
||||
" .+. ",
|
||||
" .+. ",
|
||||
" .+.. ",
|
||||
" .++.....",
|
||||
" ..++++.",
|
||||
" ....."};
|
||||
18
gtk2_ardour/pixmaps/tool_object.xpm
Normal file
18
gtk2_ardour/pixmaps/tool_object.xpm
Normal file
@@ -0,0 +1,18 @@
|
||||
/* XPM */
|
||||
static char * tool_object_xpm[] = {
|
||||
"16 12 3 1",
|
||||
" c None",
|
||||
". c #000000",
|
||||
"+ c #FFFFFF",
|
||||
" ... ",
|
||||
" .+. ",
|
||||
" .+. ",
|
||||
" .+. ",
|
||||
" .+..... ",
|
||||
" .+.+.+... ",
|
||||
" ...+.+.+.+. ",
|
||||
" .+.+++++++. ",
|
||||
" .+++++++++. ",
|
||||
" ..+++++++.. ",
|
||||
" ...+++++. ",
|
||||
" .+++++. "};
|
||||
18
gtk2_ardour/pixmaps/tool_range.xpm
Normal file
18
gtk2_ardour/pixmaps/tool_range.xpm
Normal file
@@ -0,0 +1,18 @@
|
||||
/* XPM */
|
||||
static char * tool_range_xpm[] = {
|
||||
"16 12 3 1",
|
||||
" c None",
|
||||
". c #000000",
|
||||
"+ c #FFFFFF",
|
||||
"... ...",
|
||||
".+. .. .. .+.",
|
||||
".+. .+. .+. .+.",
|
||||
".+..+. .+..+.",
|
||||
".+.++......++.+.",
|
||||
".++++++++++++++.",
|
||||
".+.++......++.+.",
|
||||
".+..+. .+..+.",
|
||||
".+. .+. .+. .+.",
|
||||
".+. .. .. .+.",
|
||||
".+. .+.",
|
||||
"... ..."};
|
||||
18
gtk2_ardour/pixmaps/tool_stretch.xpm
Normal file
18
gtk2_ardour/pixmaps/tool_stretch.xpm
Normal file
@@ -0,0 +1,18 @@
|
||||
/* XPM */
|
||||
static char * tool_stretch_xpm[] = {
|
||||
"16 12 3 1",
|
||||
" c None",
|
||||
". c #000000",
|
||||
"+ c #FFFFFF",
|
||||
" .. .. ",
|
||||
" .+. .+. ",
|
||||
".++..........++.",
|
||||
"++++++++++++++++",
|
||||
".++..........++.",
|
||||
" .+. .+. ",
|
||||
" .. .. ",
|
||||
" + + + + ",
|
||||
" ++ +++ + + +++ ",
|
||||
"++++++++++++++++",
|
||||
" ++ + ++ + + ",
|
||||
" + + + + "};
|
||||
29
gtk2_ardour/pixmaps/tool_zoom.xpm
Normal file
29
gtk2_ardour/pixmaps/tool_zoom.xpm
Normal file
@@ -0,0 +1,29 @@
|
||||
/* XPM */
|
||||
static char * tool_zoom_xpm[] = {
|
||||
"16 12 14 1",
|
||||
" c None",
|
||||
". c #000000",
|
||||
"+ c #474747",
|
||||
"@ c #E7E7E7",
|
||||
"# c #F6F6F6",
|
||||
"$ c #DCDCDC",
|
||||
"% c #FFFFFF",
|
||||
"& c #DFDFDF",
|
||||
"* c #D7D7D7",
|
||||
"= c #D6D6D6",
|
||||
"- c #040404",
|
||||
"; c #070707",
|
||||
"> c #060606",
|
||||
", c #050505",
|
||||
" ... ",
|
||||
" +.@#$.+ ",
|
||||
" .%%%%%. ",
|
||||
" .&%%%%%*. ",
|
||||
" .#%%%%%#. ",
|
||||
" .$%%%%%&. ",
|
||||
" .%%%%%.+ ",
|
||||
" +.*#=... ",
|
||||
" ...+... ",
|
||||
" -.; ",
|
||||
" >.- ",
|
||||
" ,. "};
|
||||
30
gtk2_ardour/pixmaps/zoom_full.xpm
Normal file
30
gtk2_ardour/pixmaps/zoom_full.xpm
Normal file
@@ -0,0 +1,30 @@
|
||||
/* XPM */
|
||||
static char * zoom_full_xpm[] = {
|
||||
"12 12 15 1",
|
||||
" c None",
|
||||
". c #000000",
|
||||
"+ c #474747",
|
||||
"@ c #E7E7E7",
|
||||
"# c #F6F6F6",
|
||||
"$ c #DCDCDC",
|
||||
"% c #ACACAC",
|
||||
"& c #FFFFFF",
|
||||
"* c #DFDFDF",
|
||||
"= c #D7D7D7",
|
||||
"- c #D6D6D6",
|
||||
"; c #040404",
|
||||
"> c #070707",
|
||||
", c #060606",
|
||||
"' c #050505",
|
||||
" ... ",
|
||||
" +.@#$.+ ",
|
||||
" .%&&&%. ",
|
||||
".*..&..=. ",
|
||||
".#.&&&.#. ",
|
||||
".$..&..*. ",
|
||||
" .%&&&%.+ ",
|
||||
" +.=#-... ",
|
||||
" ...+... ",
|
||||
" ;.> ",
|
||||
" ,.;",
|
||||
" '."};
|
||||
29
gtk2_ardour/pixmaps/zoom_in.xpm
Normal file
29
gtk2_ardour/pixmaps/zoom_in.xpm
Normal file
@@ -0,0 +1,29 @@
|
||||
/* XPM */
|
||||
static char * zoom_in_xpm[] = {
|
||||
"12 12 14 1",
|
||||
" c None",
|
||||
". c #000000",
|
||||
"+ c #474747",
|
||||
"@ c #E7E7E7",
|
||||
"# c #F6F6F6",
|
||||
"$ c #DCDCDC",
|
||||
"% c #FFFFFF",
|
||||
"& c #DFDFDF",
|
||||
"* c #D7D7D7",
|
||||
"= c #D6D6D6",
|
||||
"- c #040404",
|
||||
"; c #070707",
|
||||
"> c #060606",
|
||||
", c #050505",
|
||||
" ... ",
|
||||
" +.@#$.+ ",
|
||||
" .%%.%%. ",
|
||||
".&%%.%%*. ",
|
||||
".#.....#. ",
|
||||
".$%%.%%&. ",
|
||||
" .%%.%%.+ ",
|
||||
" +.*#=... ",
|
||||
" ...+... ",
|
||||
" -.; ",
|
||||
" >.-",
|
||||
" ,."};
|
||||
29
gtk2_ardour/pixmaps/zoom_out.xpm
Normal file
29
gtk2_ardour/pixmaps/zoom_out.xpm
Normal file
@@ -0,0 +1,29 @@
|
||||
/* XPM */
|
||||
static char * zoom_out_xpm[] = {
|
||||
"12 12 14 1",
|
||||
" c None",
|
||||
". c #000000",
|
||||
"+ c #474747",
|
||||
"@ c #E7E7E7",
|
||||
"# c #F6F6F6",
|
||||
"$ c #DCDCDC",
|
||||
"% c #FFFFFF",
|
||||
"& c #DFDFDF",
|
||||
"* c #D7D7D7",
|
||||
"= c #D6D6D6",
|
||||
"- c #040404",
|
||||
"; c #070707",
|
||||
"> c #060606",
|
||||
", c #050505",
|
||||
" ... ",
|
||||
" +.@#$.+ ",
|
||||
" .%%%%%. ",
|
||||
".&%%%%%*. ",
|
||||
".#.....#. ",
|
||||
".$%%%%%&. ",
|
||||
" .%%%%%.+ ",
|
||||
" +.*#=... ",
|
||||
" ...+... ",
|
||||
" -.; ",
|
||||
" >.-",
|
||||
" ,."};
|
||||
@@ -90,7 +90,7 @@ void
|
||||
PlaylistSelector::show_for (RouteUI* ruix)
|
||||
{
|
||||
vector<const char*> item;
|
||||
AudioDiskstream* this_ds;
|
||||
Diskstream* this_ds;
|
||||
string str;
|
||||
|
||||
rui = ruix;
|
||||
@@ -116,7 +116,7 @@ PlaylistSelector::show_for (RouteUI* ruix)
|
||||
|
||||
for (DSPL_Map::iterator x = dspl_map.begin(); x != dspl_map.end(); ++x) {
|
||||
|
||||
AudioDiskstream* ds = session->diskstream_by_id (x->first);
|
||||
Diskstream* ds = session->diskstream_by_id (x->first);
|
||||
|
||||
if (ds == 0) {
|
||||
continue;
|
||||
@@ -243,7 +243,7 @@ PlaylistSelector::selection_changed ()
|
||||
return;
|
||||
}
|
||||
|
||||
at->disk_stream().use_playlist (apl);
|
||||
at->diskstream().use_playlist (apl);
|
||||
|
||||
hide ();
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace ARDOUR {
|
||||
class Session;
|
||||
class PluginManager;
|
||||
class Plugin;
|
||||
class PluginInfo;
|
||||
}
|
||||
|
||||
class PluginSelector : public ArdourDialog
|
||||
|
||||
@@ -39,7 +39,7 @@ class AutomationLine;
|
||||
class ControlPoint;
|
||||
class SelectionRect;
|
||||
class CrossfadeView;
|
||||
class AudioTimeAxisView;
|
||||
class RouteTimeAxisView;
|
||||
class AudioRegionView;
|
||||
class TempoMarker;
|
||||
class MeterMarker;
|
||||
@@ -145,10 +145,10 @@ class PublicEditor : public Gtk::Window, public Stateful {
|
||||
virtual bool canvas_fade_in_handle_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0;
|
||||
virtual bool canvas_fade_out_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0;
|
||||
virtual bool canvas_fade_out_handle_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0;
|
||||
virtual bool canvas_region_view_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0;
|
||||
virtual bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0;
|
||||
virtual bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0;
|
||||
virtual bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, AudioTimeAxisView*) = 0;
|
||||
virtual bool canvas_region_view_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*) = 0;
|
||||
virtual bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*) = 0;
|
||||
virtual bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*) = 0;
|
||||
virtual bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, RouteTimeAxisView*) = 0;
|
||||
virtual bool canvas_marker_event (GdkEvent* event,ArdourCanvas::Item*, Marker*) = 0;
|
||||
virtual bool canvas_zoom_rect_event (GdkEvent* event,ArdourCanvas::Item*) = 0;
|
||||
virtual bool canvas_tempo_marker_event (GdkEvent* event,ArdourCanvas::Item*, TempoMarker*) = 0;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <ardour/audioregion.h>
|
||||
|
||||
#include "region_gain_line.h"
|
||||
#include "regionview.h"
|
||||
#include "audio_region_view.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "time_axis_view.h"
|
||||
@@ -46,8 +46,8 @@ void
|
||||
AudioRegionGainLine::start_drag (ControlPoint* cp, float fraction)
|
||||
{
|
||||
AutomationLine::start_drag(cp,fraction);
|
||||
if (!rv.region.envelope_active()) {
|
||||
trackview.session().add_undo( bind( mem_fun(rv.region, &AudioRegion::set_envelope_active), false) );
|
||||
if (!rv.audio_region().envelope_active()) {
|
||||
trackview.session().add_undo( bind( mem_fun(rv.audio_region(), &AudioRegion::set_envelope_active), false) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,10 +62,10 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
|
||||
trackview.editor.current_session()->begin_reversible_command (_("remove control point"));
|
||||
trackview.editor.current_session()->add_undo (get_memento());
|
||||
|
||||
if (!rv.region.envelope_active()) {
|
||||
trackview.session().add_undo( bind( mem_fun(rv.region, &AudioRegion::set_envelope_active), false) );
|
||||
trackview.session().add_redo( bind( mem_fun(rv.region, &AudioRegion::set_envelope_active), true) );
|
||||
rv.region.set_envelope_active(true);
|
||||
if (!rv.audio_region().envelope_active()) {
|
||||
trackview.session().add_undo( bind( mem_fun(rv.audio_region(), &AudioRegion::set_envelope_active), false) );
|
||||
trackview.session().add_redo( bind( mem_fun(rv.audio_region(), &AudioRegion::set_envelope_active), true) );
|
||||
rv.audio_region().set_envelope_active(true);
|
||||
}
|
||||
|
||||
alist.erase (mr.start, mr.end);
|
||||
@@ -78,9 +78,9 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
|
||||
void
|
||||
AudioRegionGainLine::end_drag (ControlPoint* cp)
|
||||
{
|
||||
if (!rv.region.envelope_active()) {
|
||||
trackview.session().add_redo( bind( mem_fun(rv.region, &AudioRegion::set_envelope_active), true) );
|
||||
rv.region.set_envelope_active(true);
|
||||
if (!rv.audio_region().envelope_active()) {
|
||||
trackview.session().add_redo( bind( mem_fun(rv.audio_region(), &AudioRegion::set_envelope_active), true) );
|
||||
rv.audio_region().set_envelope_active(true);
|
||||
}
|
||||
AutomationLine::end_drag(cp);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,26 @@
|
||||
/*
|
||||
Copyright (C) 2006 Paul Davis
|
||||
|
||||
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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <ardour/audioregion.h>
|
||||
#include <ardour/region.h>
|
||||
|
||||
#include "regionview.h"
|
||||
#include "region_view.h"
|
||||
#include "region_selection.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
@@ -11,7 +29,7 @@ using namespace sigc;
|
||||
|
||||
|
||||
bool
|
||||
AudioRegionComparator::operator() (const AudioRegionView* a, const AudioRegionView* b) const
|
||||
RegionComparator::operator() (const RegionView* a, const RegionView* b) const
|
||||
{
|
||||
if (a == b) {
|
||||
return false;
|
||||
@@ -20,16 +38,16 @@ AudioRegionComparator::operator() (const AudioRegionView* a, const AudioRegionVi
|
||||
}
|
||||
}
|
||||
|
||||
AudioRegionSelection::AudioRegionSelection ()
|
||||
RegionSelection::RegionSelection ()
|
||||
{
|
||||
_current_start = 0;
|
||||
_current_end = 0;
|
||||
}
|
||||
|
||||
AudioRegionSelection::AudioRegionSelection (const AudioRegionSelection& other)
|
||||
RegionSelection::RegionSelection (const RegionSelection& other)
|
||||
{
|
||||
|
||||
for (AudioRegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
|
||||
for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
|
||||
add (*i, false);
|
||||
}
|
||||
_current_start = other._current_start;
|
||||
@@ -38,14 +56,14 @@ AudioRegionSelection::AudioRegionSelection (const AudioRegionSelection& other)
|
||||
|
||||
|
||||
|
||||
AudioRegionSelection&
|
||||
AudioRegionSelection::operator= (const AudioRegionSelection& other)
|
||||
RegionSelection&
|
||||
RegionSelection::operator= (const RegionSelection& other)
|
||||
{
|
||||
if (this != &other) {
|
||||
|
||||
clear_all();
|
||||
|
||||
for (AudioRegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
|
||||
for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
|
||||
add (*i, false);
|
||||
}
|
||||
|
||||
@@ -57,13 +75,13 @@ AudioRegionSelection::operator= (const AudioRegionSelection& other)
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegionSelection::clear_all()
|
||||
RegionSelection::clear_all()
|
||||
{
|
||||
clear();
|
||||
_bylayer.clear();
|
||||
}
|
||||
|
||||
bool AudioRegionSelection::contains (AudioRegionView* rv)
|
||||
bool RegionSelection::contains (RegionView* rv)
|
||||
{
|
||||
if (this->find (rv) != end()) {
|
||||
return true;
|
||||
@@ -75,21 +93,21 @@ bool AudioRegionSelection::contains (AudioRegionView* rv)
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegionSelection::add (AudioRegionView* rv, bool dosort)
|
||||
RegionSelection::add (RegionView* rv, bool dosort)
|
||||
{
|
||||
if (this->find (rv) != end()) {
|
||||
/* we already have it */
|
||||
return;
|
||||
}
|
||||
|
||||
rv->AudioRegionViewGoingAway.connect (mem_fun(*this, &AudioRegionSelection::remove_it));
|
||||
rv->RegionViewGoingAway.connect (mem_fun(*this, &RegionSelection::remove_it));
|
||||
|
||||
if (rv->region.first_frame() < _current_start || empty()) {
|
||||
_current_start = rv->region.first_frame();
|
||||
if (rv->region().first_frame() < _current_start || empty()) {
|
||||
_current_start = rv->region().first_frame();
|
||||
}
|
||||
|
||||
if (rv->region.last_frame() > _current_end || empty()) {
|
||||
_current_end = rv->region.last_frame();
|
||||
if (rv->region().last_frame() > _current_end || empty()) {
|
||||
_current_end = rv->region().last_frame();
|
||||
}
|
||||
|
||||
insert (rv);
|
||||
@@ -100,15 +118,15 @@ AudioRegionSelection::add (AudioRegionView* rv, bool dosort)
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegionSelection::remove_it (AudioRegionView *rv)
|
||||
RegionSelection::remove_it (RegionView *rv)
|
||||
{
|
||||
remove (rv);
|
||||
}
|
||||
|
||||
bool
|
||||
AudioRegionSelection::remove (AudioRegionView* rv)
|
||||
RegionSelection::remove (RegionView* rv)
|
||||
{
|
||||
AudioRegionSelection::iterator i;
|
||||
RegionSelection::iterator i;
|
||||
|
||||
if ((i = this->find (rv)) != end()) {
|
||||
|
||||
@@ -124,7 +142,7 @@ AudioRegionSelection::remove (AudioRegionView* rv)
|
||||
|
||||
} else {
|
||||
|
||||
AudioRegion& region ((*i)->region);
|
||||
Region& region ((*i)->region());
|
||||
|
||||
if (region.first_frame() == _current_start) {
|
||||
|
||||
@@ -165,15 +183,15 @@ AudioRegionSelection::remove (AudioRegionView* rv)
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegionSelection::add_to_layer (AudioRegionView * rv)
|
||||
RegionSelection::add_to_layer (RegionView * rv)
|
||||
{
|
||||
// insert it into layer sorted position
|
||||
|
||||
list<AudioRegionView*>::iterator i;
|
||||
list<RegionView*>::iterator i;
|
||||
|
||||
for (i = _bylayer.begin(); i != _bylayer.end(); ++i)
|
||||
{
|
||||
if (rv->region.layer() < (*i)->region.layer()) {
|
||||
if (rv->region().layer() < (*i)->region().layer()) {
|
||||
_bylayer.insert(i, rv);
|
||||
return;
|
||||
}
|
||||
@@ -184,16 +202,16 @@ AudioRegionSelection::add_to_layer (AudioRegionView * rv)
|
||||
}
|
||||
|
||||
struct RegionSortByTime {
|
||||
bool operator() (const AudioRegionView* a, const AudioRegionView* b) {
|
||||
return a->region.position() < b->region.position();
|
||||
bool operator() (const RegionView* a, const RegionView* b) {
|
||||
return a->region().position() < b->region().position();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
AudioRegionSelection::by_position (list<AudioRegionView*>& foo) const
|
||||
RegionSelection::by_position (list<RegionView*>& foo) const
|
||||
{
|
||||
list<AudioRegionView*>::const_iterator i;
|
||||
list<RegionView*>::const_iterator i;
|
||||
RegionSortByTime sorter;
|
||||
|
||||
for (i = _bylayer.begin(); i != _bylayer.end(); ++i) {
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
Copyright (C) 2006 Paul Davis
|
||||
|
||||
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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ardour_gtk_region_selection_h__
|
||||
#define __ardour_gtk_region_selection_h__
|
||||
|
||||
@@ -9,23 +27,23 @@
|
||||
using std::list;
|
||||
using std::set;
|
||||
|
||||
class AudioRegionView;
|
||||
class RegionView;
|
||||
|
||||
struct AudioRegionComparator {
|
||||
bool operator() (const AudioRegionView* a, const AudioRegionView* b) const;
|
||||
struct RegionComparator {
|
||||
bool operator() (const RegionView* a, const RegionView* b) const;
|
||||
};
|
||||
|
||||
class AudioRegionSelection : public set<AudioRegionView*, AudioRegionComparator>, public sigc::trackable
|
||||
class RegionSelection : public set<RegionView*, RegionComparator>, public sigc::trackable
|
||||
{
|
||||
public:
|
||||
AudioRegionSelection();
|
||||
AudioRegionSelection (const AudioRegionSelection&);
|
||||
RegionSelection();
|
||||
RegionSelection (const RegionSelection&);
|
||||
|
||||
AudioRegionSelection& operator= (const AudioRegionSelection&);
|
||||
RegionSelection& operator= (const RegionSelection&);
|
||||
|
||||
void add (AudioRegionView*, bool dosort = true);
|
||||
bool remove (AudioRegionView*);
|
||||
bool contains (AudioRegionView*);
|
||||
void add (RegionView*, bool dosort = true);
|
||||
bool remove (RegionView*);
|
||||
bool contains (RegionView*);
|
||||
|
||||
void clear_all();
|
||||
|
||||
@@ -39,18 +57,18 @@ class AudioRegionSelection : public set<AudioRegionView*, AudioRegionComparator>
|
||||
return _current_end;
|
||||
}
|
||||
|
||||
const list<AudioRegionView *> & by_layer() const { return _bylayer; }
|
||||
void by_position (list<AudioRegionView*>&) const;
|
||||
const list<RegionView *> & by_layer() const { return _bylayer; }
|
||||
void by_position (list<RegionView*>&) const;
|
||||
|
||||
private:
|
||||
void remove_it (AudioRegionView*);
|
||||
void remove_it (RegionView*);
|
||||
|
||||
void add_to_layer (AudioRegionView *);
|
||||
void add_to_layer (RegionView *);
|
||||
|
||||
jack_nframes_t _current_start;
|
||||
jack_nframes_t _current_end;
|
||||
|
||||
list<AudioRegionView *> _bylayer;
|
||||
list<RegionView *> _bylayer;
|
||||
};
|
||||
|
||||
#endif /* __ardour_gtk_region_selection_h__ */
|
||||
|
||||
494
gtk2_ardour/region_view.cc
Normal file
494
gtk2_ardour/region_view.cc
Normal file
@@ -0,0 +1,494 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006 Paul Davis
|
||||
|
||||
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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: regionview.cc 691 2006-07-23 12:03:19Z drobilla $
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
#include <gtkmm.h>
|
||||
|
||||
#include <gtkmm2ext/gtk_ui.h>
|
||||
|
||||
#include <ardour/playlist.h>
|
||||
#include <ardour/audioregion.h>
|
||||
#include <ardour/audiosource.h>
|
||||
#include <ardour/audio_diskstream.h>
|
||||
|
||||
#include "streamview.h"
|
||||
#include "region_view.h"
|
||||
#include "route_time_axis.h"
|
||||
#include "simplerect.h"
|
||||
#include "simpleline.h"
|
||||
#include "waveview.h"
|
||||
#include "public_editor.h"
|
||||
#include "region_editor.h"
|
||||
#include "ghostregion.h"
|
||||
#include "route_time_axis.h"
|
||||
#include "utils.h"
|
||||
#include "rgb_macros.h"
|
||||
#include "gui_thread.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace sigc;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
using namespace Editing;
|
||||
using namespace ArdourCanvas;
|
||||
|
||||
static const int32_t sync_mark_width = 9;
|
||||
|
||||
sigc::signal<void,RegionView*> RegionView::RegionViewGoingAway;
|
||||
|
||||
RegionView::RegionView (ArdourCanvas::Group* parent,
|
||||
TimeAxisView& tv,
|
||||
ARDOUR::Region& r,
|
||||
double spu,
|
||||
Gdk::Color& basic_color)
|
||||
: TimeAxisViewItem (r.name(), *parent, tv, spu, basic_color, r.position(), r.length(),
|
||||
TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowNameText|
|
||||
TimeAxisViewItem::ShowNameHighlight|
|
||||
TimeAxisViewItem::ShowFrame))
|
||||
, _region (r)
|
||||
, sync_mark(0)
|
||||
, no_wave_msg(0)
|
||||
, editor(0)
|
||||
, current_visible_sync_position(0.0)
|
||||
, valid(false)
|
||||
, _pixel_width(1.0)
|
||||
, _height(1.0)
|
||||
, in_destructor(false)
|
||||
, wait_for_data(false)
|
||||
{
|
||||
}
|
||||
|
||||
RegionView::RegionView (ArdourCanvas::Group* parent,
|
||||
TimeAxisView& tv,
|
||||
ARDOUR::Region& r,
|
||||
double spu,
|
||||
Gdk::Color& basic_color,
|
||||
TimeAxisViewItem::Visibility visibility)
|
||||
: TimeAxisViewItem (r.name(), *parent, tv, spu, basic_color, r.position(), r.length(), visibility)
|
||||
, _region (r)
|
||||
, sync_mark(0)
|
||||
, no_wave_msg(0)
|
||||
, editor(0)
|
||||
, current_visible_sync_position(0.0)
|
||||
, valid(false)
|
||||
, _pixel_width(1.0)
|
||||
, _height(1.0)
|
||||
, in_destructor(false)
|
||||
, wait_for_data(false)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::init (Gdk::Color& basic_color, bool wfd)
|
||||
{
|
||||
editor = 0;
|
||||
valid = true;
|
||||
in_destructor = false;
|
||||
_height = 0;
|
||||
wait_for_data = wfd;
|
||||
|
||||
compute_colors (basic_color);
|
||||
|
||||
name_highlight->set_data ("regionview", this);
|
||||
name_text->set_data ("regionview", this);
|
||||
|
||||
/* an equilateral triangle */
|
||||
ArdourCanvas::Points shape;
|
||||
shape.push_back (Gnome::Art::Point (-((sync_mark_width-1)/2), 1));
|
||||
shape.push_back (Gnome::Art::Point ((sync_mark_width - 1)/2, 1));
|
||||
shape.push_back (Gnome::Art::Point (0, sync_mark_width - 1));
|
||||
shape.push_back (Gnome::Art::Point (-((sync_mark_width-1)/2), 1));
|
||||
|
||||
sync_mark = new ArdourCanvas::Polygon (*group);
|
||||
sync_mark->property_points() = shape;
|
||||
sync_mark->property_fill_color_rgba() = fill_color;
|
||||
sync_mark->hide();
|
||||
|
||||
reset_width_dependent_items ((double) _region.length() / samples_per_unit);
|
||||
|
||||
set_height (trackview.height);
|
||||
|
||||
region_muted ();
|
||||
region_sync_changed ();
|
||||
region_resized (BoundsChanged);
|
||||
region_locked ();
|
||||
|
||||
_region.StateChanged.connect (mem_fun(*this, &RegionView::region_changed));
|
||||
|
||||
group->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_event), group, this));
|
||||
name_highlight->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_name_highlight_event), name_highlight, this));
|
||||
|
||||
set_colors ();
|
||||
|
||||
ColorChanged.connect (mem_fun (*this, &RegionView::color_handler));
|
||||
|
||||
/* XXX sync mark drag? */
|
||||
}
|
||||
|
||||
RegionView::~RegionView ()
|
||||
{
|
||||
in_destructor = true;
|
||||
|
||||
RegionViewGoingAway (this); /* EMIT_SIGNAL */
|
||||
|
||||
for (vector<GhostRegion*>::iterator g = ghosts.begin(); g != ghosts.end(); ++g) {
|
||||
delete *g;
|
||||
}
|
||||
|
||||
if (editor) {
|
||||
delete editor;
|
||||
}
|
||||
}
|
||||
|
||||
gint
|
||||
RegionView::_lock_toggle (ArdourCanvas::Item* item, GdkEvent* ev, void* arg)
|
||||
{
|
||||
switch (ev->type) {
|
||||
case GDK_BUTTON_RELEASE:
|
||||
static_cast<RegionView*>(arg)->lock_toggle ();
|
||||
return TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::lock_toggle ()
|
||||
{
|
||||
_region.set_locked (!_region.locked());
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::region_changed (Change what_changed)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun(*this, &RegionView::region_changed), what_changed));
|
||||
|
||||
if (what_changed & BoundsChanged) {
|
||||
region_resized (what_changed);
|
||||
region_sync_changed ();
|
||||
}
|
||||
if (what_changed & Region::MuteChanged) {
|
||||
region_muted ();
|
||||
}
|
||||
if (what_changed & Region::OpacityChanged) {
|
||||
region_opacity ();
|
||||
}
|
||||
if (what_changed & ARDOUR::NameChanged) {
|
||||
region_renamed ();
|
||||
}
|
||||
if (what_changed & Region::SyncOffsetChanged) {
|
||||
region_sync_changed ();
|
||||
}
|
||||
if (what_changed & Region::LayerChanged) {
|
||||
region_layered ();
|
||||
}
|
||||
if (what_changed & Region::LockChanged) {
|
||||
region_locked ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::region_locked ()
|
||||
{
|
||||
/* name will show locked status */
|
||||
region_renamed ();
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::region_resized (Change what_changed)
|
||||
{
|
||||
double unit_length;
|
||||
|
||||
if (what_changed & ARDOUR::PositionChanged) {
|
||||
set_position (_region.position(), 0);
|
||||
}
|
||||
|
||||
if (what_changed & Change (StartChanged|LengthChanged)) {
|
||||
|
||||
set_duration (_region.length(), 0);
|
||||
|
||||
unit_length = _region.length() / samples_per_unit;
|
||||
|
||||
reset_width_dependent_items (unit_length);
|
||||
|
||||
for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
|
||||
|
||||
(*i)->set_duration (unit_length);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::reset_width_dependent_items (double pixel_width)
|
||||
{
|
||||
TimeAxisViewItem::reset_width_dependent_items (pixel_width);
|
||||
_pixel_width = pixel_width;
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::region_layered ()
|
||||
{
|
||||
RouteTimeAxisView *rtv = dynamic_cast<RouteTimeAxisView*>(&get_time_axis_view());
|
||||
assert(rtv);
|
||||
rtv->view()->region_layered (this);
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::region_muted ()
|
||||
{
|
||||
set_frame_color ();
|
||||
region_renamed ();
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::region_opacity ()
|
||||
{
|
||||
set_frame_color ();
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::raise ()
|
||||
{
|
||||
_region.raise ();
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::raise_to_top ()
|
||||
{
|
||||
_region.raise_to_top ();
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::lower ()
|
||||
{
|
||||
_region.lower ();
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::lower_to_bottom ()
|
||||
{
|
||||
_region.lower_to_bottom ();
|
||||
}
|
||||
|
||||
bool
|
||||
RegionView::set_position (jack_nframes_t pos, void* src, double* ignored)
|
||||
{
|
||||
double delta;
|
||||
bool ret;
|
||||
|
||||
if (!(ret = TimeAxisViewItem::set_position (pos, this, &delta))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ignored) {
|
||||
*ignored = delta;
|
||||
}
|
||||
|
||||
if (delta) {
|
||||
for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
|
||||
(*i)->group->move (delta, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::set_samples_per_unit (gdouble spu)
|
||||
{
|
||||
TimeAxisViewItem::set_samples_per_unit (spu);
|
||||
|
||||
for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
|
||||
(*i)->set_samples_per_unit (spu);
|
||||
(*i)->set_duration (_region.length() / samples_per_unit);
|
||||
}
|
||||
|
||||
region_sync_changed ();
|
||||
}
|
||||
|
||||
bool
|
||||
RegionView::set_duration (jack_nframes_t frames, void *src)
|
||||
{
|
||||
if (!TimeAxisViewItem::set_duration (frames, src)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
|
||||
(*i)->set_duration (_region.length() / samples_per_unit);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::compute_colors (Gdk::Color& basic_color)
|
||||
{
|
||||
TimeAxisViewItem::compute_colors (basic_color);
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::set_colors ()
|
||||
{
|
||||
TimeAxisViewItem::set_colors ();
|
||||
|
||||
if (sync_mark) {
|
||||
sync_mark->property_fill_color_rgba() = fill_color;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::set_frame_color ()
|
||||
{
|
||||
if (_region.opaque()) {
|
||||
fill_opacity = 180;
|
||||
} else {
|
||||
fill_opacity = 100;
|
||||
}
|
||||
|
||||
TimeAxisViewItem::set_frame_color ();
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::hide_region_editor()
|
||||
{
|
||||
if (editor) {
|
||||
editor->hide_all ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::region_renamed ()
|
||||
{
|
||||
string str;
|
||||
|
||||
if (_region.locked()) {
|
||||
str += '>';
|
||||
str += _region.name();
|
||||
str += '<';
|
||||
} else {
|
||||
str = _region.name();
|
||||
}
|
||||
|
||||
if (_region.speed_mismatch (trackview.session().frame_rate())) {
|
||||
str = string ("*") + str;
|
||||
}
|
||||
|
||||
if (_region.muted()) {
|
||||
str = string ("!") + str;
|
||||
}
|
||||
|
||||
set_item_name (str, this);
|
||||
set_name_text (str);
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::region_sync_changed ()
|
||||
{
|
||||
if (sync_mark == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int sync_dir;
|
||||
jack_nframes_t sync_offset;
|
||||
|
||||
sync_offset = _region.sync_offset (sync_dir);
|
||||
|
||||
/* this has to handle both a genuine change of position, a change of samples_per_unit,
|
||||
and a change in the bounds of the _region.
|
||||
*/
|
||||
|
||||
if (sync_offset == 0) {
|
||||
|
||||
/* no sync mark - its the start of the region */
|
||||
|
||||
sync_mark->hide();
|
||||
|
||||
} else {
|
||||
|
||||
if ((sync_dir < 0) || ((sync_dir > 0) && (sync_offset > _region.length()))) {
|
||||
|
||||
/* no sync mark - its out of the bounds of the region */
|
||||
|
||||
sync_mark->hide();
|
||||
|
||||
} else {
|
||||
|
||||
/* lets do it */
|
||||
|
||||
Points points;
|
||||
|
||||
//points = sync_mark->property_points().get_value();
|
||||
|
||||
double offset = sync_offset / samples_per_unit;
|
||||
points.push_back (Gnome::Art::Point (offset - ((sync_mark_width-1)/2), 1));
|
||||
points.push_back (Gnome::Art::Point (offset + ((sync_mark_width-1)/2), 1));
|
||||
points.push_back (Gnome::Art::Point (offset, sync_mark_width - 1));
|
||||
points.push_back (Gnome::Art::Point (offset - ((sync_mark_width-1)/2), 1));
|
||||
sync_mark->property_points().set_value (points);
|
||||
sync_mark->show();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::move (double x_delta, double y_delta)
|
||||
{
|
||||
if (_region.locked() || (x_delta == 0 && y_delta == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
get_canvas_group()->move (x_delta, y_delta);
|
||||
|
||||
/* note: ghosts never leave their tracks so y_delta for them is always zero */
|
||||
|
||||
for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
|
||||
(*i)->group->move (x_delta, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegionView::remove_ghost (GhostRegion* ghost)
|
||||
{
|
||||
if (in_destructor) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
|
||||
if (*i == ghost) {
|
||||
ghosts.erase (i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RegionView::get_fill_color ()
|
||||
{
|
||||
return fill_color;
|
||||
}
|
||||
|
||||
140
gtk2_ardour/region_view.h
Normal file
140
gtk2_ardour/region_view.h
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006 Paul Davis
|
||||
|
||||
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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __gtk_ardour_region_view_h__
|
||||
#define __gtk_ardour_region_view_h__
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <libgnomecanvasmm.h>
|
||||
#include <libgnomecanvasmm/polygon.h>
|
||||
#include <sigc++/signal.h>
|
||||
#include <ardour/region.h>
|
||||
|
||||
#include "time_axis_view_item.h"
|
||||
#include "automation_line.h"
|
||||
#include "enums.h"
|
||||
#include "waveview.h"
|
||||
#include "canvas.h"
|
||||
#include "color.h"
|
||||
|
||||
class TimeAxisView;
|
||||
class RegionEditor;
|
||||
class GhostRegion;
|
||||
class AutomationTimeAxisView;
|
||||
|
||||
class RegionView : public TimeAxisViewItem
|
||||
{
|
||||
public:
|
||||
RegionView (ArdourCanvas::Group* parent,
|
||||
TimeAxisView& time_view,
|
||||
ARDOUR::Region& region,
|
||||
double samples_per_unit,
|
||||
Gdk::Color& basic_color);
|
||||
|
||||
~RegionView ();
|
||||
|
||||
virtual void init (Gdk::Color& base_color, bool wait_for_data);
|
||||
|
||||
ARDOUR::Region& region() const { return _region; }
|
||||
|
||||
bool is_valid() const { return valid; }
|
||||
void set_valid (bool yn) { valid = yn; }
|
||||
|
||||
virtual void set_height (double) = 0;
|
||||
virtual void set_samples_per_unit (double);
|
||||
virtual bool set_duration (jack_nframes_t, void*);
|
||||
|
||||
void move (double xdelta, double ydelta);
|
||||
|
||||
void raise ();
|
||||
void raise_to_top ();
|
||||
void lower ();
|
||||
void lower_to_bottom ();
|
||||
|
||||
bool set_position(jack_nframes_t pos, void* src, double* delta = 0);
|
||||
|
||||
virtual void show_region_editor () = 0;
|
||||
virtual void hide_region_editor();
|
||||
|
||||
virtual void region_changed (ARDOUR::Change);
|
||||
|
||||
virtual GhostRegion* add_ghost (AutomationTimeAxisView&) = 0;
|
||||
void remove_ghost (GhostRegion*);
|
||||
|
||||
uint32_t get_fill_color ();
|
||||
|
||||
virtual void entered () {}
|
||||
virtual void exited () {}
|
||||
|
||||
static sigc::signal<void,RegionView*> RegionViewGoingAway;
|
||||
sigc::signal<void> GoingAway;
|
||||
|
||||
protected:
|
||||
|
||||
/** Allows derived types to specify their visibility requirements
|
||||
* to the TimeAxisViewItem parent class
|
||||
*/
|
||||
RegionView (ArdourCanvas::Group *,
|
||||
TimeAxisView&,
|
||||
ARDOUR::Region&,
|
||||
double samples_per_unit,
|
||||
Gdk::Color& basic_color,
|
||||
TimeAxisViewItem::Visibility);
|
||||
|
||||
virtual void region_resized (ARDOUR::Change);
|
||||
void region_moved (void *);
|
||||
virtual void region_muted ();
|
||||
void region_locked ();
|
||||
void region_opacity ();
|
||||
void region_layered ();
|
||||
void region_renamed ();
|
||||
void region_sync_changed ();
|
||||
|
||||
static gint _lock_toggle (ArdourCanvas::Item*, GdkEvent*, void*);
|
||||
void lock_toggle ();
|
||||
|
||||
virtual void set_colors ();
|
||||
virtual void compute_colors (Gdk::Color&);
|
||||
virtual void set_frame_color ();
|
||||
virtual void reset_width_dependent_items (double pixel_width);
|
||||
|
||||
virtual void color_handler (ColorID, uint32_t) {}
|
||||
|
||||
ARDOUR::Region& _region;
|
||||
|
||||
ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position
|
||||
ArdourCanvas::Text* no_wave_msg;
|
||||
|
||||
RegionEditor* editor;
|
||||
|
||||
vector<ControlPoint *> control_points;
|
||||
double current_visible_sync_position;
|
||||
|
||||
bool valid; ///< see StreamView::redisplay_diskstream()
|
||||
double _pixel_width;
|
||||
double _height;
|
||||
bool in_destructor;
|
||||
|
||||
bool wait_for_data;
|
||||
sigc::connection data_ready_connection;
|
||||
|
||||
vector<GhostRegion*> ghosts;
|
||||
};
|
||||
|
||||
#endif /* __gtk_ardour_region_view_h__ */
|
||||
1559
gtk2_ardour/route_time_axis.cc
Normal file
1559
gtk2_ardour/route_time_axis.cc
Normal file
File diff suppressed because it is too large
Load Diff
256
gtk2_ardour/route_time_axis.h
Normal file
256
gtk2_ardour/route_time_axis.h
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
Copyright (C) 2006 Paul Davis
|
||||
|
||||
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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: audio_time_axis.h 664 2006-07-05 19:47:25Z drobilla $
|
||||
*/
|
||||
|
||||
#ifndef __ardour_route_time_axis_h__
|
||||
#define __ardour_route_time_axis_h__
|
||||
|
||||
#include <gtkmm/table.h>
|
||||
#include <gtkmm/button.h>
|
||||
#include <gtkmm/box.h>
|
||||
#include <gtkmm/menu.h>
|
||||
#include <gtkmm/menuitem.h>
|
||||
#include <gtkmm/radiomenuitem.h>
|
||||
#include <gtkmm/checkmenuitem.h>
|
||||
|
||||
#include <gtkmm2ext/selector.h>
|
||||
#include <list>
|
||||
|
||||
#include <ardour/types.h>
|
||||
|
||||
#include "ardour_dialog.h"
|
||||
#include "route_ui.h"
|
||||
#include "enums.h"
|
||||
#include "time_axis_view.h"
|
||||
#include "canvas.h"
|
||||
#include "color.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
class Session;
|
||||
class Region;
|
||||
class Diskstream;
|
||||
class RouteGroup;
|
||||
class Redirect;
|
||||
class Insert;
|
||||
class Location;
|
||||
class Playlist;
|
||||
}
|
||||
|
||||
class PublicEditor;
|
||||
class RegionView;
|
||||
class StreamView;
|
||||
class Selection;
|
||||
class RegionSelection;
|
||||
class Selectable;
|
||||
class AutomationTimeAxisView;
|
||||
class AutomationLine;
|
||||
class RedirectAutomationLine;
|
||||
class TimeSelection;
|
||||
|
||||
class RouteTimeAxisView : public RouteUI, public TimeAxisView
|
||||
{
|
||||
public:
|
||||
RouteTimeAxisView (PublicEditor&, ARDOUR::Session&, boost::shared_ptr<ARDOUR::Route>, ArdourCanvas::Canvas& canvas);
|
||||
virtual ~RouteTimeAxisView ();
|
||||
|
||||
void show_selection (TimeSelection&);
|
||||
|
||||
void set_samples_per_unit (double);
|
||||
void set_height (TimeAxisView::TrackHeight);
|
||||
void show_timestretch (jack_nframes_t start, jack_nframes_t end);
|
||||
void hide_timestretch ();
|
||||
void selection_click (GdkEventButton*);
|
||||
void set_selected_points (PointSelection&);
|
||||
void set_selected_regionviews (RegionSelection&);
|
||||
void get_selectables (jack_nframes_t start, jack_nframes_t end, double top, double bot, list<Selectable *>&);
|
||||
void get_inverted_selectables (Selection&, list<Selectable*>&);
|
||||
|
||||
ARDOUR::Region* find_next_region (jack_nframes_t pos, ARDOUR::RegionPoint, int32_t dir);
|
||||
|
||||
/* Editing operations */
|
||||
bool cut_copy_clear (Selection&, Editing::CutCopyOp);
|
||||
bool paste (jack_nframes_t, float times, Selection&, size_t nth);
|
||||
|
||||
list<TimeAxisView*> get_child_list();
|
||||
|
||||
/* The editor calls these when mapping an operation across multiple tracks */
|
||||
void use_new_playlist (bool prompt);
|
||||
void use_copy_playlist (bool prompt);
|
||||
void clear_playlist ();
|
||||
|
||||
void build_playlist_menu (Gtk::Menu *);
|
||||
|
||||
string name() const;
|
||||
StreamView* view() const { return _view; }
|
||||
ARDOUR::RouteGroup* edit_group() const;
|
||||
ARDOUR::Playlist* playlist() const;
|
||||
|
||||
protected:
|
||||
friend class StreamView;
|
||||
|
||||
struct RedirectAutomationNode {
|
||||
uint32_t what;
|
||||
Gtk::CheckMenuItem* menu_item;
|
||||
AutomationTimeAxisView* view;
|
||||
RouteTimeAxisView& parent;
|
||||
|
||||
RedirectAutomationNode (uint32_t w, Gtk::CheckMenuItem* mitem, RouteTimeAxisView& p)
|
||||
: what (w), menu_item (mitem), view (0), parent (p) {}
|
||||
|
||||
~RedirectAutomationNode ();
|
||||
};
|
||||
|
||||
struct RedirectAutomationInfo {
|
||||
boost::shared_ptr<ARDOUR::Redirect> redirect;
|
||||
bool valid;
|
||||
Gtk::Menu* menu;
|
||||
vector<RedirectAutomationNode*> lines;
|
||||
|
||||
RedirectAutomationInfo (boost::shared_ptr<ARDOUR::Redirect> r)
|
||||
: redirect (r), valid (true), menu (0) {}
|
||||
|
||||
~RedirectAutomationInfo ();
|
||||
};
|
||||
|
||||
|
||||
void diskstream_changed ();
|
||||
void update_diskstream_display ();
|
||||
|
||||
gint edit_click (GdkEventButton *);
|
||||
|
||||
void build_redirect_window ();
|
||||
void redirect_click ();
|
||||
void redirect_add ();
|
||||
void redirect_remove ();
|
||||
void redirect_edit ();
|
||||
void redirect_relist ();
|
||||
void redirect_row_selected (gint row, gint col, GdkEvent *ev);
|
||||
void add_to_redirect_display (ARDOUR::Redirect *);
|
||||
void redirects_changed (void *);
|
||||
|
||||
void add_redirect_to_subplugin_menu (boost::shared_ptr<ARDOUR::Redirect>);
|
||||
void remove_ran (RedirectAutomationNode* ran);
|
||||
|
||||
void redirect_menu_item_toggled (RouteTimeAxisView::RedirectAutomationInfo*,
|
||||
RouteTimeAxisView::RedirectAutomationNode*);
|
||||
|
||||
void redirect_automation_track_hidden (RedirectAutomationNode*,
|
||||
boost::shared_ptr<ARDOUR::Redirect>);
|
||||
|
||||
RedirectAutomationNode*
|
||||
find_redirect_automation_node (boost::shared_ptr<ARDOUR::Redirect> r, uint32_t);
|
||||
|
||||
RedirectAutomationLine*
|
||||
find_redirect_automation_curve (boost::shared_ptr<ARDOUR::Redirect> r, uint32_t);
|
||||
|
||||
void add_redirect_automation_curve (boost::shared_ptr<ARDOUR::Redirect> r, uint32_t);
|
||||
void add_existing_redirect_automation_curves (boost::shared_ptr<ARDOUR::Redirect>);
|
||||
|
||||
void reset_redirect_automation_curves ();
|
||||
|
||||
void update_automation_view (ARDOUR::AutomationType);
|
||||
|
||||
void take_name_changed (void *);
|
||||
void route_name_changed (void *);
|
||||
void name_entry_changed ();
|
||||
|
||||
void on_area_realize ();
|
||||
|
||||
virtual void label_view ();
|
||||
|
||||
void add_edit_group_menu_item (ARDOUR::RouteGroup *, Gtk::RadioMenuItem::Group*);
|
||||
void set_edit_group_from_menu (ARDOUR::RouteGroup *);
|
||||
|
||||
void reset_samples_per_unit ();
|
||||
|
||||
void select_track_color();
|
||||
|
||||
virtual void build_automation_action_menu ();
|
||||
virtual void append_extra_display_menu_items () {}
|
||||
void build_display_menu ();
|
||||
|
||||
void align_style_changed ();
|
||||
void set_align_style (ARDOUR::AlignStyle);
|
||||
|
||||
virtual void set_playlist (ARDOUR::Playlist *);
|
||||
void playlist_click ();
|
||||
void show_playlist_selector ();
|
||||
void playlist_changed ();
|
||||
void playlist_state_changed (ARDOUR::Change);
|
||||
void playlist_modified ();
|
||||
|
||||
void add_playlist_to_playlist_menu (ARDOUR::Playlist*);
|
||||
void rename_current_playlist ();
|
||||
|
||||
void automation_click ();
|
||||
virtual void show_all_automation ();
|
||||
virtual void show_existing_automation ();
|
||||
virtual void hide_all_automation ();
|
||||
|
||||
void timestretch (jack_nframes_t start, jack_nframes_t end);
|
||||
|
||||
void visual_click ();
|
||||
void hide_click ();
|
||||
gint when_displayed (GdkEventAny*);
|
||||
|
||||
void speed_changed ();
|
||||
|
||||
void map_frozen ();
|
||||
|
||||
void color_handler (ColorID, uint32_t);
|
||||
bool select_me (GdkEventButton*);
|
||||
|
||||
void region_view_added (RegionView*);
|
||||
void add_ghost_to_redirect (RegionView*, AutomationTimeAxisView*);
|
||||
|
||||
|
||||
StreamView* _view;
|
||||
ArdourCanvas::Canvas& parent_canvas;
|
||||
bool no_redraw;
|
||||
|
||||
Gtk::HBox other_button_hbox;
|
||||
Gtk::Table button_table;
|
||||
Gtk::Button redirect_button;
|
||||
Gtk::Button edit_group_button;
|
||||
Gtk::Button playlist_button;
|
||||
Gtk::Button size_button;
|
||||
Gtk::Button automation_button;
|
||||
Gtk::Button hide_button;
|
||||
Gtk::Button visual_button;
|
||||
|
||||
Gtk::Menu subplugin_menu;
|
||||
Gtk::Menu* automation_action_menu;
|
||||
Gtk::Menu edit_group_menu;
|
||||
Gtk::RadioMenuItem* align_existing_item;
|
||||
Gtk::RadioMenuItem* align_capture_item;
|
||||
Gtk::Menu* playlist_menu;
|
||||
Gtk::Menu* playlist_action_menu;
|
||||
Gtk::MenuItem* playlist_item;
|
||||
|
||||
ArdourCanvas::SimpleRect* timestretch_rect;
|
||||
|
||||
list<RedirectAutomationInfo*> redirect_automation;
|
||||
vector<RedirectAutomationLine*> redirect_automation_curves;
|
||||
|
||||
sigc::connection modified_connection;
|
||||
sigc::connection state_changed_connection;
|
||||
};
|
||||
|
||||
#endif /* __ardour_route_time_axis_h__ */
|
||||
|
||||
@@ -70,14 +70,14 @@ RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session& sess, co
|
||||
mute_button = manage (new BindableToggleButton (_route->mute_control(), m_name ));
|
||||
solo_button = manage (new BindableToggleButton (_route->solo_control(), s_name ));
|
||||
|
||||
if (is_audio_track()) {
|
||||
boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack>(_route);
|
||||
if (is_track()) {
|
||||
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
|
||||
|
||||
at->disk_stream().record_enable_changed.connect (mem_fun (*this, &RouteUI::route_rec_enable_changed));
|
||||
t->diskstream().RecordEnableChanged.connect (mem_fun (*this, &RouteUI::route_rec_enable_changed));
|
||||
|
||||
_session.RecordStateChanged.connect (mem_fun (*this, &RouteUI::session_rec_enable_changed));
|
||||
|
||||
rec_enable_button = manage (new BindableToggleButton (at->rec_enable_control(), r_name ));
|
||||
rec_enable_button = manage (new BindableToggleButton (t->rec_enable_control(), r_name ));
|
||||
|
||||
rec_enable_button->unset_flags (Gtk::CAN_FOCUS);
|
||||
|
||||
@@ -268,7 +268,7 @@ RouteUI::solo_release(GdkEventButton* ev)
|
||||
gint
|
||||
RouteUI::rec_enable_press(GdkEventButton* ev)
|
||||
{
|
||||
if (!ignore_toggle && is_audio_track() && rec_enable_button) {
|
||||
if (!ignore_toggle && is_track() && rec_enable_button) {
|
||||
|
||||
if (ev->button == 2 && Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
|
||||
// do nothing on midi bind event
|
||||
@@ -351,7 +351,7 @@ RouteUI::update_mute_display ()
|
||||
}
|
||||
|
||||
void
|
||||
RouteUI::route_rec_enable_changed (void *src)
|
||||
RouteUI::route_rec_enable_changed ()
|
||||
{
|
||||
Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &RouteUI::update_rec_display));
|
||||
}
|
||||
@@ -694,7 +694,7 @@ RouteUI::remove_this_route ()
|
||||
vector<string> choices;
|
||||
string prompt;
|
||||
|
||||
if (is_audio_track()) {
|
||||
if (is_track()) {
|
||||
prompt = string_compose (_("Do you really want to remove track \"%1\" ?\n\nYou may also lose the playlist used by this track.\n(cannot be undone)"), _route->name());
|
||||
} else {
|
||||
prompt = string_compose (_("Do you really want to remove bus \"%1\" ?\n(cannot be undone)"), _route->name());
|
||||
@@ -869,30 +869,42 @@ RouteUI::disconnect_output ()
|
||||
_route->disconnect_outputs (this);
|
||||
}
|
||||
|
||||
bool
|
||||
RouteUI::is_track () const
|
||||
{
|
||||
return dynamic_cast<Track*>(_route.get()) != 0;
|
||||
}
|
||||
|
||||
Track*
|
||||
RouteUI::track() const
|
||||
{
|
||||
return dynamic_cast<Track*>(_route.get());
|
||||
}
|
||||
|
||||
bool
|
||||
RouteUI::is_audio_track () const
|
||||
{
|
||||
return dynamic_cast<AudioTrack*>(_route.get()) != 0;
|
||||
}
|
||||
|
||||
AudioDiskstream*
|
||||
RouteUI::get_diskstream () const
|
||||
{
|
||||
boost::shared_ptr<AudioTrack> at;
|
||||
|
||||
if ((at = boost::dynamic_pointer_cast<AudioTrack>(_route)) != 0) {
|
||||
return &at->disk_stream();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
AudioTrack*
|
||||
RouteUI::audio_track() const
|
||||
{
|
||||
return dynamic_cast<AudioTrack*>(_route.get());
|
||||
}
|
||||
|
||||
Diskstream*
|
||||
RouteUI::get_diskstream () const
|
||||
{
|
||||
boost::shared_ptr<Track> t;
|
||||
|
||||
if ((t = boost::dynamic_pointer_cast<Track>(_route)) != 0) {
|
||||
return &t->diskstream();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
RouteUI::name() const
|
||||
{
|
||||
@@ -917,3 +929,4 @@ RouteUI::map_frozen ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <pbd/xml++.h>
|
||||
#include <ardour/ardour.h>
|
||||
#include <ardour/route.h>
|
||||
#include <ardour/track.h>
|
||||
|
||||
#include "axis_view.h"
|
||||
|
||||
@@ -47,11 +48,16 @@ class RouteUI : public virtual AxisView
|
||||
RouteUI(boost::shared_ptr<ARDOUR::Route>, ARDOUR::Session&, const char*, const char*, const char*);
|
||||
virtual ~RouteUI();
|
||||
|
||||
bool is_track() const;
|
||||
bool is_audio_track() const;
|
||||
ARDOUR::AudioDiskstream* get_diskstream() const;
|
||||
|
||||
boost::shared_ptr<ARDOUR::Route> route() const { return _route; }
|
||||
|
||||
// FIXME: make these return shared_ptr
|
||||
ARDOUR::Track* track() const;
|
||||
ARDOUR::AudioTrack* audio_track() const;
|
||||
|
||||
ARDOUR::Diskstream* get_diskstream() const;
|
||||
|
||||
string name() const;
|
||||
|
||||
@@ -89,7 +95,8 @@ class RouteUI : public virtual AxisView
|
||||
|
||||
void solo_changed(void*);
|
||||
void mute_changed(void*);
|
||||
void route_rec_enable_changed(void*);
|
||||
virtual void redirects_changed (void *) {}
|
||||
void route_rec_enable_changed();
|
||||
void session_rec_enable_changed();
|
||||
|
||||
void build_solo_menu (void);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <ardour/playlist.h>
|
||||
|
||||
#include "regionview.h"
|
||||
#include "region_view.h"
|
||||
#include "selection.h"
|
||||
#include "selection_templates.h"
|
||||
#include "time_axis_view.h"
|
||||
@@ -46,7 +46,7 @@ Selection&
|
||||
Selection::operator= (const Selection& other)
|
||||
{
|
||||
if (&other != this) {
|
||||
audio_regions = other.audio_regions;
|
||||
regions = other.regions;
|
||||
tracks = other.tracks;
|
||||
time = other.time;
|
||||
lines = other.lines;
|
||||
@@ -57,7 +57,7 @@ Selection::operator= (const Selection& other)
|
||||
bool
|
||||
operator== (const Selection& a, const Selection& b)
|
||||
{
|
||||
return a.audio_regions == b.audio_regions &&
|
||||
return a.regions == b.regions &&
|
||||
a.tracks == b.tracks &&
|
||||
a.time.track == b.time.track &&
|
||||
a.time.group == b.time.group &&
|
||||
@@ -71,7 +71,7 @@ void
|
||||
Selection::clear ()
|
||||
{
|
||||
clear_tracks ();
|
||||
clear_audio_regions ();
|
||||
clear_regions ();
|
||||
clear_points ();
|
||||
clear_lines();
|
||||
clear_time ();
|
||||
@@ -83,8 +83,8 @@ void
|
||||
Selection::dump_region_layers()
|
||||
{
|
||||
cerr << "region selection layer dump" << endl;
|
||||
for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
|
||||
cerr << "layer: " << (int)(*i)->region.layer() << endl;
|
||||
for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
|
||||
cerr << "layer: " << (int)(*i)->region().layer() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,10 +99,10 @@ Selection::clear_redirects ()
|
||||
}
|
||||
|
||||
void
|
||||
Selection::clear_audio_regions ()
|
||||
Selection::clear_regions ()
|
||||
{
|
||||
if (!audio_regions.empty()) {
|
||||
audio_regions.clear_all ();
|
||||
if (!regions.empty()) {
|
||||
regions.clear_all ();
|
||||
RegionsChanged();
|
||||
}
|
||||
}
|
||||
@@ -196,29 +196,29 @@ Selection::toggle (TimeAxisView* track)
|
||||
}
|
||||
|
||||
void
|
||||
Selection::toggle (AudioRegionView* r)
|
||||
Selection::toggle (RegionView* r)
|
||||
{
|
||||
AudioRegionSelection::iterator i;
|
||||
RegionSelection::iterator i;
|
||||
|
||||
if ((i = find (audio_regions.begin(), audio_regions.end(), r)) == audio_regions.end()) {
|
||||
audio_regions.add (r);
|
||||
if ((i = find (regions.begin(), regions.end(), r)) == regions.end()) {
|
||||
regions.add (r);
|
||||
} else {
|
||||
audio_regions.erase (i);
|
||||
regions.erase (i);
|
||||
}
|
||||
|
||||
RegionsChanged ();
|
||||
}
|
||||
|
||||
void
|
||||
Selection::toggle (vector<AudioRegionView*>& r)
|
||||
Selection::toggle (vector<RegionView*>& r)
|
||||
{
|
||||
AudioRegionSelection::iterator i;
|
||||
RegionSelection::iterator i;
|
||||
|
||||
for (vector<AudioRegionView*>::iterator x = r.begin(); x != r.end(); ++x) {
|
||||
if ((i = find (audio_regions.begin(), audio_regions.end(), (*x))) == audio_regions.end()) {
|
||||
audio_regions.add ((*x));
|
||||
for (vector<RegionView*>::iterator x = r.begin(); x != r.end(); ++x) {
|
||||
if ((i = find (regions.begin(), regions.end(), (*x))) == regions.end()) {
|
||||
regions.add ((*x));
|
||||
} else {
|
||||
audio_regions.erase (i);
|
||||
regions.erase (i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,22 +310,22 @@ Selection::add (TimeAxisView* track)
|
||||
}
|
||||
|
||||
void
|
||||
Selection::add (AudioRegionView* r)
|
||||
Selection::add (RegionView* r)
|
||||
{
|
||||
if (find (audio_regions.begin(), audio_regions.end(), r) == audio_regions.end()) {
|
||||
audio_regions.add (r);
|
||||
if (find (regions.begin(), regions.end(), r) == regions.end()) {
|
||||
regions.add (r);
|
||||
RegionsChanged ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Selection::add (vector<AudioRegionView*>& v)
|
||||
Selection::add (vector<RegionView*>& v)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
for (vector<AudioRegionView*>::iterator i = v.begin(); i != v.end(); ++i) {
|
||||
if (find (audio_regions.begin(), audio_regions.end(), (*i)) == audio_regions.end()) {
|
||||
audio_regions.add ((*i));
|
||||
for (vector<RegionView*>::iterator i = v.begin(); i != v.end(); ++i) {
|
||||
if (find (regions.begin(), regions.end(), (*i)) == regions.end()) {
|
||||
regions.add ((*i));
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
@@ -451,9 +451,9 @@ Selection::remove (const list<Playlist*>& pllist)
|
||||
}
|
||||
|
||||
void
|
||||
Selection::remove (AudioRegionView* r)
|
||||
Selection::remove (RegionView* r)
|
||||
{
|
||||
audio_regions.remove (r);
|
||||
regions.remove (r);
|
||||
RegionsChanged ();
|
||||
}
|
||||
|
||||
@@ -526,17 +526,16 @@ Selection::set (const list<Playlist*>& pllist)
|
||||
}
|
||||
|
||||
void
|
||||
Selection::set (AudioRegionView* r)
|
||||
Selection::set (RegionView* r)
|
||||
{
|
||||
clear_audio_regions ();
|
||||
clear_regions ();
|
||||
add (r);
|
||||
}
|
||||
|
||||
void
|
||||
Selection::set (vector<AudioRegionView*>& v)
|
||||
Selection::set (vector<RegionView*>& v)
|
||||
{
|
||||
|
||||
clear_audio_regions ();
|
||||
clear_regions ();
|
||||
// make sure to deselect any automation selections
|
||||
clear_points();
|
||||
add (v);
|
||||
@@ -590,15 +589,15 @@ Selection::selected (TimeAxisView* tv)
|
||||
}
|
||||
|
||||
bool
|
||||
Selection::selected (AudioRegionView* arv)
|
||||
Selection::selected (RegionView* rv)
|
||||
{
|
||||
return find (audio_regions.begin(), audio_regions.end(), arv) != audio_regions.end();
|
||||
return find (regions.begin(), regions.end(), rv) != regions.end();
|
||||
}
|
||||
|
||||
bool
|
||||
Selection::empty ()
|
||||
{
|
||||
return audio_regions.empty () &&
|
||||
return regions.empty () &&
|
||||
tracks.empty () &&
|
||||
points.empty () &&
|
||||
playlists.empty () &&
|
||||
@@ -612,7 +611,7 @@ Selection::empty ()
|
||||
void
|
||||
Selection::set (list<Selectable*>& selectables)
|
||||
{
|
||||
clear_audio_regions();
|
||||
clear_regions();
|
||||
clear_points ();
|
||||
add (selectables);
|
||||
}
|
||||
@@ -620,14 +619,14 @@ Selection::set (list<Selectable*>& selectables)
|
||||
void
|
||||
Selection::add (list<Selectable*>& selectables)
|
||||
{
|
||||
AudioRegionView* arv;
|
||||
RegionView* rv;
|
||||
AutomationSelectable* as;
|
||||
vector<AudioRegionView*> arvs;
|
||||
vector<RegionView*> rvs;
|
||||
vector<AutomationSelectable*> autos;
|
||||
|
||||
for (std::list<Selectable*>::iterator i = selectables.begin(); i != selectables.end(); ++i) {
|
||||
if ((arv = dynamic_cast<AudioRegionView*> (*i)) != 0) {
|
||||
arvs.push_back (arv);
|
||||
if ((rv = dynamic_cast<RegionView*> (*i)) != 0) {
|
||||
rvs.push_back (rv);
|
||||
} else if ((as = dynamic_cast<AutomationSelectable*> (*i)) != 0) {
|
||||
autos.push_back (as);
|
||||
} else {
|
||||
@@ -638,8 +637,8 @@ Selection::add (list<Selectable*>& selectables)
|
||||
}
|
||||
}
|
||||
|
||||
if (!arvs.empty()) {
|
||||
add (arvs);
|
||||
if (!rvs.empty()) {
|
||||
add (rvs);
|
||||
}
|
||||
|
||||
if (!autos.empty()) {
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "point_selection.h"
|
||||
|
||||
class TimeAxisView;
|
||||
class AudioRegionView;
|
||||
class RegionView;
|
||||
class Selectable;
|
||||
|
||||
namespace ARDOUR {
|
||||
@@ -61,7 +61,7 @@ class Selection : public sigc::trackable
|
||||
};
|
||||
|
||||
TrackSelection tracks;
|
||||
AudioRegionSelection audio_regions;
|
||||
RegionSelection regions;
|
||||
TimeSelection time;
|
||||
AutomationSelection lines;
|
||||
PlaylistSelection playlists;
|
||||
@@ -89,15 +89,15 @@ class Selection : public sigc::trackable
|
||||
void dump_region_layers();
|
||||
|
||||
bool selected (TimeAxisView*);
|
||||
bool selected (AudioRegionView*);
|
||||
bool selected (RegionView*);
|
||||
|
||||
void set (list<Selectable*>&);
|
||||
void add (list<Selectable*>&);
|
||||
|
||||
void set (TimeAxisView*);
|
||||
void set (const list<TimeAxisView*>&);
|
||||
void set (AudioRegionView*);
|
||||
void set (std::vector<AudioRegionView*>&);
|
||||
void set (RegionView*);
|
||||
void set (std::vector<RegionView*>&);
|
||||
long set (TimeAxisView*, jack_nframes_t, jack_nframes_t);
|
||||
void set (ARDOUR::AutomationList*);
|
||||
void set (ARDOUR::Playlist*);
|
||||
@@ -107,8 +107,8 @@ class Selection : public sigc::trackable
|
||||
|
||||
void toggle (TimeAxisView*);
|
||||
void toggle (const list<TimeAxisView*>&);
|
||||
void toggle (AudioRegionView*);
|
||||
void toggle (std::vector<AudioRegionView*>&);
|
||||
void toggle (RegionView*);
|
||||
void toggle (std::vector<RegionView*>&);
|
||||
long toggle (jack_nframes_t, jack_nframes_t);
|
||||
void toggle (ARDOUR::AutomationList*);
|
||||
void toggle (ARDOUR::Playlist*);
|
||||
@@ -117,8 +117,8 @@ class Selection : public sigc::trackable
|
||||
|
||||
void add (TimeAxisView*);
|
||||
void add (const list<TimeAxisView*>&);
|
||||
void add (AudioRegionView*);
|
||||
void add (std::vector<AudioRegionView*>&);
|
||||
void add (RegionView*);
|
||||
void add (std::vector<RegionView*>&);
|
||||
long add (jack_nframes_t, jack_nframes_t);
|
||||
void add (ARDOUR::AutomationList*);
|
||||
void add (ARDOUR::Playlist*);
|
||||
@@ -127,7 +127,7 @@ class Selection : public sigc::trackable
|
||||
|
||||
void remove (TimeAxisView*);
|
||||
void remove (const list<TimeAxisView*>&);
|
||||
void remove (AudioRegionView*);
|
||||
void remove (RegionView*);
|
||||
void remove (uint32_t selection_id);
|
||||
void remove (jack_nframes_t, jack_nframes_t);
|
||||
void remove (ARDOUR::AutomationList*);
|
||||
@@ -137,7 +137,7 @@ class Selection : public sigc::trackable
|
||||
|
||||
void replace (uint32_t time_index, jack_nframes_t start, jack_nframes_t end);
|
||||
|
||||
void clear_audio_regions();
|
||||
void clear_regions();
|
||||
void clear_tracks ();
|
||||
void clear_time();
|
||||
void clear_lines ();
|
||||
@@ -145,10 +145,8 @@ class Selection : public sigc::trackable
|
||||
void clear_redirects ();
|
||||
void clear_points ();
|
||||
|
||||
void foreach_audio_region (void (ARDOUR::AudioRegion::*method)(void));
|
||||
void foreach_audio_region (void (ARDOUR::Region::*method)(void));
|
||||
template<class A> void foreach_audio_region (void (ARDOUR::AudioRegion::*method)(A), A arg);
|
||||
template<class A> void foreach_audio_region (void (ARDOUR::Region::*method)(A), A arg);
|
||||
void foreach_region (void (ARDOUR::Region::*method)(void));
|
||||
template<class A> void foreach_region (void (ARDOUR::Region::*method)(A), A arg);
|
||||
|
||||
private:
|
||||
uint32_t next_time_id;
|
||||
|
||||
@@ -27,35 +27,21 @@
|
||||
*/
|
||||
|
||||
#include <ardour/region.h>
|
||||
#include <ardour/audioregion.h>
|
||||
|
||||
#include "selection.h"
|
||||
#include "region_view.h"
|
||||
|
||||
inline void
|
||||
Selection::foreach_audio_region (void (ARDOUR::AudioRegion::*method)(void)) {
|
||||
for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
|
||||
((*i)->region.*(method))();
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Selection::foreach_audio_region (void (ARDOUR::Region::*method)(void)) {
|
||||
for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
|
||||
((*i)->region.*(method))();
|
||||
Selection::foreach_region (void (ARDOUR::Region::*method)(void)) {
|
||||
for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
|
||||
((*i)->region().*(method))();
|
||||
}
|
||||
}
|
||||
|
||||
template<class A> inline void
|
||||
Selection::foreach_audio_region (void (ARDOUR::AudioRegion::*method)(A), A arg) {
|
||||
for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
|
||||
((*i)->region.*(method))(arg);
|
||||
}
|
||||
}
|
||||
|
||||
template<class A> inline void
|
||||
Selection::foreach_audio_region (void (ARDOUR::Region::*method)(A), A arg) {
|
||||
for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
|
||||
((*i)->region.*(method))(arg);
|
||||
Selection::foreach_region (void (ARDOUR::Region::*method)(A), A arg) {
|
||||
for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
|
||||
((*i)->region().*(method))(arg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,14 +50,14 @@ Selection::foreach_audio_region (void (ARDOUR::Region::*method)(A), A arg) {
|
||||
template<class A> inline void
|
||||
Selection::foreach_route (void (ARDOUR::Route::*method)(A), A arg) {
|
||||
for (list<ARDOUR::Route*>::iterator i = routes.begin(); i != routes.end(); ++i) {
|
||||
((*i)->region.*(method))(arg);
|
||||
((*i)->region().*(method))(arg);
|
||||
}
|
||||
}
|
||||
|
||||
template<class A1, class A2> inline void
|
||||
Selection::foreach_route (void (ARDOUR::Route::*method)(A1,A2), A1 arg1, A2 arg2) {
|
||||
for (list<ARDOUR::Route*>::iterator i = routes.begin(); i != routes.end(); ++i) {
|
||||
((*i)->region.*(method))(arg1, arg2);
|
||||
((*i)->region().*(method))(arg1, arg2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,42 @@
|
||||
/*
|
||||
Copyright (C) 2001, 2006 Paul Davis
|
||||
|
||||
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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <gtkmm.h>
|
||||
|
||||
#include <gtkmm2ext/gtk_ui.h>
|
||||
|
||||
#include <ardour/audioplaylist.h>
|
||||
#include <ardour/audioregion.h>
|
||||
#include <ardour/audiosource.h>
|
||||
#include <ardour/audio_diskstream.h>
|
||||
#include <ardour/audio_track.h>
|
||||
#include <ardour/playlist_templates.h>
|
||||
#include <ardour/playlist.h>
|
||||
#include <ardour/region.h>
|
||||
#include <ardour/source.h>
|
||||
#include <ardour/diskstream.h>
|
||||
#include <ardour/track.h>
|
||||
|
||||
#include "streamview.h"
|
||||
#include "regionview.h"
|
||||
#include "taperegionview.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "region_view.h"
|
||||
#include "route_time_axis.h"
|
||||
#include "canvas-waveview.h"
|
||||
#include "canvas-simplerect.h"
|
||||
#include "region_selection.h"
|
||||
#include "selection.h"
|
||||
#include "public_editor.h"
|
||||
#include "ardour_ui.h"
|
||||
#include "crossfade_view.h"
|
||||
#include "rgb_macros.h"
|
||||
#include "gui_thread.h"
|
||||
#include "utils.h"
|
||||
@@ -32,21 +46,10 @@ using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
using namespace Editing;
|
||||
|
||||
StreamView::StreamView (AudioTimeAxisView& tv)
|
||||
StreamView::StreamView (RouteTimeAxisView& tv)
|
||||
: _trackview (tv)
|
||||
{
|
||||
region_color = _trackview.color();
|
||||
crossfades_visible = true;
|
||||
|
||||
if (tv.is_audio_track()) {
|
||||
/* TRACK */
|
||||
//stream_base_color = RGBA_TO_UINT (222,223,218,255);
|
||||
stream_base_color = color_map[cAudioTrackBase];
|
||||
} else {
|
||||
/* BUS */
|
||||
//stream_base_color = RGBA_TO_UINT (230,226,238,255);
|
||||
stream_base_color = color_map[cAudioBusBase];
|
||||
}
|
||||
|
||||
/* set_position() will position the group */
|
||||
|
||||
@@ -57,26 +60,23 @@ StreamView::StreamView (AudioTimeAxisView& tv)
|
||||
canvas_rect->property_y1() = 0.0;
|
||||
canvas_rect->property_x2() = 1000000.0;
|
||||
canvas_rect->property_y2() = (double) tv.height;
|
||||
canvas_rect->property_outline_color_rgba() = color_map[cAudioTrackOutline];
|
||||
canvas_rect->property_outline_what() = (guint32) (0x1|0x2|0x8); // outline ends and bottom
|
||||
canvas_rect->property_fill_color_rgba() = stream_base_color;
|
||||
|
||||
canvas_rect->signal_event().connect (bind (mem_fun (_trackview.editor, &PublicEditor::canvas_stream_view_event), canvas_rect, &_trackview));
|
||||
|
||||
_samples_per_unit = _trackview.editor.get_current_zoom();
|
||||
_amplitude_above_axis = 1.0;
|
||||
|
||||
if (_trackview.is_audio_track()) {
|
||||
_trackview.audio_track()->diskstream_changed.connect (mem_fun (*this, &StreamView::diskstream_changed));
|
||||
if (_trackview.is_track()) {
|
||||
_trackview.track()->DiskstreamChanged.connect (mem_fun (*this, &StreamView::diskstream_changed));
|
||||
_trackview.session().TransportStateChange.connect (mem_fun (*this, &StreamView::transport_changed));
|
||||
_trackview.get_diskstream()->record_enable_changed.connect (mem_fun (*this, &StreamView::rec_enable_changed));
|
||||
_trackview.get_diskstream()->RecordEnableChanged.connect (mem_fun (*this, &StreamView::rec_enable_changed));
|
||||
_trackview.session().RecordStateChanged.connect (mem_fun (*this, &StreamView::sess_rec_enable_changed));
|
||||
}
|
||||
|
||||
rec_updating = false;
|
||||
rec_active = false;
|
||||
use_rec_regions = tv.editor.show_waveforms_recording ();
|
||||
last_rec_peak_frame = 0;
|
||||
|
||||
ColorChanged.connect (mem_fun (*this, &StreamView::color_handler));
|
||||
}
|
||||
@@ -90,7 +90,7 @@ StreamView::~StreamView ()
|
||||
void
|
||||
StreamView::attach ()
|
||||
{
|
||||
if (_trackview.is_audio_track()) {
|
||||
if (_trackview.is_track()) {
|
||||
display_diskstream (_trackview.get_diskstream());
|
||||
}
|
||||
}
|
||||
@@ -115,13 +115,13 @@ StreamView::set_height (gdouble h)
|
||||
|
||||
canvas_rect->property_y2() = h;
|
||||
|
||||
for (AudioRegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
(*i)->set_height (h);
|
||||
}
|
||||
|
||||
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
/*for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
(*i)->set_height (h);
|
||||
}
|
||||
}*/
|
||||
|
||||
for (vector<RecBoxInfo>::iterator i = rec_rects.begin(); i != rec_rects.end(); ++i) {
|
||||
RecBoxInfo &recbox = (*i);
|
||||
@@ -134,7 +134,7 @@ StreamView::set_height (gdouble h)
|
||||
int
|
||||
StreamView::set_samples_per_unit (gdouble spp)
|
||||
{
|
||||
AudioRegionViewList::iterator i;
|
||||
RegionViewList::iterator i;
|
||||
|
||||
if (spp < 1.0) {
|
||||
return -1;
|
||||
@@ -146,10 +146,6 @@ StreamView::set_samples_per_unit (gdouble spp)
|
||||
(*i)->set_samples_per_unit (spp);
|
||||
}
|
||||
|
||||
for (CrossfadeViewList::iterator xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) {
|
||||
(*xi)->set_samples_per_unit (spp);
|
||||
}
|
||||
|
||||
for (vector<RecBoxInfo>::iterator xi = rec_rects.begin(); xi != rec_rects.end(); ++xi) {
|
||||
RecBoxInfo &recbox = (*xi);
|
||||
|
||||
@@ -163,113 +159,24 @@ StreamView::set_samples_per_unit (gdouble spp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
StreamView::set_amplitude_above_axis (gdouble app)
|
||||
|
||||
{
|
||||
AudioRegionViewList::iterator i;
|
||||
|
||||
if (app < 1.0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_amplitude_above_axis = app;
|
||||
|
||||
for (i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
(*i)->set_amplitude_above_axis (app);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::add_region_view (Region *r)
|
||||
{
|
||||
add_region_view_internal (r, true);
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::add_region_view_internal (Region *r, bool wait_for_waves)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::add_region_view), r));
|
||||
|
||||
AudioRegion* region = dynamic_cast<AudioRegion*> (r);
|
||||
|
||||
if (region == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
AudioRegionView *region_view;
|
||||
list<AudioRegionView *>::iterator i;
|
||||
|
||||
for (i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
if (&(*i)->region == region) {
|
||||
|
||||
/* great. we already have a AudioRegionView for this Region. use it again.
|
||||
*/
|
||||
|
||||
(*i)->set_valid (true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (_trackview.audio_track()->mode()) {
|
||||
case Normal:
|
||||
region_view = new AudioRegionView (canvas_group, _trackview, *region,
|
||||
_samples_per_unit, region_color);
|
||||
break;
|
||||
case Destructive:
|
||||
region_view = new TapeAudioRegionView (canvas_group, _trackview, *region,
|
||||
_samples_per_unit, region_color);
|
||||
break;
|
||||
}
|
||||
|
||||
region_view->init (_amplitude_above_axis, region_color, wait_for_waves);
|
||||
region_views.push_front (region_view);
|
||||
|
||||
/* follow global waveform setting */
|
||||
|
||||
region_view->set_waveform_visible(_trackview.editor.show_waveforms());
|
||||
|
||||
/* catch regionview going away */
|
||||
|
||||
region->GoingAway.connect (mem_fun (*this, &StreamView::remove_region_view));
|
||||
|
||||
AudioRegionViewAdded (region_view);
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::remove_region_view (Region *r)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::remove_region_view), r));
|
||||
|
||||
AudioRegion* ar = dynamic_cast<AudioRegion*> (r);
|
||||
|
||||
if (ar == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (list<AudioRegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
if (&((*i)->region) == ar) {
|
||||
for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
if (&((*i)->region()) == r) {
|
||||
delete *i;
|
||||
region_views.erase (i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end();) {
|
||||
list<CrossfadeView*>::iterator tmp;
|
||||
|
||||
tmp = i;
|
||||
++tmp;
|
||||
|
||||
if ((*i)->crossfade.involves (*ar)) {
|
||||
delete *i;
|
||||
crossfade_views.erase (i);
|
||||
}
|
||||
|
||||
i = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -282,14 +189,8 @@ StreamView::remove_rec_region (Region *r)
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
AudioRegion* ar = dynamic_cast<AudioRegion*> (r);
|
||||
|
||||
if (ar == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (list<AudioRegion *>::iterator i = rec_regions.begin(); i != rec_regions.end(); ++i) {
|
||||
if (*i == ar) {
|
||||
for (list<Region *>::iterator i = rec_regions.begin(); i != rec_regions.end(); ++i) {
|
||||
if (*i == r) {
|
||||
rec_regions.erase (i);
|
||||
break;
|
||||
}
|
||||
@@ -299,21 +200,15 @@ StreamView::remove_rec_region (Region *r)
|
||||
void
|
||||
StreamView::undisplay_diskstream ()
|
||||
{
|
||||
|
||||
for (AudioRegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
|
||||
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
|
||||
region_views.clear();
|
||||
crossfade_views.clear ();
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::display_diskstream (AudioDiskstream *ds)
|
||||
StreamView::display_diskstream (Diskstream *ds)
|
||||
{
|
||||
playlist_change_connection.disconnect();
|
||||
playlist_changed (ds);
|
||||
@@ -325,21 +220,13 @@ StreamView::playlist_modified ()
|
||||
{
|
||||
ENSURE_GUI_THREAD (mem_fun (*this, &StreamView::playlist_modified));
|
||||
|
||||
/* if the playlist is modified, make sure xfades are on top and all the regionviews are stacked
|
||||
correctly.
|
||||
*/
|
||||
|
||||
for (AudioRegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
region_layered (*i);
|
||||
}
|
||||
|
||||
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
(*i)->get_canvas_group()->raise_to_top();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::playlist_changed (AudioDiskstream *ds)
|
||||
StreamView::playlist_changed (Diskstream *ds)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::playlist_changed), ds));
|
||||
|
||||
@@ -362,69 +249,6 @@ StreamView::playlist_changed (AudioDiskstream *ds)
|
||||
playlist_connections.push_back (ds->playlist()->RegionRemoved.connect (mem_fun (*this, &StreamView::remove_region_view)));
|
||||
playlist_connections.push_back (ds->playlist()->StateChanged.connect (mem_fun (*this, &StreamView::playlist_state_changed)));
|
||||
playlist_connections.push_back (ds->playlist()->Modified.connect (mem_fun (*this, &StreamView::playlist_modified)));
|
||||
playlist_connections.push_back (ds->playlist()->NewCrossfade.connect (mem_fun (*this, &StreamView::add_crossfade)));
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::add_crossfade (Crossfade *crossfade)
|
||||
{
|
||||
AudioRegionView* lview = 0;
|
||||
AudioRegionView* rview = 0;
|
||||
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::add_crossfade), crossfade));
|
||||
|
||||
/* first see if we already have a CrossfadeView for this Crossfade */
|
||||
|
||||
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
if (&(*i)->crossfade == crossfade) {
|
||||
if (!crossfades_visible) {
|
||||
(*i)->hide();
|
||||
} else {
|
||||
(*i)->show ();
|
||||
}
|
||||
(*i)->set_valid (true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* create a new one */
|
||||
|
||||
for (list<AudioRegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
if (!lview && &((*i)->region) == &crossfade->out()) {
|
||||
lview = *i;
|
||||
}
|
||||
if (!rview && &((*i)->region) == &crossfade->in()) {
|
||||
rview = *i;
|
||||
}
|
||||
}
|
||||
|
||||
CrossfadeView *cv = new CrossfadeView (_trackview.canvas_display,
|
||||
_trackview,
|
||||
*crossfade,
|
||||
_samples_per_unit,
|
||||
region_color,
|
||||
*lview, *rview);
|
||||
|
||||
crossfade->Invalidated.connect (mem_fun (*this, &StreamView::remove_crossfade));
|
||||
crossfade_views.push_back (cv);
|
||||
|
||||
if (!crossfades_visible) {
|
||||
cv->hide ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::remove_crossfade (Crossfade *xfade)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::remove_crossfade), xfade));
|
||||
|
||||
for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
if (&(*i)->crossfade == xfade) {
|
||||
delete *i;
|
||||
crossfade_views.erase (i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -436,64 +260,12 @@ StreamView::playlist_state_changed (Change ignored)
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::redisplay_diskstream ()
|
||||
StreamView::diskstream_changed ()
|
||||
{
|
||||
list<AudioRegionView *>::iterator i, tmp;
|
||||
list<CrossfadeView*>::iterator xi, tmpx;
|
||||
Track *t;
|
||||
|
||||
|
||||
for (i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
(*i)->set_valid (false);
|
||||
}
|
||||
|
||||
for (xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) {
|
||||
(*xi)->set_valid (false);
|
||||
if ((*xi)->visible()) {
|
||||
(*xi)->show ();
|
||||
}
|
||||
}
|
||||
|
||||
if (_trackview.is_audio_track()) {
|
||||
_trackview.get_diskstream()->playlist()->foreach_region (this, &StreamView::add_region_view);
|
||||
_trackview.get_diskstream()->playlist()->foreach_crossfade (this, &StreamView::add_crossfade);
|
||||
}
|
||||
|
||||
for (i = region_views.begin(); i != region_views.end(); ) {
|
||||
tmp = i;
|
||||
tmp++;
|
||||
|
||||
if (!(*i)->is_valid()) {
|
||||
delete *i;
|
||||
region_views.erase (i);
|
||||
}
|
||||
|
||||
i = tmp;
|
||||
}
|
||||
|
||||
for (xi = crossfade_views.begin(); xi != crossfade_views.end();) {
|
||||
tmpx = xi;
|
||||
tmpx++;
|
||||
|
||||
if (!(*xi)->valid()) {
|
||||
delete *xi;
|
||||
crossfade_views.erase (xi);
|
||||
}
|
||||
|
||||
xi = tmpx;
|
||||
}
|
||||
|
||||
/* now fix layering */
|
||||
|
||||
playlist_modified ();
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::diskstream_changed (void *src_ignored)
|
||||
{
|
||||
AudioTrack *at;
|
||||
|
||||
if ((at = _trackview.audio_track()) != 0) {
|
||||
AudioDiskstream& ds = at->disk_stream();
|
||||
if ((t = _trackview.track()) != 0) {
|
||||
Diskstream& ds = t->diskstream();
|
||||
/* XXX grrr: when will SigC++ allow me to bind references? */
|
||||
Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun (*this, &StreamView::display_diskstream), &ds));
|
||||
} else {
|
||||
@@ -505,7 +277,7 @@ void
|
||||
StreamView::apply_color (Gdk::Color& color, ColorTarget target)
|
||||
|
||||
{
|
||||
list<AudioRegionView *>::iterator i;
|
||||
list<RegionView *>::iterator i;
|
||||
|
||||
switch (target) {
|
||||
case RegionColor:
|
||||
@@ -525,64 +297,7 @@ StreamView::apply_color (Gdk::Color& color, ColorTarget target)
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::set_show_waveforms (bool yn)
|
||||
{
|
||||
for (list<AudioRegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
(*i)->set_waveform_visible (yn);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::set_selected_regionviews (AudioRegionSelection& regions)
|
||||
{
|
||||
bool selected;
|
||||
|
||||
// cerr << _trackview.name() << " (selected = " << regions.size() << ")" << endl;
|
||||
for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
|
||||
selected = false;
|
||||
|
||||
for (AudioRegionSelection::iterator ii = regions.begin(); ii != regions.end(); ++ii) {
|
||||
if (*i == *ii) {
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
|
||||
// cerr << "\tregion " << (*i)->region.name() << " selected = " << selected << endl;
|
||||
(*i)->set_selected (selected);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::get_selectables (jack_nframes_t start, jack_nframes_t end, list<Selectable*>& results)
|
||||
{
|
||||
for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
if ((*i)->region.coverage(start, end) != OverlapNone) {
|
||||
results.push_back (*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::get_inverted_selectables (Selection& sel, list<Selectable*>& results)
|
||||
{
|
||||
for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
if (!sel.audio_regions.contains (*i)) {
|
||||
results.push_back (*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::set_waveform_shape (WaveformShape shape)
|
||||
{
|
||||
for (AudioRegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
(*i)->set_waveform_shape (shape);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::region_layered (AudioRegionView* rv)
|
||||
StreamView::region_layered (RegionView* rv)
|
||||
{
|
||||
rv->get_canvas_group()->lower_to_bottom();
|
||||
|
||||
@@ -590,11 +305,11 @@ StreamView::region_layered (AudioRegionView* rv)
|
||||
get events - the parent group does instead ...
|
||||
*/
|
||||
|
||||
rv->get_canvas_group()->raise (rv->region.layer() + 1);
|
||||
rv->get_canvas_group()->raise (rv->region().layer() + 1);
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::rec_enable_changed (void *src)
|
||||
StreamView::rec_enable_changed ()
|
||||
{
|
||||
Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &StreamView::setup_rec_box));
|
||||
}
|
||||
@@ -611,161 +326,6 @@ StreamView::transport_changed()
|
||||
Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &StreamView::setup_rec_box));
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::setup_rec_box ()
|
||||
{
|
||||
// cerr << _trackview.name() << " streamview SRB\n";
|
||||
|
||||
if (_trackview.session().transport_rolling()) {
|
||||
|
||||
// cerr << "\trolling\n";
|
||||
|
||||
if (!rec_active &&
|
||||
_trackview.session().record_status() == Session::Recording &&
|
||||
_trackview.get_diskstream()->record_enabled()) {
|
||||
|
||||
if (_trackview.audio_track()->mode() == Normal && use_rec_regions && rec_regions.size() == rec_rects.size()) {
|
||||
|
||||
/* add a new region, but don't bother if they set use_rec_regions mid-record */
|
||||
|
||||
AudioRegion::SourceList sources;
|
||||
|
||||
for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) {
|
||||
(*prc).disconnect();
|
||||
}
|
||||
peak_ready_connections.clear();
|
||||
|
||||
for (uint32_t n=0; n < _trackview.get_diskstream()->n_channels(); ++n) {
|
||||
AudioSource *src = (AudioSource *) _trackview.get_diskstream()->write_source (n);
|
||||
if (src) {
|
||||
sources.push_back (src);
|
||||
peak_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &StreamView::rec_peak_range_ready), src)));
|
||||
}
|
||||
}
|
||||
|
||||
// handle multi
|
||||
|
||||
jack_nframes_t start = 0;
|
||||
if (rec_regions.size() > 0) {
|
||||
start = rec_regions.back()->start() + _trackview.get_diskstream()->get_captured_frames(rec_regions.size()-1);
|
||||
}
|
||||
|
||||
AudioRegion * region = new AudioRegion(sources, start, 1 , "", 0, (Region::Flag)(Region::DefaultFlags | Region::DoNotSaveState), false);
|
||||
region->set_position (_trackview.session().transport_frame(), this);
|
||||
rec_regions.push_back (region);
|
||||
/* catch it if it goes away */
|
||||
region->GoingAway.connect (mem_fun (*this, &StreamView::remove_rec_region));
|
||||
|
||||
/* we add the region later */
|
||||
}
|
||||
|
||||
/* start a new rec box */
|
||||
|
||||
AudioTrack* at;
|
||||
|
||||
at = _trackview.audio_track(); /* we know what it is already */
|
||||
AudioDiskstream& ds = at->disk_stream();
|
||||
jack_nframes_t frame_pos = ds.current_capture_start ();
|
||||
gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos);
|
||||
gdouble xend;
|
||||
uint32_t fill_color;
|
||||
|
||||
switch (_trackview.audio_track()->mode()) {
|
||||
case Normal:
|
||||
xend = xstart;
|
||||
fill_color = color_map[cRecordingRectFill];
|
||||
break;
|
||||
|
||||
case Destructive:
|
||||
xend = xstart + 2;
|
||||
fill_color = color_map[cRecordingRectFill];
|
||||
/* make the recording rect translucent to allow
|
||||
the user to see the peak data coming in, etc.
|
||||
*/
|
||||
fill_color = UINT_RGBA_CHANGE_A (fill_color, 120);
|
||||
break;
|
||||
}
|
||||
|
||||
ArdourCanvas::SimpleRect * rec_rect = new Gnome::Canvas::SimpleRect (*canvas_group);
|
||||
rec_rect->property_x1() = xstart;
|
||||
rec_rect->property_y1() = 1.0;
|
||||
rec_rect->property_x2() = xend;
|
||||
rec_rect->property_y2() = (double) _trackview.height - 1;
|
||||
rec_rect->property_outline_color_rgba() = color_map[cRecordingRectOutline];
|
||||
rec_rect->property_fill_color_rgba() = fill_color;
|
||||
|
||||
RecBoxInfo recbox;
|
||||
recbox.rectangle = rec_rect;
|
||||
recbox.start = _trackview.session().transport_frame();
|
||||
recbox.length = 0;
|
||||
|
||||
rec_rects.push_back (recbox);
|
||||
|
||||
screen_update_connection.disconnect();
|
||||
screen_update_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (mem_fun (*this, &StreamView::update_rec_box));
|
||||
rec_updating = true;
|
||||
rec_active = true;
|
||||
|
||||
} else if (rec_active &&
|
||||
(_trackview.session().record_status() != Session::Recording ||
|
||||
!_trackview.get_diskstream()->record_enabled())) {
|
||||
|
||||
screen_update_connection.disconnect();
|
||||
rec_active = false;
|
||||
rec_updating = false;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// cerr << "\tNOT rolling, rec_rects = " << rec_rects.size() << " rec_regions = " << rec_regions.size() << endl;
|
||||
|
||||
if (!rec_rects.empty() || !rec_regions.empty()) {
|
||||
|
||||
/* disconnect rapid update */
|
||||
screen_update_connection.disconnect();
|
||||
|
||||
for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) {
|
||||
(*prc).disconnect();
|
||||
}
|
||||
peak_ready_connections.clear();
|
||||
|
||||
rec_updating = false;
|
||||
rec_active = false;
|
||||
last_rec_peak_frame = 0;
|
||||
|
||||
/* remove temp regions */
|
||||
for (list<AudioRegion*>::iterator iter=rec_regions.begin(); iter != rec_regions.end(); )
|
||||
{
|
||||
list<AudioRegion*>::iterator tmp;
|
||||
|
||||
tmp = iter;
|
||||
++tmp;
|
||||
|
||||
/* this will trigger the remove_region_view */
|
||||
delete *iter;
|
||||
|
||||
iter = tmp;
|
||||
}
|
||||
|
||||
rec_regions.clear();
|
||||
|
||||
// cerr << "\tclear " << rec_rects.size() << " rec rects\n";
|
||||
|
||||
|
||||
/* transport stopped, clear boxes */
|
||||
for (vector<RecBoxInfo>::iterator iter=rec_rects.begin(); iter != rec_rects.end(); ++iter) {
|
||||
RecBoxInfo &rect = (*iter);
|
||||
delete rect.rectangle;
|
||||
}
|
||||
|
||||
rec_rects.clear();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StreamView::update_rec_box ()
|
||||
{
|
||||
@@ -776,7 +336,7 @@ StreamView::update_rec_box ()
|
||||
double xstart;
|
||||
double xend;
|
||||
|
||||
switch (_trackview.audio_track()->mode()) {
|
||||
switch (_trackview.track()->mode()) {
|
||||
case Normal:
|
||||
rect.length = at - rect.start;
|
||||
xstart = _trackview.editor.frame_to_pixel (rect.start);
|
||||
@@ -795,12 +355,12 @@ StreamView::update_rec_box ()
|
||||
}
|
||||
}
|
||||
|
||||
AudioRegionView*
|
||||
StreamView::find_view (const AudioRegion& region)
|
||||
RegionView*
|
||||
StreamView::find_view (const Region& region)
|
||||
{
|
||||
for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
|
||||
if (&(*i)->region == ®ion) {
|
||||
if (&(*i)->region() == ®ion) {
|
||||
return *i;
|
||||
}
|
||||
}
|
||||
@@ -808,172 +368,51 @@ StreamView::find_view (const AudioRegion& region)
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::foreach_regionview (sigc::slot<void,AudioRegionView*> slot)
|
||||
StreamView::foreach_regionview (sigc::slot<void,RegionView*> slot)
|
||||
{
|
||||
for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
slot (*i);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::foreach_crossfadeview (void (CrossfadeView::*pmf)(void))
|
||||
StreamView::set_selected_regionviews (RegionSelection& regions)
|
||||
{
|
||||
for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
((*i)->*pmf) ();
|
||||
}
|
||||
}
|
||||
bool selected;
|
||||
|
||||
void
|
||||
StreamView::rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, Source * src)
|
||||
{
|
||||
// this is called from the peak building thread
|
||||
|
||||
ENSURE_GUI_THREAD(bind (mem_fun (*this, &StreamView::rec_peak_range_ready), start, cnt, src));
|
||||
|
||||
if (rec_peak_ready_map.size() == 0 || start+cnt > last_rec_peak_frame) {
|
||||
last_rec_peak_frame = start + cnt;
|
||||
}
|
||||
|
||||
rec_peak_ready_map[src] = true;
|
||||
|
||||
if (rec_peak_ready_map.size() == _trackview.get_diskstream()->n_channels()) {
|
||||
this->update_rec_regions ();
|
||||
rec_peak_ready_map.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::update_rec_regions ()
|
||||
{
|
||||
if (use_rec_regions) {
|
||||
|
||||
uint32_t n = 0;
|
||||
|
||||
for (list<AudioRegion*>::iterator iter = rec_regions.begin(); iter != rec_regions.end(); n++) {
|
||||
|
||||
list<AudioRegion*>::iterator tmp;
|
||||
|
||||
tmp = iter;
|
||||
++tmp;
|
||||
|
||||
if (!canvas_item_visible (rec_rects[n].rectangle)) {
|
||||
/* rect already hidden, this region is done */
|
||||
iter = tmp;
|
||||
continue;
|
||||
// cerr << _trackview.name() << " (selected = " << regions.size() << ")" << endl;
|
||||
for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
|
||||
selected = false;
|
||||
|
||||
for (RegionSelection::iterator ii = regions.begin(); ii != regions.end(); ++ii) {
|
||||
if (*i == *ii) {
|
||||
selected = true;
|
||||
}
|
||||
|
||||
AudioRegion * region = (*iter);
|
||||
jack_nframes_t origlen = region->length();
|
||||
}
|
||||
|
||||
// cerr << "\tregion " << (*i)->region().name() << " selected = " << selected << endl;
|
||||
(*i)->set_selected (selected);
|
||||
}
|
||||
}
|
||||
|
||||
if (region == rec_regions.back() && rec_active) {
|
||||
|
||||
if (last_rec_peak_frame > region->start()) {
|
||||
|
||||
jack_nframes_t nlen = last_rec_peak_frame - region->start();
|
||||
|
||||
if (nlen != region->length()) {
|
||||
|
||||
region->freeze ();
|
||||
region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
|
||||
region->set_length (nlen, this);
|
||||
region->thaw ("updated");
|
||||
|
||||
if (origlen == 1) {
|
||||
/* our special initial length */
|
||||
add_region_view_internal (region, false);
|
||||
}
|
||||
|
||||
/* also update rect */
|
||||
ArdourCanvas::SimpleRect * rect = rec_rects[n].rectangle;
|
||||
gdouble xend = _trackview.editor.frame_to_pixel (region->position() + region->length());
|
||||
rect->property_x2() = xend;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
jack_nframes_t nlen = _trackview.get_diskstream()->get_captured_frames(n);
|
||||
|
||||
if (nlen != region->length()) {
|
||||
|
||||
if (region->source(0).length() >= region->start() + nlen) {
|
||||
|
||||
region->freeze ();
|
||||
region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
|
||||
region->set_length (nlen, this);
|
||||
region->thaw ("updated");
|
||||
|
||||
if (origlen == 1) {
|
||||
/* our special initial length */
|
||||
add_region_view_internal (region, false);
|
||||
}
|
||||
|
||||
/* also hide rect */
|
||||
ArdourCanvas::Item * rect = rec_rects[n].rectangle;
|
||||
rect->hide();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iter = tmp;
|
||||
void
|
||||
StreamView::get_selectables (jack_nframes_t start, jack_nframes_t end, list<Selectable*>& results)
|
||||
{
|
||||
for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
if ((*i)->region().coverage(start, end) != OverlapNone) {
|
||||
results.push_back (*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::show_all_xfades ()
|
||||
StreamView::get_inverted_selectables (Selection& sel, list<Selectable*>& results)
|
||||
{
|
||||
foreach_crossfadeview (&CrossfadeView::show);
|
||||
crossfades_visible = true;
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::hide_all_xfades ()
|
||||
{
|
||||
foreach_crossfadeview (&CrossfadeView::hide);
|
||||
crossfades_visible = false;
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::hide_xfades_involving (AudioRegionView& rv)
|
||||
{
|
||||
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
if ((*i)->crossfade.involves (rv.region)) {
|
||||
(*i)->fake_hide ();
|
||||
for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
if (!sel.regions.contains (*i)) {
|
||||
results.push_back (*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::reveal_xfades_involving (AudioRegionView& rv)
|
||||
{
|
||||
for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
|
||||
if ((*i)->crossfade.involves (rv.region) && (*i)->visible()) {
|
||||
(*i)->show ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamView::color_handler (ColorID id, uint32_t val)
|
||||
{
|
||||
switch (id) {
|
||||
case cAudioTrackBase:
|
||||
if (_trackview.is_audio_track()) {
|
||||
canvas_rect->property_fill_color_rgba() = val;
|
||||
}
|
||||
break;
|
||||
case cAudioBusBase:
|
||||
if (!_trackview.is_audio_track()) {
|
||||
canvas_rect->property_fill_color_rgba() = val;
|
||||
}
|
||||
break;
|
||||
case cAudioTrackOutline:
|
||||
canvas_rect->property_outline_color_rgba() = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (C) 2001 Paul Davis
|
||||
Copyright (C) 2001, 2006 Paul Davis
|
||||
|
||||
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
|
||||
@@ -14,8 +14,6 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef __ardour_streamview_h__
|
||||
@@ -37,141 +35,117 @@ namespace Gdk {
|
||||
|
||||
namespace ARDOUR {
|
||||
class Route;
|
||||
class AudioDiskstream;
|
||||
class Diskstream;
|
||||
class Crossfade;
|
||||
class PeakData;
|
||||
class AudioRegion;
|
||||
class Region;
|
||||
class Source;
|
||||
}
|
||||
|
||||
struct RecBoxInfo {
|
||||
ArdourCanvas::SimpleRect* rectangle;
|
||||
jack_nframes_t start;
|
||||
jack_nframes_t length;
|
||||
ArdourCanvas::SimpleRect* rectangle;
|
||||
jack_nframes_t start;
|
||||
jack_nframes_t length;
|
||||
};
|
||||
|
||||
class PublicEditor;
|
||||
class Selectable;
|
||||
class AudioTimeAxisView;
|
||||
class AudioRegionView;
|
||||
class AudioRegionSelection;
|
||||
class RouteTimeAxisView;
|
||||
class RegionView;
|
||||
class RegionSelection;
|
||||
class CrossfadeView;
|
||||
class Selection;
|
||||
|
||||
class StreamView : public sigc::trackable
|
||||
{
|
||||
public:
|
||||
StreamView (AudioTimeAxisView&);
|
||||
~StreamView ();
|
||||
public:
|
||||
virtual ~StreamView ();
|
||||
|
||||
void set_waveform_shape (WaveformShape);
|
||||
RouteTimeAxisView& trackview() { return _trackview; }
|
||||
|
||||
AudioTimeAxisView& trackview() { return _trackview; }
|
||||
void attach ();
|
||||
|
||||
void set_zoom_all();
|
||||
|
||||
int set_height (gdouble);
|
||||
int set_position (gdouble x, gdouble y);
|
||||
virtual int set_height (gdouble);
|
||||
|
||||
int set_samples_per_unit (gdouble spp);
|
||||
gdouble get_samples_per_unit () { return _samples_per_unit; }
|
||||
|
||||
int set_amplitude_above_axis (gdouble app);
|
||||
gdouble get_amplitude_above_axis () { return _amplitude_above_axis; }
|
||||
|
||||
void set_show_waveforms (bool yn);
|
||||
void set_show_waveforms_recording (bool yn) { use_rec_regions = yn; }
|
||||
virtual int set_samples_per_unit (gdouble spp);
|
||||
gdouble get_samples_per_unit () { return _samples_per_unit; }
|
||||
|
||||
ArdourCanvas::Item* canvas_item() { return canvas_group; }
|
||||
|
||||
sigc::signal<void,AudioRegionView*> AudioRegionViewAdded;
|
||||
|
||||
enum ColorTarget {
|
||||
RegionColor,
|
||||
StreamBaseColor
|
||||
};
|
||||
|
||||
void apply_color (Gdk::Color&, ColorTarget t);
|
||||
void set_selected_regionviews (AudioRegionSelection&);
|
||||
Gdk::Color get_region_color () const { return region_color; }
|
||||
void apply_color (Gdk::Color&, ColorTarget t);
|
||||
|
||||
RegionView* find_view (const ARDOUR::Region&);
|
||||
void foreach_regionview (sigc::slot<void,RegionView*> slot);
|
||||
|
||||
void set_selected_regionviews (RegionSelection&);
|
||||
void get_selectables (jack_nframes_t start, jack_nframes_t end, list<Selectable* >&);
|
||||
void get_inverted_selectables (Selection&, list<Selectable* >& results);
|
||||
Gdk::Color get_region_color () const { return region_color; }
|
||||
|
||||
void foreach_regionview (sigc::slot<void,AudioRegionView*> slot);
|
||||
void foreach_crossfadeview (void (CrossfadeView::*pmf)(void));
|
||||
|
||||
void attach ();
|
||||
void add_region_view (ARDOUR::Region*);
|
||||
void region_layered (RegionView*);
|
||||
|
||||
void region_layered (AudioRegionView*);
|
||||
sigc::signal<void,RegionView*> RegionViewAdded;
|
||||
|
||||
protected:
|
||||
StreamView (RouteTimeAxisView&);
|
||||
|
||||
AudioRegionView* find_view (const ARDOUR::AudioRegion&);
|
||||
//private: (FIXME?)
|
||||
|
||||
void show_all_xfades ();
|
||||
void hide_all_xfades ();
|
||||
void hide_xfades_involving (AudioRegionView&);
|
||||
void reveal_xfades_involving (AudioRegionView&);
|
||||
void transport_changed();
|
||||
void rec_enable_changed();
|
||||
void sess_rec_enable_changed();
|
||||
virtual void setup_rec_box () = 0;
|
||||
void update_rec_box ();
|
||||
virtual void update_rec_regions () = 0;
|
||||
|
||||
virtual void add_region_view_internal (ARDOUR::Region*, bool wait_for_waves) = 0;
|
||||
virtual void remove_region_view (ARDOUR::Region* );
|
||||
void remove_rec_region (ARDOUR::Region*);
|
||||
|
||||
private:
|
||||
AudioTimeAxisView& _trackview;
|
||||
void display_diskstream (ARDOUR::Diskstream* );
|
||||
virtual void undisplay_diskstream ();
|
||||
virtual void redisplay_diskstream () = 0;
|
||||
void diskstream_changed ();
|
||||
|
||||
void playlist_state_changed (ARDOUR::Change);
|
||||
virtual void playlist_changed (ARDOUR::Diskstream* );
|
||||
virtual void playlist_modified ();
|
||||
|
||||
virtual void color_handler (ColorID, uint32_t) = 0;
|
||||
|
||||
ArdourCanvas::Group* canvas_group;
|
||||
|
||||
RouteTimeAxisView& _trackview;
|
||||
ArdourCanvas::Group* canvas_group;
|
||||
ArdourCanvas::SimpleRect* canvas_rect; /* frame around the whole thing */
|
||||
|
||||
typedef list<AudioRegionView* > AudioRegionViewList;
|
||||
AudioRegionViewList region_views;
|
||||
|
||||
typedef list<CrossfadeView*> CrossfadeViewList;
|
||||
CrossfadeViewList crossfade_views;
|
||||
typedef list<RegionView* > RegionViewList;
|
||||
RegionViewList region_views;
|
||||
|
||||
double _samples_per_unit;
|
||||
double _amplitude_above_axis;
|
||||
|
||||
sigc::connection screen_update_connection;
|
||||
vector<RecBoxInfo> rec_rects;
|
||||
list<ARDOUR::AudioRegion* > rec_regions;
|
||||
bool rec_updating;
|
||||
bool rec_active;
|
||||
bool use_rec_regions;
|
||||
list<sigc::connection> peak_ready_connections;
|
||||
jack_nframes_t last_rec_peak_frame;
|
||||
map<ARDOUR::Source*, bool> rec_peak_ready_map;
|
||||
sigc::connection screen_update_connection;
|
||||
vector<RecBoxInfo> rec_rects;
|
||||
list<ARDOUR::Region* > rec_regions;
|
||||
bool rec_updating;
|
||||
bool rec_active;
|
||||
bool use_rec_regions;
|
||||
|
||||
void update_rec_box ();
|
||||
void transport_changed();
|
||||
void rec_enable_changed(void* src = 0);
|
||||
void sess_rec_enable_changed();
|
||||
void setup_rec_box ();
|
||||
void rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, ARDOUR::Source* src);
|
||||
void update_rec_regions ();
|
||||
|
||||
void add_region_view (ARDOUR::Region*);
|
||||
void add_region_view_internal (ARDOUR::Region*, bool wait_for_waves);
|
||||
void remove_region_view (ARDOUR::Region* );
|
||||
void remove_rec_region (ARDOUR::Region*);
|
||||
void remove_audio_region_view (ARDOUR::AudioRegion* );
|
||||
void remove_audio_rec_region (ARDOUR::AudioRegion*);
|
||||
|
||||
void display_diskstream (ARDOUR::AudioDiskstream* );
|
||||
void undisplay_diskstream ();
|
||||
void redisplay_diskstream ();
|
||||
void diskstream_changed (void* );
|
||||
void playlist_state_changed (ARDOUR::Change);
|
||||
void playlist_changed (ARDOUR::AudioDiskstream* );
|
||||
void playlist_modified ();
|
||||
|
||||
bool crossfades_visible;
|
||||
void add_crossfade (ARDOUR::Crossfade*);
|
||||
void remove_crossfade (ARDOUR::Crossfade*);
|
||||
|
||||
/* XXX why are these different? */
|
||||
|
||||
Gdk::Color region_color;
|
||||
uint32_t stream_base_color;
|
||||
|
||||
void color_handler (ColorID, uint32_t);
|
||||
uint32_t stream_base_color;
|
||||
|
||||
vector<sigc::connection> playlist_connections;
|
||||
sigc::connection playlist_change_connection;
|
||||
sigc::connection playlist_change_connection;
|
||||
};
|
||||
|
||||
#endif /* __ardour_streamview_h__ */
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <ardour/audiosource.h>
|
||||
#include <ardour/audio_diskstream.h>
|
||||
|
||||
#include "taperegionview.h"
|
||||
#include "tape_region_view.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "gui_thread.h"
|
||||
|
||||
@@ -42,12 +42,14 @@ using namespace PBD;
|
||||
using namespace Editing;
|
||||
using namespace ArdourCanvas;
|
||||
|
||||
const TimeAxisViewItem::Visibility TapeAudioRegionView::default_tape_visibility = TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowNameHighlight|
|
||||
TimeAxisViewItem::ShowFrame|
|
||||
TimeAxisViewItem::HideFrameRight|
|
||||
TimeAxisViewItem::FullWidthNameHighlight);
|
||||
const TimeAxisViewItem::Visibility TapeAudioRegionView::default_tape_visibility
|
||||
= TimeAxisViewItem::Visibility (
|
||||
TimeAxisViewItem::ShowNameHighlight |
|
||||
TimeAxisViewItem::ShowFrame |
|
||||
TimeAxisViewItem::HideFrameRight |
|
||||
TimeAxisViewItem::FullWidthNameHighlight);
|
||||
|
||||
TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, AudioTimeAxisView &tv,
|
||||
TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv,
|
||||
AudioRegion& r,
|
||||
double spu,
|
||||
Gdk::Color& basic_color)
|
||||
@@ -59,58 +61,14 @@ TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, AudioTime
|
||||
}
|
||||
|
||||
void
|
||||
TapeAudioRegionView::init (double amplitude_above_axis, Gdk::Color& basic_color, bool wfw)
|
||||
TapeAudioRegionView::init (Gdk::Color& basic_color, bool wfw)
|
||||
{
|
||||
XMLNode *node;
|
||||
|
||||
editor = 0;
|
||||
valid = true;
|
||||
in_destructor = false;
|
||||
_amplitude_above_axis = amplitude_above_axis;
|
||||
zero_line = 0;
|
||||
wait_for_waves = wfw;
|
||||
_height = 0;
|
||||
|
||||
_flags = 0;
|
||||
|
||||
if ((node = region.extra_xml ("GUI")) != 0) {
|
||||
set_flags (node);
|
||||
} else {
|
||||
_flags = WaveformVisible;
|
||||
store_flags ();
|
||||
}
|
||||
|
||||
fade_in_handle = 0;
|
||||
fade_out_handle = 0;
|
||||
gain_line = 0;
|
||||
sync_mark = 0;
|
||||
|
||||
compute_colors (basic_color);
|
||||
|
||||
create_waves ();
|
||||
|
||||
name_highlight->set_data ("regionview", this);
|
||||
|
||||
reset_width_dependent_items ((double) region.length() / samples_per_unit);
|
||||
|
||||
set_height (trackview.height);
|
||||
|
||||
region_muted ();
|
||||
region_resized (BoundsChanged);
|
||||
set_waveview_data_src();
|
||||
region_locked ();
|
||||
|
||||
/* no events, no state changes */
|
||||
|
||||
set_colors ();
|
||||
|
||||
// ColorChanged.connect (mem_fun (*this, &AudioRegionView::color_handler));
|
||||
AudioRegionView::init(basic_color, wfw);
|
||||
|
||||
/* every time the wave data changes and peaks are ready, redraw */
|
||||
|
||||
|
||||
for (uint32_t n = 0; n < region.n_channels(); ++n) {
|
||||
region.source(n).PeaksReady.connect (bind (mem_fun(*this, &TapeAudioRegionView::update), n));
|
||||
for (uint32_t n = 0; n < audio_region().n_channels(); ++n) {
|
||||
audio_region().source(n).PeaksReady.connect (bind (mem_fun(*this, &TapeAudioRegionView::update), n));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -132,7 +90,7 @@ TapeAudioRegionView::update (uint32_t n)
|
||||
|
||||
/* this triggers a cache invalidation and redraw in the waveview */
|
||||
|
||||
waves[n]->property_data_src() = ®ion;
|
||||
waves[n]->property_data_src() = &_region;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -23,20 +23,20 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "regionview.h"
|
||||
#include "audio_region_view.h"
|
||||
|
||||
class TapeAudioRegionView : public AudioRegionView
|
||||
{
|
||||
public:
|
||||
TapeAudioRegionView (ArdourCanvas::Group *,
|
||||
AudioTimeAxisView&,
|
||||
RouteTimeAxisView&,
|
||||
ARDOUR::AudioRegion&,
|
||||
double initial_samples_per_unit,
|
||||
Gdk::Color& base_color);
|
||||
~TapeAudioRegionView ();
|
||||
|
||||
protected:
|
||||
void init (double amplitude_above_axis, Gdk::Color& base_color, bool wait_for_waves);
|
||||
void init (Gdk::Color& base_color, bool wait_for_waves);
|
||||
|
||||
void set_frame_color ();
|
||||
void update (uint32_t n);
|
||||
@@ -54,7 +54,7 @@ namespace Gtk {
|
||||
}
|
||||
|
||||
class PublicEditor;
|
||||
class AudioRegionSelection;
|
||||
class RegionSelection;
|
||||
class TimeSelection;
|
||||
class PointSelection;
|
||||
class TimeAxisViewItem;
|
||||
@@ -183,7 +183,7 @@ class TimeAxisView : public virtual AxisView
|
||||
virtual bool cut_copy_clear (Selection&, Editing::CutCopyOp) { return false; }
|
||||
virtual bool paste (jack_nframes_t, float times, Selection&, size_t nth) { return false; }
|
||||
|
||||
virtual void set_selected_regionviews (AudioRegionSelection&) {}
|
||||
virtual void set_selected_regionviews (RegionSelection&) {}
|
||||
virtual void set_selected_points (PointSelection&) {}
|
||||
|
||||
virtual ARDOUR::Region* find_next_region (jack_nframes_t pos, ARDOUR::RegionPoint, int32_t dir) {
|
||||
|
||||
@@ -255,7 +255,7 @@ VisualTimeAxis::set_time_axis_color(Gdk::Color c)
|
||||
}
|
||||
|
||||
void
|
||||
VisualTimeAxis::set_selected_regionviews (AudioRegionSelection& regions)
|
||||
VisualTimeAxis::set_selected_regionviews (RegionSelection& regions)
|
||||
{
|
||||
// Not handled by purely visual TimeAxis
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ class ImageFrameView;
|
||||
class ImageFrameTimeAxisView;
|
||||
class MarkersTimeAxisView;
|
||||
class TimeSelection;
|
||||
class AudioRegionSelection;
|
||||
class RegionSelection;
|
||||
class MarkerTimeAxis;
|
||||
class TimeAxisViewStrip;
|
||||
|
||||
@@ -105,7 +105,7 @@ class VisualTimeAxis : public TimeAxisView
|
||||
/**
|
||||
* Not implemented
|
||||
*/
|
||||
virtual void set_selected_regionviews(AudioRegionSelection&) ;
|
||||
virtual void set_selected_regionviews(RegionSelection&) ;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------//
|
||||
|
||||
@@ -27,9 +27,11 @@ ardour.Append(POTFILE = domain + '.pot')
|
||||
ardour.Append(CPPPATH = '#libs/surfaces/control_protocol')
|
||||
|
||||
ardour_files=Split("""
|
||||
diskstream.cc
|
||||
audio_diskstream.cc
|
||||
audio_library.cc
|
||||
audio_playlist.cc
|
||||
track.cc
|
||||
audio_track.cc
|
||||
audioengine.cc
|
||||
audiofilesource.cc
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (C) 2000 Paul Davis
|
||||
Copyright (C) 2000-2006 Paul Davis
|
||||
|
||||
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
|
||||
@@ -14,12 +14,10 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: diskstream.h 579 2006-06-12 19:56:37Z essej $
|
||||
*/
|
||||
|
||||
#ifndef __ardour_diskstream_h__
|
||||
#define __ardour_diskstream_h__
|
||||
#ifndef __ardour_audio_diskstream_h__
|
||||
#define __ardour_audio_diskstream_h__
|
||||
|
||||
#include <sigc++/signal.h>
|
||||
|
||||
@@ -42,6 +40,8 @@
|
||||
#include <ardour/route.h>
|
||||
#include <ardour/port.h>
|
||||
#include <ardour/utils.h>
|
||||
#include <ardour/diskstream.h>
|
||||
#include <ardour/audioplaylist.h>
|
||||
|
||||
struct tm;
|
||||
|
||||
@@ -54,53 +54,20 @@ class AudioPlaylist;
|
||||
class AudioFileSource;
|
||||
class IO;
|
||||
|
||||
class AudioDiskstream : public Stateful, public sigc::trackable
|
||||
class AudioDiskstream : public Diskstream
|
||||
{
|
||||
public:
|
||||
enum Flag {
|
||||
Recordable = 0x1,
|
||||
Hidden = 0x2,
|
||||
Destructive = 0x4
|
||||
};
|
||||
|
||||
AudioDiskstream (Session &, const string& name, Flag f = Recordable);
|
||||
AudioDiskstream (Session &, const string& name, Diskstream::Flag f = Recordable);
|
||||
AudioDiskstream (Session &, const XMLNode&);
|
||||
|
||||
string name() const { return _name; }
|
||||
|
||||
ARDOUR::IO* io() const { return _io; }
|
||||
void set_io (ARDOUR::IO& io);
|
||||
const PBD::ID& id() const { return _id; }
|
||||
|
||||
// FIXME
|
||||
AudioDiskstream& ref() { _refcnt++; return *this; }
|
||||
void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; }
|
||||
uint32_t refcnt() const { return _refcnt; }
|
||||
|
||||
float playback_buffer_load() const;
|
||||
float capture_buffer_load() const;
|
||||
|
||||
void set_flag (Flag f) {
|
||||
_flags |= f;
|
||||
}
|
||||
|
||||
void unset_flag (Flag f) {
|
||||
_flags &= ~f;
|
||||
}
|
||||
|
||||
AlignStyle alignment_style() const { return _alignment_style; }
|
||||
void set_align_style (AlignStyle);
|
||||
void set_persistent_align_style (AlignStyle);
|
||||
|
||||
bool hidden() const { return _flags & Hidden; }
|
||||
bool recordable() const { return _flags & Recordable; }
|
||||
bool destructive() const { return _flags & Destructive; }
|
||||
|
||||
void set_destructive (bool yn);
|
||||
|
||||
jack_nframes_t roll_delay() const { return _roll_delay; }
|
||||
void set_roll_delay (jack_nframes_t);
|
||||
|
||||
int set_name (string str, void* src);
|
||||
|
||||
string input_source (uint32_t n=0) const {
|
||||
if (n < channels.size()) {
|
||||
return channels[n].source ? channels[n].source->name() : "";
|
||||
@@ -113,14 +80,7 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
||||
if (n < channels.size()) return channels[n].source; return 0;
|
||||
}
|
||||
|
||||
void set_record_enabled (bool yn, void *src);
|
||||
bool record_enabled() const { return g_atomic_int_get (&_record_enabled); }
|
||||
void punch_in ();
|
||||
void punch_out ();
|
||||
|
||||
bool reversed() const { return _actual_speed < 0.0f; }
|
||||
double speed() const { return _visible_speed; }
|
||||
void set_speed (double);
|
||||
void set_record_enabled (bool yn);
|
||||
|
||||
float peak_power(uint32_t n=0) {
|
||||
float x = channels[n].peak_power;
|
||||
@@ -131,14 +91,13 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
||||
return minus_infinity();
|
||||
}
|
||||
}
|
||||
|
||||
AudioPlaylist* audio_playlist () { return dynamic_cast<AudioPlaylist*>(_playlist); }
|
||||
|
||||
int use_playlist (AudioPlaylist *);
|
||||
int use_playlist (Playlist *);
|
||||
int use_new_playlist ();
|
||||
int use_copy_playlist ();
|
||||
|
||||
void start_scrub (jack_nframes_t where);
|
||||
void end_scrub ();
|
||||
|
||||
Sample *playback_buffer (uint32_t n=0) {
|
||||
if (n < channels.size())
|
||||
return channels[n].current_playback_buffer;
|
||||
@@ -151,51 +110,23 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
||||
return 0;
|
||||
}
|
||||
|
||||
AudioPlaylist *playlist () { return _playlist; }
|
||||
|
||||
AudioFileSource *write_source (uint32_t n=0) {
|
||||
if (n < channels.size())
|
||||
return channels[n].write_source;
|
||||
return 0;
|
||||
}
|
||||
|
||||
jack_nframes_t current_capture_start() const { return capture_start_frame; }
|
||||
jack_nframes_t current_capture_end() const { return capture_start_frame + capture_captured; }
|
||||
jack_nframes_t get_capture_start_frame (uint32_t n=0);
|
||||
jack_nframes_t get_captured_frames (uint32_t n=0);
|
||||
|
||||
uint32_t n_channels() { return _n_channels; }
|
||||
|
||||
int add_channel ();
|
||||
int remove_channel ();
|
||||
|
||||
static void set_disk_io_chunk_frames (uint32_t n) {
|
||||
disk_io_chunk_frames = n;
|
||||
}
|
||||
|
||||
static jack_nframes_t disk_io_frames() { return disk_io_chunk_frames; }
|
||||
|
||||
sigc::signal<void,void*> record_enable_changed;
|
||||
sigc::signal<void> speed_changed;
|
||||
sigc::signal<void,void*> reverse_changed;
|
||||
sigc::signal<void> PlaylistChanged;
|
||||
sigc::signal<void> AlignmentStyleChanged;
|
||||
|
||||
static sigc::signal<void> DiskOverrun;
|
||||
static sigc::signal<void> DiskUnderrun;
|
||||
static sigc::signal<void,AudioDiskstream*> AudioDiskstreamCreated; // XXX use a ref with sigc2
|
||||
static sigc::signal<void,list<AudioFileSource*>*> DeleteSources;
|
||||
|
||||
/* stateful */
|
||||
|
||||
XMLNode& get_state(void);
|
||||
int set_state(const XMLNode& node);
|
||||
int set_state(const XMLNode& node);
|
||||
|
||||
void monitor_input (bool);
|
||||
|
||||
jack_nframes_t capture_offset() const { return _capture_offset; }
|
||||
void set_capture_offset ();
|
||||
|
||||
static void swap_by_ptr (Sample *first, Sample *last) {
|
||||
while (first < last) {
|
||||
Sample tmp = *first;
|
||||
@@ -212,19 +143,7 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
||||
}
|
||||
}
|
||||
|
||||
bool slaved() const { return _slaved; }
|
||||
void set_slaved(bool yn) { _slaved = yn; }
|
||||
|
||||
int set_loop (Location *loc);
|
||||
sigc::signal<void,Location *> LoopSet;
|
||||
|
||||
std::list<Region*>& last_capture_regions () {
|
||||
return _last_capture_regions;
|
||||
}
|
||||
|
||||
void handle_input_change (IOChange, void *src);
|
||||
|
||||
const PBD::ID& id() const { return _id; }
|
||||
std::list<Region*>& last_capture_regions () { return _last_capture_regions; }
|
||||
|
||||
XMLNode* deprecated_io_node;
|
||||
|
||||
@@ -236,9 +155,8 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
||||
while they are called.
|
||||
*/
|
||||
|
||||
void set_pending_overwrite (bool);
|
||||
void set_pending_overwrite(bool);
|
||||
int overwrite_existing_buffers ();
|
||||
void reverse_scrub_buffer (bool to_forward);
|
||||
void set_block_size (jack_nframes_t);
|
||||
int internal_playback_seek (jack_nframes_t distance);
|
||||
int can_internal_playback_seek (jack_nframes_t distance);
|
||||
@@ -246,9 +164,6 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
||||
void reset_write_sources (bool, bool force = false);
|
||||
void non_realtime_input_change ();
|
||||
|
||||
uint32_t read_data_count() const { return _read_data_count; }
|
||||
uint32_t write_data_count() const { return _write_data_count; }
|
||||
|
||||
protected:
|
||||
friend class Auditioner;
|
||||
int seek (jack_nframes_t which_sample, bool complete_refill = false);
|
||||
@@ -256,38 +171,23 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
||||
protected:
|
||||
friend class AudioTrack;
|
||||
|
||||
void prepare ();
|
||||
int process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input);
|
||||
bool commit (jack_nframes_t nframes);
|
||||
void recover (); /* called if commit will not be called, but process was */
|
||||
|
||||
private:
|
||||
|
||||
/* use unref() to destroy a diskstream */
|
||||
|
||||
~AudioDiskstream();
|
||||
|
||||
enum TransitionType {
|
||||
CaptureStart = 0,
|
||||
CaptureEnd
|
||||
};
|
||||
|
||||
struct CaptureTransition {
|
||||
|
||||
TransitionType type;
|
||||
// the start or end file frame pos
|
||||
jack_nframes_t capture_val;
|
||||
};
|
||||
|
||||
struct ChannelInfo {
|
||||
|
||||
Sample *playback_wrap_buffer;
|
||||
Sample *capture_wrap_buffer;
|
||||
Sample *speed_buffer;
|
||||
|
||||
float peak_power;
|
||||
float peak_power;
|
||||
|
||||
AudioFileSource *fades_source;
|
||||
AudioFileSource *fades_source;
|
||||
AudioFileSource *write_source;
|
||||
|
||||
Port *source;
|
||||
@@ -309,129 +209,30 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
||||
jack_nframes_t curr_capture_cnt;
|
||||
};
|
||||
|
||||
typedef vector<ChannelInfo> ChannelList;
|
||||
|
||||
|
||||
string _name;
|
||||
ARDOUR::Session& _session;
|
||||
ARDOUR::IO* _io;
|
||||
ChannelList channels;
|
||||
uint32_t _n_channels;
|
||||
PBD::ID _id;
|
||||
|
||||
mutable gint _record_enabled;
|
||||
AudioPlaylist* _playlist;
|
||||
double _visible_speed;
|
||||
double _actual_speed;
|
||||
/* items needed for speed change logic */
|
||||
bool _buffer_reallocation_required;
|
||||
bool _seek_required;
|
||||
/* The two central butler operations */
|
||||
int do_flush (Session::RunContext context, bool force = false);
|
||||
int do_refill () { return _do_refill(_mixdown_buffer, _gain_buffer, _conversion_buffer); }
|
||||
|
||||
bool force_refill;
|
||||
jack_nframes_t capture_start_frame;
|
||||
jack_nframes_t capture_captured;
|
||||
bool was_recording;
|
||||
jack_nframes_t adjust_capture_position;
|
||||
jack_nframes_t _capture_offset;
|
||||
jack_nframes_t _roll_delay;
|
||||
jack_nframes_t first_recordable_frame;
|
||||
jack_nframes_t last_recordable_frame;
|
||||
int last_possibly_recording;
|
||||
AlignStyle _alignment_style;
|
||||
bool _scrubbing;
|
||||
bool _slaved;
|
||||
bool _processed;
|
||||
Location* loop_location;
|
||||
jack_nframes_t overwrite_frame;
|
||||
off_t overwrite_offset;
|
||||
bool pending_overwrite;
|
||||
bool overwrite_queued;
|
||||
IOChange input_change_pending;
|
||||
jack_nframes_t wrap_buffer_size;
|
||||
jack_nframes_t speed_buffer_size;
|
||||
int do_refill_with_alloc();
|
||||
|
||||
uint64_t last_phase;
|
||||
uint64_t phi;
|
||||
|
||||
jack_nframes_t file_frame;
|
||||
jack_nframes_t playback_sample;
|
||||
jack_nframes_t playback_distance;
|
||||
|
||||
uint32_t _read_data_count;
|
||||
uint32_t _write_data_count;
|
||||
|
||||
bool in_set_state;
|
||||
AlignStyle _persistent_alignment_style;
|
||||
bool first_input_change;
|
||||
|
||||
Glib::Mutex state_lock;
|
||||
|
||||
jack_nframes_t scrub_start;
|
||||
jack_nframes_t scrub_buffer_size;
|
||||
jack_nframes_t scrub_offset;
|
||||
uint32_t _refcnt;
|
||||
|
||||
sigc::connection ports_created_c;
|
||||
sigc::connection plmod_connection;
|
||||
sigc::connection plstate_connection;
|
||||
sigc::connection plgone_connection;
|
||||
|
||||
/* the two central butler operations */
|
||||
|
||||
int do_flush (char * workbuf, bool force = false);
|
||||
int do_refill (Sample *mixdown_buffer, float *gain_buffer, char *workbuf);
|
||||
|
||||
int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf, jack_nframes_t& start, jack_nframes_t cnt,
|
||||
ChannelInfo& channel_info, int channel, bool reversed);
|
||||
|
||||
uint32_t i_am_the_modifier;
|
||||
|
||||
/* XXX fix this redundancy ... */
|
||||
|
||||
void playlist_changed (Change);
|
||||
void playlist_modified ();
|
||||
void playlist_deleted (Playlist*);
|
||||
void session_controls_changed (Session::ControlType);
|
||||
int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf,
|
||||
jack_nframes_t& start, jack_nframes_t cnt,
|
||||
ChannelInfo& channel_info, int channel, bool reversed);
|
||||
|
||||
void finish_capture (bool rec_monitors_input);
|
||||
void clean_up_capture (struct tm&, time_t, bool abort);
|
||||
void transport_stopped (struct tm&, time_t, bool abort);
|
||||
|
||||
struct CaptureInfo {
|
||||
uint32_t start;
|
||||
uint32_t frames;
|
||||
};
|
||||
|
||||
vector<CaptureInfo*> capture_info;
|
||||
Glib::Mutex capture_info_lock;
|
||||
|
||||
void init (Flag);
|
||||
void init (Diskstream::Flag);
|
||||
|
||||
void init_channel (ChannelInfo &chan);
|
||||
void destroy_channel (ChannelInfo &chan);
|
||||
|
||||
static jack_nframes_t disk_io_chunk_frames;
|
||||
|
||||
int use_new_write_source (uint32_t n=0);
|
||||
int use_new_fade_source (uint32_t n=0);
|
||||
|
||||
int find_and_use_playlist (const string&);
|
||||
|
||||
void allocate_temporary_buffers ();
|
||||
|
||||
unsigned char _flags;
|
||||
|
||||
int create_input_port ();
|
||||
int connect_input_port ();
|
||||
int seek_unlocked (jack_nframes_t which_sample);
|
||||
|
||||
int ports_created ();
|
||||
|
||||
bool realtime_set_speed (double, bool global_change);
|
||||
void non_realtime_set_speed ();
|
||||
|
||||
std::list<Region*> _last_capture_regions;
|
||||
std::vector<AudioFileSource*> capturing_sources;
|
||||
int use_pending_capture_data (XMLNode& node);
|
||||
|
||||
void get_input_sources ();
|
||||
@@ -439,10 +240,29 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
||||
void set_align_style_from_io();
|
||||
void setup_destructive_playlist ();
|
||||
void use_destructive_playlist ();
|
||||
void engage_record_enable (void* src);
|
||||
void disengage_record_enable (void* src);
|
||||
|
||||
void engage_record_enable ();
|
||||
void disengage_record_enable ();
|
||||
|
||||
// Working buffers for do_refill (butler thread)
|
||||
static void allocate_working_buffers();
|
||||
static void free_working_buffers();
|
||||
|
||||
static size_t _working_buffers_size;
|
||||
static Sample* _mixdown_buffer;
|
||||
static gain_t* _gain_buffer;
|
||||
static char* _conversion_buffer;
|
||||
|
||||
// Uh, /really/ private? (death to friend classes)
|
||||
int _do_refill (Sample *mixdown_buffer, float *gain_buffer, char *workbuf);
|
||||
|
||||
|
||||
std::vector<AudioFileSource*> capturing_sources;
|
||||
|
||||
typedef vector<ChannelInfo> ChannelList;
|
||||
ChannelList channels;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_diskstream_h__ */
|
||||
#endif /* __ardour_audio_diskstream_h__ */
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#ifndef __ardour_audio_track_h__
|
||||
#define __ardour_audio_track_h__
|
||||
|
||||
#include <ardour/route.h>
|
||||
#include <ardour/track.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
@@ -30,76 +30,38 @@ class AudioDiskstream;
|
||||
class AudioPlaylist;
|
||||
class RouteGroup;
|
||||
|
||||
class AudioTrack : public Route
|
||||
class AudioTrack : public Track
|
||||
{
|
||||
public:
|
||||
AudioTrack (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal);
|
||||
AudioTrack (Session&, const XMLNode&);
|
||||
~AudioTrack ();
|
||||
|
||||
int roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
jack_nframes_t offset, int declick, bool can_record, bool rec_monitors_input);
|
||||
|
||||
int set_name (string str, void *src);
|
||||
int no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
jack_nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input);
|
||||
|
||||
int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
jack_nframes_t offset, bool can_record, bool rec_monitors_input);
|
||||
|
||||
int roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
AudioDiskstream& audio_diskstream() const;
|
||||
|
||||
jack_nframes_t offset, int declick, bool can_record, bool rec_monitors_input);
|
||||
int no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
jack_nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input);
|
||||
int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
jack_nframes_t offset, bool can_record, bool rec_monitors_input);
|
||||
|
||||
void toggle_monitor_input ();
|
||||
|
||||
bool can_record() const { return true; }
|
||||
void set_record_enable (bool yn, void *src);
|
||||
|
||||
AudioDiskstream& disk_stream() const { return *diskstream; }
|
||||
int set_diskstream (AudioDiskstream&, void *);
|
||||
int use_diskstream (string name);
|
||||
int use_diskstream (const PBD::ID& id);
|
||||
|
||||
TrackMode mode() const { return _mode; }
|
||||
void set_mode (TrackMode m);
|
||||
sigc::signal<void> ModeChanged;
|
||||
|
||||
jack_nframes_t update_total_latency();
|
||||
void set_latency_delay (jack_nframes_t);
|
||||
|
||||
int export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t end_frame);
|
||||
|
||||
sigc::signal<void,void*> diskstream_changed;
|
||||
|
||||
enum FreezeState {
|
||||
NoFreeze,
|
||||
Frozen,
|
||||
UnFrozen
|
||||
};
|
||||
|
||||
FreezeState freeze_state() const;
|
||||
|
||||
sigc::signal<void> FreezeChange;
|
||||
|
||||
void freeze (InterThreadInfo&);
|
||||
void unfreeze ();
|
||||
|
||||
void bounce (InterThreadInfo&);
|
||||
void bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo&);
|
||||
|
||||
XMLNode& get_state();
|
||||
XMLNode& get_template();
|
||||
int set_state(const XMLNode& node);
|
||||
|
||||
PBD::Controllable& rec_enable_control() {
|
||||
return _rec_enable_control;
|
||||
}
|
||||
|
||||
bool record_enabled() const;
|
||||
void set_meter_point (MeterPoint, void* src);
|
||||
|
||||
protected:
|
||||
AudioDiskstream *diskstream;
|
||||
MeterPoint _saved_meter_point;
|
||||
TrackMode _mode;
|
||||
|
||||
XMLNode& state (bool full);
|
||||
|
||||
void passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
@@ -107,59 +69,12 @@ class AudioTrack : public Route
|
||||
bool meter);
|
||||
|
||||
uint32_t n_process_buffers ();
|
||||
|
||||
|
||||
private:
|
||||
struct FreezeRecordInsertInfo {
|
||||
FreezeRecordInsertInfo(XMLNode& st, boost::shared_ptr<Insert> ins)
|
||||
: state (st), insert (ins) {}
|
||||
|
||||
XMLNode state;
|
||||
boost::shared_ptr<Insert> insert;
|
||||
PBD::ID id;
|
||||
UndoAction memento;
|
||||
};
|
||||
|
||||
struct FreezeRecord {
|
||||
FreezeRecord() {
|
||||
playlist = 0;
|
||||
have_mementos = false;
|
||||
}
|
||||
|
||||
~FreezeRecord();
|
||||
|
||||
AudioPlaylist* playlist;
|
||||
vector<FreezeRecordInsertInfo*> insert_info;
|
||||
bool have_mementos;
|
||||
FreezeState state;
|
||||
};
|
||||
|
||||
FreezeRecord _freeze_record;
|
||||
XMLNode* pending_state;
|
||||
|
||||
void diskstream_record_enable_changed (void *src);
|
||||
void diskstream_input_channel_changed (void *src);
|
||||
|
||||
void input_change_handler (void *src);
|
||||
|
||||
sigc::connection recenable_connection;
|
||||
sigc::connection ic_connection;
|
||||
|
||||
int deprecated_use_diskstream_connections ();
|
||||
int set_diskstream (AudioDiskstream&, void *);
|
||||
int deprecated_use_diskstream_connections ();
|
||||
void set_state_part_two ();
|
||||
void set_state_part_three ();
|
||||
|
||||
struct RecEnableControllable : public PBD::Controllable {
|
||||
RecEnableControllable (AudioTrack&);
|
||||
|
||||
void set_value (float);
|
||||
float get_value (void) const;
|
||||
|
||||
AudioTrack& track;
|
||||
};
|
||||
|
||||
RecEnableControllable _rec_enable_control;
|
||||
|
||||
bool _destructive;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <ardour/ardour.h>
|
||||
#include <jack/jack.h>
|
||||
#include <jack/transport.h>
|
||||
#include <ardour/types.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
@@ -104,8 +105,8 @@ class AudioEngine : public sigc::trackable
|
||||
virtual const char *what() const throw() { return "could not connect to engine backend"; }
|
||||
};
|
||||
|
||||
Port *register_audio_input_port (const std::string& portname);
|
||||
Port *register_audio_output_port (const std::string& portname);
|
||||
Port *register_input_port (DataType type, const std::string& portname);
|
||||
Port *register_output_port (DataType type, const std::string& portname);
|
||||
int unregister_port (Port *);
|
||||
|
||||
int connect (const std::string& source, const std::string& destination);
|
||||
|
||||
@@ -77,9 +77,6 @@ class AudioPlaylist : public ARDOUR::Playlist
|
||||
|
||||
bool destroy_region (Region*);
|
||||
|
||||
void get_equivalent_regions (const AudioRegion&, std::vector<AudioRegion*>&);
|
||||
void get_region_list_equivalent_regions (const AudioRegion&, std::vector<AudioRegion*>&);
|
||||
|
||||
void drop_all_states ();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -27,8 +27,9 @@
|
||||
#include <pbd/undo.h>
|
||||
|
||||
#include <ardour/ardour.h>
|
||||
#include <ardour/gain.h>
|
||||
#include <ardour/region.h>
|
||||
#include <ardour/gain.h>
|
||||
#include <ardour/logcurve.h>
|
||||
#include <ardour/export.h>
|
||||
|
||||
class XMLNode;
|
||||
@@ -43,14 +44,14 @@ class AudioSource;
|
||||
|
||||
struct AudioRegionState : public RegionState
|
||||
{
|
||||
AudioRegionState (std::string why);
|
||||
AudioRegionState (std::string why);
|
||||
|
||||
Curve _fade_in;
|
||||
Curve _fade_out;
|
||||
Curve _envelope;
|
||||
gain_t _scale_amplitude;
|
||||
uint32_t _fade_in_disabled;
|
||||
uint32_t _fade_out_disabled;
|
||||
Curve _fade_in;
|
||||
Curve _fade_out;
|
||||
Curve _envelope;
|
||||
gain_t _scale_amplitude;
|
||||
uint32_t _fade_in_disabled;
|
||||
uint32_t _fade_out_disabled;
|
||||
};
|
||||
|
||||
class AudioRegion : public Region
|
||||
@@ -75,11 +76,7 @@ class AudioRegion : public Region
|
||||
AudioRegion (SourceList &, const XMLNode&);
|
||||
~AudioRegion();
|
||||
|
||||
bool region_list_equivalent (const AudioRegion&) const ;
|
||||
bool source_equivalent (const AudioRegion&) const;
|
||||
bool equivalent (const AudioRegion&) const;
|
||||
bool size_equivalent (const AudioRegion&) const;
|
||||
bool overlap_equivalent (const AudioRegion&) const;
|
||||
bool source_equivalent (const Region&) const;
|
||||
|
||||
bool speed_mismatch (float) const;
|
||||
|
||||
@@ -96,7 +93,7 @@ class AudioRegion : public Region
|
||||
vector<string> master_source_names();
|
||||
|
||||
bool envelope_active () const { return _flags & Region::EnvelopeActive; }
|
||||
bool fade_in_active () const { return _flags & Region::FadeIn; }
|
||||
bool fade_in_active () const { return _flags & Region::FadeIn; }
|
||||
bool fade_out_active () const { return _flags & Region::FadeOut; }
|
||||
bool captured() const { return !(_flags & (Region::Flag (Region::Import|Region::External))); }
|
||||
|
||||
@@ -104,20 +101,21 @@ class AudioRegion : public Region
|
||||
Curve& fade_out() { return _fade_out; }
|
||||
Curve& envelope() { return _envelope; }
|
||||
|
||||
jack_nframes_t read_peaks (PeakData *buf, jack_nframes_t npeaks, jack_nframes_t offset, jack_nframes_t cnt, uint32_t chan_n=0, double samples_per_unit= 1.0) const;
|
||||
jack_nframes_t read_peaks (PeakData *buf, jack_nframes_t npeaks,
|
||||
jack_nframes_t offset, jack_nframes_t cnt,
|
||||
uint32_t chan_n=0, double samples_per_unit= 1.0) const;
|
||||
|
||||
virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
|
||||
float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt,
|
||||
uint32_t chan_n = 0,
|
||||
jack_nframes_t read_frames = 0,
|
||||
jack_nframes_t skip_frames = 0) const;
|
||||
|
||||
jack_nframes_t master_read_at (Sample *buf, Sample *mixdown_buffer,
|
||||
float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt, uint32_t chan_n=0) const;
|
||||
virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buf,
|
||||
float *gain_buf, char * workbuf, jack_nframes_t position, jack_nframes_t cnt,
|
||||
uint32_t chan_n = 0,
|
||||
jack_nframes_t read_frames = 0,
|
||||
jack_nframes_t skip_frames = 0) const;
|
||||
|
||||
jack_nframes_t master_read_at (Sample *buf, Sample *mixdown_buf,
|
||||
float *gain_buf, char * workbuf,
|
||||
jack_nframes_t position, jack_nframes_t cnt, uint32_t chan_n=0) const;
|
||||
|
||||
XMLNode& state (bool);
|
||||
XMLNode& get_state ();
|
||||
int set_state (const XMLNode&);
|
||||
|
||||
static void set_default_fade (float steepness, jack_nframes_t len);
|
||||
@@ -144,10 +142,6 @@ class AudioRegion : public Region
|
||||
|
||||
int separate_by_channel (ARDOUR::Session&, vector<AudioRegion*>&) const;
|
||||
|
||||
uint32_t read_data_count() const { return _read_data_count; }
|
||||
|
||||
ARDOUR::Playlist* playlist() const { return _playlist; }
|
||||
|
||||
UndoAction get_memento() const;
|
||||
|
||||
/* filter */
|
||||
@@ -171,20 +165,6 @@ class AudioRegion : public Region
|
||||
friend class Playlist;
|
||||
|
||||
private:
|
||||
SourceList sources;
|
||||
SourceList master_sources; /* used when timefx are applied, so
|
||||
we can always use the original
|
||||
source.
|
||||
*/
|
||||
mutable Curve _fade_in;
|
||||
FadeShape _fade_in_shape;
|
||||
mutable Curve _fade_out;
|
||||
FadeShape _fade_out_shape;
|
||||
mutable Curve _envelope;
|
||||
gain_t _scale_amplitude;
|
||||
uint32_t _fade_in_disabled;
|
||||
uint32_t _fade_out_disabled;
|
||||
|
||||
void set_default_fades ();
|
||||
void set_default_fade_in ();
|
||||
void set_default_fade_out ();
|
||||
@@ -196,10 +176,6 @@ class AudioRegion : public Region
|
||||
void recompute_gain_at_end ();
|
||||
void recompute_gain_at_start ();
|
||||
|
||||
bool copied() const { return _flags & Copied; }
|
||||
void maybe_uncopy ();
|
||||
void rename_after_first_edit ();
|
||||
|
||||
jack_nframes_t _read_at (const SourceList&, Sample *buf, Sample *mixdown_buffer,
|
||||
float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt,
|
||||
uint32_t chan_n = 0,
|
||||
@@ -216,6 +192,21 @@ class AudioRegion : public Region
|
||||
void envelope_changed (Change);
|
||||
|
||||
void source_deleted (Source*);
|
||||
|
||||
|
||||
SourceList sources;
|
||||
|
||||
/** Used when timefx are applied, so we can always use the original source. */
|
||||
SourceList master_sources;
|
||||
|
||||
mutable Curve _fade_in;
|
||||
FadeShape _fade_in_shape;
|
||||
mutable Curve _fade_out;
|
||||
FadeShape _fade_out_shape;
|
||||
mutable Curve _envelope;
|
||||
gain_t _scale_amplitude;
|
||||
uint32_t _fade_in_disabled;
|
||||
uint32_t _fade_out_disabled;
|
||||
};
|
||||
|
||||
} /* namespace ARDOUR */
|
||||
|
||||
144
libs/ardour/ardour/buffer.h
Normal file
144
libs/ardour/ardour/buffer.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
Copyright (C) 2006 Paul Davis
|
||||
Written by Dave Robillard, 2006
|
||||
|
||||
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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ardour_buffer_h__
|
||||
#define __ardour_buffer_h__
|
||||
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include <cstdlib> // for posix_memalign
|
||||
#include <cassert>
|
||||
#include <ardour/types.h>
|
||||
#include <jack/jack.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
|
||||
/* Yes, this is a bit of a mess right now. I'll clean it up when everything
|
||||
* using it works out.. */
|
||||
|
||||
|
||||
/** A buffer of recordable/playable data.
|
||||
*
|
||||
* This is a datatype-agnostic base class for all buffers (there are no
|
||||
* methods to actually access the data). This provides a way for code that
|
||||
* doesn't care about the data type to still deal with buffers (which is
|
||||
* why the base class can't be a template).
|
||||
*
|
||||
* To actually read/write buffer contents, use the appropriate derived class.
|
||||
*/
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
Buffer(DataType type, size_t capacity)
|
||||
: _type(type), _capacity(capacity), _size(0)
|
||||
{}
|
||||
|
||||
virtual ~Buffer() {}
|
||||
|
||||
/** Maximum capacity of buffer.
|
||||
* Note in some cases the entire buffer may not contain valid data, use size. */
|
||||
size_t capacity() const { return _capacity; }
|
||||
|
||||
/** Amount of valid data in buffer. Use this over capacity almost always. */
|
||||
size_t size() const { return _size; }
|
||||
|
||||
/** Type of this buffer.
|
||||
* Based on this you can static cast a Buffer* to the desired type. */
|
||||
virtual DataType type() const { return _type; }
|
||||
|
||||
/** Jack type (eg JACK_DEFAULT_AUDIO_TYPE) */
|
||||
const char* jack_type() const { return type_to_jack_type(type()); }
|
||||
|
||||
/** String type as saved in session XML files (eg "audio" or "midi") */
|
||||
const char* type_string() const { return type_to_string(type()); }
|
||||
|
||||
/* The below static methods need to be separate from the above methods
|
||||
* because the conversion is needed in places where there's no Buffer.
|
||||
* These should probably live somewhere else...
|
||||
*/
|
||||
|
||||
static const char* type_to_jack_type(DataType t) {
|
||||
switch (t) {
|
||||
case AUDIO: return JACK_DEFAULT_AUDIO_TYPE;
|
||||
case MIDI: return JACK_DEFAULT_MIDI_TYPE;
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
static const char* type_to_string(DataType t) {
|
||||
switch (t) {
|
||||
case AUDIO: return "audio";
|
||||
case MIDI: return "midi";
|
||||
default: return "unknown"; // reeeally shouldn't ever happen
|
||||
}
|
||||
}
|
||||
|
||||
/** Used for loading from XML (route default types etc) */
|
||||
static DataType type_from_string(const string& str) {
|
||||
if (str == "audio")
|
||||
return AUDIO;
|
||||
else if (str == "midi")
|
||||
return MIDI;
|
||||
else
|
||||
return NIL;
|
||||
}
|
||||
|
||||
protected:
|
||||
DataType _type;
|
||||
size_t _capacity;
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
|
||||
/* Inside every class with a type in it's name is a template waiting to get out... */
|
||||
|
||||
|
||||
/** Buffer containing 32-bit floating point (audio) data. */
|
||||
class AudioBuffer : public Buffer
|
||||
{
|
||||
public:
|
||||
AudioBuffer(size_t capacity)
|
||||
: Buffer(AUDIO, capacity)
|
||||
, _data(NULL)
|
||||
{
|
||||
_size = capacity; // For audio buffers, size = capacity (always)
|
||||
#ifdef NO_POSIX_MEMALIGN
|
||||
b = (Sample *) malloc(sizeof(Sample) * capacity);
|
||||
#else
|
||||
posix_memalign((void**)_data, 16, sizeof(Sample) * capacity);
|
||||
#endif
|
||||
assert(_data);
|
||||
memset(_data, 0, sizeof(Sample) * capacity);
|
||||
}
|
||||
|
||||
const Sample* data() const { return _data; }
|
||||
Sample* data() { return _data; }
|
||||
|
||||
private:
|
||||
// These are undefined (prevent copies)
|
||||
AudioBuffer(const AudioBuffer& copy);
|
||||
AudioBuffer& operator=(const AudioBuffer& copy);
|
||||
|
||||
Sample* const _data; ///< Actual buffer contents
|
||||
};
|
||||
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif // __ardour_buffer_h__
|
||||
319
libs/ardour/ardour/diskstream.h
Normal file
319
libs/ardour/ardour/diskstream.h
Normal file
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
Copyright (C) 2000-2006 Paul Davis
|
||||
|
||||
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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: diskstream.h 579 2006-06-12 19:56:37Z essej $
|
||||
*/
|
||||
|
||||
#ifndef __ardour_diskstream_h__
|
||||
#define __ardour_diskstream_h__
|
||||
|
||||
#include <sigc++/signal.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <queue>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <pbd/fastlog.h>
|
||||
#include <pbd/ringbufferNPT.h>
|
||||
#include <pbd/stateful.h>
|
||||
|
||||
#include <ardour/ardour.h>
|
||||
#include <ardour/configuration.h>
|
||||
#include <ardour/session.h>
|
||||
#include <ardour/route_group.h>
|
||||
#include <ardour/route.h>
|
||||
#include <ardour/port.h>
|
||||
#include <ardour/utils.h>
|
||||
|
||||
|
||||
struct tm;
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class AudioEngine;
|
||||
class Send;
|
||||
class Session;
|
||||
class Playlist;
|
||||
class IO;
|
||||
|
||||
class Diskstream : public Stateful, public sigc::trackable
|
||||
{
|
||||
public:
|
||||
enum Flag {
|
||||
Recordable = 0x1,
|
||||
Hidden = 0x2,
|
||||
Destructive = 0x4
|
||||
};
|
||||
|
||||
string name () const { return _name; }
|
||||
virtual int set_name (string str);
|
||||
|
||||
ARDOUR::IO* io() const { return _io; }
|
||||
void set_io (ARDOUR::IO& io);
|
||||
|
||||
virtual Diskstream& ref() { _refcnt++; return *this; }
|
||||
void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; }
|
||||
uint32_t refcnt() const { return _refcnt; }
|
||||
|
||||
virtual float playback_buffer_load() const = 0;
|
||||
virtual float capture_buffer_load() const = 0;
|
||||
|
||||
void set_flag (Flag f) { _flags |= f; }
|
||||
void unset_flag (Flag f) { _flags &= ~f; }
|
||||
|
||||
AlignStyle alignment_style() const { return _alignment_style; }
|
||||
void set_align_style (AlignStyle);
|
||||
void set_persistent_align_style (AlignStyle a) { _persistent_alignment_style = a; }
|
||||
|
||||
jack_nframes_t roll_delay() const { return _roll_delay; }
|
||||
void set_roll_delay (jack_nframes_t);
|
||||
|
||||
bool record_enabled() const { return g_atomic_int_get (&_record_enabled); }
|
||||
virtual void set_record_enabled (bool yn) = 0;
|
||||
|
||||
bool destructive() const { return _flags & Destructive; }
|
||||
virtual void set_destructive (bool yn);
|
||||
|
||||
const PBD::ID& id() const { return _id; }
|
||||
bool hidden() const { return _flags & Hidden; }
|
||||
bool recordable() const { return _flags & Recordable; }
|
||||
bool reversed() const { return _actual_speed < 0.0f; }
|
||||
double speed() const { return _visible_speed; }
|
||||
|
||||
virtual void punch_in() {}
|
||||
virtual void punch_out() {}
|
||||
|
||||
void set_speed (double);
|
||||
void non_realtime_set_speed ();
|
||||
|
||||
Playlist* playlist () { return _playlist; }
|
||||
|
||||
virtual int use_playlist (Playlist *);
|
||||
virtual int use_new_playlist () = 0;
|
||||
virtual int use_copy_playlist () = 0;
|
||||
|
||||
jack_nframes_t current_capture_start() const { return capture_start_frame; }
|
||||
jack_nframes_t current_capture_end() const { return capture_start_frame + capture_captured; }
|
||||
jack_nframes_t get_capture_start_frame (uint32_t n=0);
|
||||
jack_nframes_t get_captured_frames (uint32_t n=0);
|
||||
|
||||
uint32_t n_channels() { return _n_channels; }
|
||||
|
||||
static jack_nframes_t disk_io_frames() { return disk_io_chunk_frames; }
|
||||
static void set_disk_io_chunk_frames (uint32_t n) { disk_io_chunk_frames = n; }
|
||||
|
||||
/* Stateful */
|
||||
virtual XMLNode& get_state(void) = 0;
|
||||
virtual int set_state(const XMLNode& node) = 0;
|
||||
|
||||
// FIXME: makes sense for all diskstream types?
|
||||
virtual void monitor_input (bool) {}
|
||||
|
||||
jack_nframes_t capture_offset() const { return _capture_offset; }
|
||||
virtual void set_capture_offset ();
|
||||
|
||||
bool slaved() const { return _slaved; }
|
||||
void set_slaved(bool yn) { _slaved = yn; }
|
||||
|
||||
int set_loop (Location *loc);
|
||||
|
||||
std::list<Region*>& last_capture_regions () { return _last_capture_regions; }
|
||||
|
||||
void handle_input_change (IOChange, void *src);
|
||||
|
||||
sigc::signal<void> RecordEnableChanged;
|
||||
sigc::signal<void> SpeedChanged;
|
||||
sigc::signal<void> ReverseChanged;
|
||||
sigc::signal<void> PlaylistChanged;
|
||||
sigc::signal<void> AlignmentStyleChanged;
|
||||
sigc::signal<void,Location *> LoopSet;
|
||||
|
||||
static sigc::signal<void> DiskOverrun;
|
||||
static sigc::signal<void> DiskUnderrun;
|
||||
static sigc::signal<void,Diskstream*> DiskstreamCreated; // XXX use a ref with sigc2
|
||||
static sigc::signal<void,list<Source*>*> DeleteSources;
|
||||
|
||||
protected:
|
||||
friend class Session;
|
||||
|
||||
Diskstream (Session &, const string& name, Flag f = Recordable);
|
||||
Diskstream (Session &, const XMLNode&);
|
||||
|
||||
/* the Session is the only point of access for these because they require
|
||||
* that the Session is "inactive" while they are called.
|
||||
*/
|
||||
|
||||
virtual void set_pending_overwrite (bool) = 0;
|
||||
virtual int overwrite_existing_buffers () = 0;
|
||||
virtual void set_block_size (jack_nframes_t) = 0;
|
||||
virtual int internal_playback_seek (jack_nframes_t distance) = 0;
|
||||
virtual int can_internal_playback_seek (jack_nframes_t distance) = 0;
|
||||
virtual int rename_write_sources () = 0;
|
||||
virtual void reset_write_sources (bool, bool force = false) = 0;
|
||||
virtual void non_realtime_input_change () = 0;
|
||||
|
||||
uint32_t read_data_count() const { return _read_data_count; }
|
||||
uint32_t write_data_count() const { return _write_data_count; }
|
||||
|
||||
protected:
|
||||
friend class Auditioner;
|
||||
virtual int seek (jack_nframes_t which_sample, bool complete_refill = false) = 0;
|
||||
|
||||
protected:
|
||||
friend class Track;
|
||||
|
||||
virtual void prepare ();
|
||||
virtual int process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input) = 0;
|
||||
virtual bool commit (jack_nframes_t nframes) = 0;
|
||||
virtual void recover (); /* called if commit will not be called, but process was */
|
||||
|
||||
//private:
|
||||
|
||||
/** Use unref() to destroy a diskstream */
|
||||
virtual ~Diskstream();
|
||||
|
||||
enum TransitionType {
|
||||
CaptureStart = 0,
|
||||
CaptureEnd
|
||||
};
|
||||
|
||||
struct CaptureTransition {
|
||||
TransitionType type;
|
||||
jack_nframes_t capture_val; ///< The start or end file frame position
|
||||
};
|
||||
|
||||
/* The two central butler operations */
|
||||
virtual int do_flush (Session::RunContext context, bool force = false) = 0;
|
||||
virtual int do_refill () = 0;
|
||||
|
||||
/** For non-butler contexts (allocates temporary working buffers) */
|
||||
virtual int do_refill_with_alloc() = 0;
|
||||
|
||||
|
||||
/* XXX fix this redundancy ... */
|
||||
|
||||
virtual void playlist_changed (Change);
|
||||
virtual void playlist_modified ();
|
||||
virtual void playlist_deleted (Playlist*);
|
||||
|
||||
virtual void finish_capture (bool rec_monitors_input) = 0;
|
||||
virtual void transport_stopped (struct tm&, time_t, bool abort) = 0;
|
||||
|
||||
struct CaptureInfo {
|
||||
uint32_t start;
|
||||
uint32_t frames;
|
||||
};
|
||||
|
||||
virtual void init (Flag);
|
||||
|
||||
virtual int use_new_write_source (uint32_t n=0) = 0;
|
||||
|
||||
virtual int find_and_use_playlist (const string&) = 0;
|
||||
|
||||
virtual void allocate_temporary_buffers () = 0;
|
||||
|
||||
virtual bool realtime_set_speed (double, bool global_change);
|
||||
|
||||
std::list<Region*> _last_capture_regions;
|
||||
virtual int use_pending_capture_data (XMLNode& node) = 0;
|
||||
|
||||
virtual void get_input_sources () = 0;
|
||||
virtual void check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record) = 0;
|
||||
virtual void set_align_style_from_io() {}
|
||||
virtual void setup_destructive_playlist () = 0;
|
||||
virtual void use_destructive_playlist () = 0;
|
||||
|
||||
static jack_nframes_t disk_io_chunk_frames;
|
||||
vector<CaptureInfo*> capture_info;
|
||||
Glib::Mutex capture_info_lock;
|
||||
|
||||
uint32_t i_am_the_modifier;
|
||||
|
||||
string _name;
|
||||
ARDOUR::Session& _session;
|
||||
ARDOUR::IO* _io;
|
||||
uint32_t _n_channels;
|
||||
PBD::ID _id;
|
||||
Playlist* _playlist;
|
||||
|
||||
mutable gint _record_enabled;
|
||||
double _visible_speed;
|
||||
double _actual_speed;
|
||||
/* items needed for speed change logic */
|
||||
bool _buffer_reallocation_required;
|
||||
bool _seek_required;
|
||||
|
||||
bool force_refill;
|
||||
jack_nframes_t capture_start_frame;
|
||||
jack_nframes_t capture_captured;
|
||||
bool was_recording;
|
||||
jack_nframes_t adjust_capture_position;
|
||||
jack_nframes_t _capture_offset;
|
||||
jack_nframes_t _roll_delay;
|
||||
jack_nframes_t first_recordable_frame;
|
||||
jack_nframes_t last_recordable_frame;
|
||||
int last_possibly_recording;
|
||||
AlignStyle _alignment_style;
|
||||
bool _scrubbing;
|
||||
bool _slaved;
|
||||
bool _processed;
|
||||
Location* loop_location;
|
||||
jack_nframes_t overwrite_frame;
|
||||
off_t overwrite_offset;
|
||||
bool pending_overwrite;
|
||||
bool overwrite_queued;
|
||||
IOChange input_change_pending;
|
||||
jack_nframes_t wrap_buffer_size;
|
||||
jack_nframes_t speed_buffer_size;
|
||||
|
||||
uint64_t last_phase;
|
||||
uint64_t phi;
|
||||
|
||||
jack_nframes_t file_frame;
|
||||
jack_nframes_t playback_sample;
|
||||
jack_nframes_t playback_distance;
|
||||
|
||||
uint32_t _read_data_count;
|
||||
uint32_t _write_data_count;
|
||||
|
||||
bool in_set_state;
|
||||
AlignStyle _persistent_alignment_style;
|
||||
bool first_input_change;
|
||||
|
||||
Glib::Mutex state_lock;
|
||||
|
||||
jack_nframes_t scrub_start;
|
||||
jack_nframes_t scrub_buffer_size;
|
||||
jack_nframes_t scrub_offset;
|
||||
|
||||
uint32_t _refcnt;
|
||||
|
||||
sigc::connection ports_created_c;
|
||||
sigc::connection plmod_connection;
|
||||
sigc::connection plstate_connection;
|
||||
sigc::connection plgone_connection;
|
||||
|
||||
unsigned char _flags;
|
||||
};
|
||||
|
||||
}; /* namespace ARDOUR */
|
||||
|
||||
#endif /* __ardour_diskstream_h__ */
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <ardour/utils.h>
|
||||
#include <ardour/state_manager.h>
|
||||
#include <ardour/curve.h>
|
||||
#include <ardour/types.h>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
@@ -52,6 +53,11 @@ class Port;
|
||||
class Connection;
|
||||
class Panner;
|
||||
|
||||
/** A collection of input and output ports with connections.
|
||||
*
|
||||
* An IO can contain ports of varying types, making routes/inserts/etc with
|
||||
* varied combinations of types (eg MIDI and audio) possible.
|
||||
*/
|
||||
class IO : public Stateful, public ARDOUR::StateManager
|
||||
{
|
||||
|
||||
@@ -60,7 +66,8 @@ class IO : public Stateful, public ARDOUR::StateManager
|
||||
|
||||
IO (Session&, string name,
|
||||
int input_min = -1, int input_max = -1,
|
||||
int output_min = -1, int output_max = -1);
|
||||
int output_min = -1, int output_max = -1,
|
||||
DataType default_type = AUDIO);
|
||||
|
||||
virtual ~IO();
|
||||
|
||||
@@ -74,25 +81,29 @@ class IO : public Stateful, public ARDOUR::StateManager
|
||||
void set_output_minimum (int n);
|
||||
void set_output_maximum (int n);
|
||||
|
||||
DataType default_type() const { return _default_type; }
|
||||
|
||||
const string& name() const { return _name; }
|
||||
virtual int set_name (string str, void *src);
|
||||
|
||||
virtual void silence (jack_nframes_t, jack_nframes_t offset);
|
||||
|
||||
// These should be moved in to a separate object that manipulates an IO
|
||||
|
||||
void pan (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset, gain_t gain_coeff);
|
||||
void pan_automated (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
jack_nframes_t nframes, jack_nframes_t offset);
|
||||
void collect_input (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
|
||||
void deliver_output (vector<Sample *>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
|
||||
void deliver_output_no_pan (vector<Sample *>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
|
||||
void deliver_output (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
|
||||
void deliver_output_no_pan (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
|
||||
void just_meter_input (jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
jack_nframes_t nframes, jack_nframes_t offset);
|
||||
|
||||
virtual uint32_t n_process_buffers () { return 0; }
|
||||
|
||||
virtual void set_gain (gain_t g, void *src);
|
||||
void inc_gain (gain_t delta, void *src);
|
||||
gain_t gain () const { return _desired_gain; }
|
||||
void inc_gain (gain_t delta, void *src);
|
||||
gain_t gain () const { return _desired_gain; }
|
||||
virtual gain_t effective_gain () const;
|
||||
|
||||
Panner& panner() { return *_panner; }
|
||||
@@ -105,8 +116,8 @@ class IO : public Stateful, public ARDOUR::StateManager
|
||||
Connection *input_connection() const { return _input_connection; }
|
||||
Connection *output_connection() const { return _output_connection; }
|
||||
|
||||
int add_input_port (string source, void *src);
|
||||
int add_output_port (string destination, void *src);
|
||||
int add_input_port (string source, void *src, DataType type = NIL);
|
||||
int add_output_port (string destination, void *src, DataType type = NIL);
|
||||
|
||||
int remove_input_port (Port *, void *src);
|
||||
int remove_output_port (Port *, void *src);
|
||||
@@ -273,6 +284,7 @@ public:
|
||||
PBD::ID _id;
|
||||
bool no_panner_reset;
|
||||
XMLNode* deferred_state;
|
||||
DataType _default_type;
|
||||
|
||||
virtual void set_deferred_state() {}
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ class Playlist : public Stateful, public StateManager {
|
||||
Playlist (const Playlist&, string name, bool hidden = false);
|
||||
Playlist (const Playlist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false);
|
||||
|
||||
virtual jack_nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, char * workbuf, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0) = 0;
|
||||
virtual void clear (bool with_delete = false, bool with_save = true);
|
||||
virtual void dump () const;
|
||||
virtual UndoAction get_memento() const = 0;
|
||||
@@ -81,6 +80,8 @@ class Playlist : public Stateful, public StateManager {
|
||||
|
||||
void add_region (const Region&, jack_nframes_t position, float times = 1, bool with_save = true);
|
||||
void remove_region (Region *);
|
||||
void get_equivalent_regions (const Region&, std::vector<Region*>&);
|
||||
void get_region_list_equivalent_regions (const Region&, std::vector<Region*>&);
|
||||
void replace_region (Region& old, Region& newr, jack_nframes_t pos);
|
||||
void split_region (Region&, jack_nframes_t position);
|
||||
void partition (jack_nframes_t start, jack_nframes_t end, bool just_top_level);
|
||||
@@ -108,16 +109,15 @@ class Playlist : public Stateful, public StateManager {
|
||||
int set_state (const XMLNode&);
|
||||
XMLNode& get_template ();
|
||||
|
||||
sigc::signal<void,Region *> RegionAdded;
|
||||
sigc::signal<void,Region *> RegionRemoved;
|
||||
|
||||
sigc::signal<void,Region *> RegionAdded;
|
||||
sigc::signal<void,Region *> RegionRemoved;
|
||||
sigc::signal<void,Playlist*,bool> InUse;
|
||||
sigc::signal<void> Modified;
|
||||
sigc::signal<void> NameChanged;
|
||||
sigc::signal<void> LengthChanged;
|
||||
sigc::signal<void> LayeringChanged;
|
||||
sigc::signal<void,Playlist *> GoingAway;
|
||||
sigc::signal<void> StatePushed;
|
||||
sigc::signal<void> Modified;
|
||||
sigc::signal<void> NameChanged;
|
||||
sigc::signal<void> LengthChanged;
|
||||
sigc::signal<void> LayeringChanged;
|
||||
sigc::signal<void,Playlist *> GoingAway;
|
||||
sigc::signal<void> StatePushed;
|
||||
|
||||
static sigc::signal<void,Playlist*> PlaylistCreated;
|
||||
|
||||
|
||||
@@ -33,24 +33,24 @@ class AudioEngine;
|
||||
class Port : public sigc::trackable {
|
||||
public:
|
||||
virtual ~Port() {
|
||||
free (port);
|
||||
free (_port);
|
||||
}
|
||||
|
||||
Sample *get_buffer (jack_nframes_t nframes) {
|
||||
if (_flags & JackPortIsOutput) {
|
||||
return _buffer;
|
||||
} else {
|
||||
return (Sample *) jack_port_get_buffer (port, nframes);
|
||||
return (Sample *) jack_port_get_buffer (_port, nframes);
|
||||
}
|
||||
}
|
||||
|
||||
void reset_buffer () {
|
||||
if (_flags & JackPortIsOutput) {
|
||||
_buffer = (Sample *) jack_port_get_buffer (port, 0);
|
||||
_buffer = (Sample *) jack_port_get_buffer (_port, 0);
|
||||
} else {
|
||||
_buffer = 0; /* catch illegal attempts to use it */
|
||||
}
|
||||
silent = false;
|
||||
_silent = false;
|
||||
}
|
||||
|
||||
std::string name() {
|
||||
@@ -58,7 +58,7 @@ class Port : public sigc::trackable {
|
||||
}
|
||||
|
||||
std::string short_name() {
|
||||
return jack_port_short_name (port);
|
||||
return jack_port_short_name (_port);
|
||||
}
|
||||
|
||||
int set_name (std::string str);
|
||||
@@ -68,7 +68,7 @@ class Port : public sigc::trackable {
|
||||
}
|
||||
|
||||
bool is_mine (jack_client_t *client) {
|
||||
return jack_port_is_mine (client, port);
|
||||
return jack_port_is_mine (client, _port);
|
||||
}
|
||||
|
||||
const char* type() const {
|
||||
@@ -76,21 +76,21 @@ class Port : public sigc::trackable {
|
||||
}
|
||||
|
||||
int connected () const {
|
||||
return jack_port_connected (port);
|
||||
return jack_port_connected (_port);
|
||||
}
|
||||
|
||||
bool connected_to (const std::string& portname) const {
|
||||
return jack_port_connected_to (port, portname.c_str());
|
||||
return jack_port_connected_to (_port, portname.c_str());
|
||||
}
|
||||
|
||||
const char ** get_connections () const {
|
||||
return jack_port_get_connections (port);
|
||||
return jack_port_get_connections (_port);
|
||||
}
|
||||
|
||||
void reset_overs () {
|
||||
_short_overs = 0;
|
||||
_long_overs = 0;
|
||||
overlen = 0;
|
||||
_overlen = 0;
|
||||
}
|
||||
|
||||
void reset_peak_meter () {
|
||||
@@ -103,18 +103,18 @@ class Port : public sigc::trackable {
|
||||
}
|
||||
|
||||
void enable_metering() {
|
||||
metering++;
|
||||
_metering++;
|
||||
}
|
||||
|
||||
void disable_metering () {
|
||||
if (metering) { metering--; }
|
||||
if (_metering) { _metering--; }
|
||||
}
|
||||
|
||||
float peak_db() const { return _peak_db; }
|
||||
float peak_db() const { return _peak_db; }
|
||||
jack_default_audio_sample_t peak() const { return _peak; }
|
||||
|
||||
uint32_t short_overs () const { return _short_overs; }
|
||||
uint32_t long_overs () const { return _long_overs; }
|
||||
uint32_t long_overs () const { return _long_overs; }
|
||||
|
||||
static void set_short_over_length (jack_nframes_t);
|
||||
static void set_long_over_length (jack_nframes_t);
|
||||
@@ -128,7 +128,7 @@ class Port : public sigc::trackable {
|
||||
}
|
||||
|
||||
bool monitoring_input () const {
|
||||
return jack_port_monitoring_input (port);
|
||||
return jack_port_monitoring_input (_port);
|
||||
}
|
||||
|
||||
bool can_monitor () const {
|
||||
@@ -136,30 +136,29 @@ class Port : public sigc::trackable {
|
||||
}
|
||||
|
||||
void ensure_monitor_input (bool yn) {
|
||||
jack_port_request_monitor (port, yn);
|
||||
jack_port_request_monitor (_port, yn);
|
||||
}
|
||||
|
||||
void request_monitor_input (bool yn) {
|
||||
jack_port_request_monitor (port, yn);
|
||||
jack_port_request_monitor (_port, yn);
|
||||
}
|
||||
|
||||
jack_nframes_t latency () const {
|
||||
return jack_port_get_latency (port);
|
||||
return jack_port_get_latency (_port);
|
||||
}
|
||||
|
||||
void set_latency (jack_nframes_t nframes) {
|
||||
jack_port_set_latency (port, nframes);
|
||||
jack_port_set_latency (_port, nframes);
|
||||
}
|
||||
|
||||
sigc::signal<void,bool> MonitorInputChanged;
|
||||
sigc::signal<void,bool> ClockSyncChanged;
|
||||
|
||||
bool is_silent() const { return silent; }
|
||||
bool is_silent() const { return _silent; }
|
||||
|
||||
/** Assumes that the port is an audio output port */
|
||||
void silence (jack_nframes_t nframes, jack_nframes_t offset) {
|
||||
/* assumes that the port is an output port */
|
||||
|
||||
if (!silent) {
|
||||
if (!_silent) {
|
||||
memset (_buffer + offset, 0, sizeof (Sample) * nframes);
|
||||
if (offset == 0) {
|
||||
/* XXX this isn't really true, but i am not sure
|
||||
@@ -167,13 +166,13 @@ class Port : public sigc::trackable {
|
||||
want to set it true when the entire port
|
||||
buffer has been overrwritten.
|
||||
*/
|
||||
silent = true;
|
||||
_silent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mark_silence (bool yn) {
|
||||
silent = yn;
|
||||
_silent = yn;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -184,7 +183,7 @@ class Port : public sigc::trackable {
|
||||
|
||||
/* engine isn't supposed to below here */
|
||||
|
||||
Sample *_buffer;
|
||||
Sample *_buffer;
|
||||
|
||||
/* cache these 3 from JACK so that we can
|
||||
access them for reconnecting.
|
||||
@@ -194,18 +193,18 @@ class Port : public sigc::trackable {
|
||||
std::string _type;
|
||||
std::string _name;
|
||||
|
||||
bool last_monitor : 1;
|
||||
bool silent : 1;
|
||||
jack_port_t *port;
|
||||
jack_nframes_t overlen;
|
||||
jack_default_audio_sample_t _peak;
|
||||
float _peak_db;
|
||||
uint32_t _short_overs;
|
||||
uint32_t _long_overs;
|
||||
unsigned short metering;
|
||||
bool _last_monitor : 1;
|
||||
bool _silent : 1;
|
||||
jack_port_t *_port;
|
||||
jack_nframes_t _overlen;
|
||||
jack_default_audio_sample_t _peak;
|
||||
float _peak_db;
|
||||
uint32_t _short_overs;
|
||||
uint32_t _long_overs;
|
||||
unsigned short _metering;
|
||||
|
||||
static jack_nframes_t long_over_length;
|
||||
static jack_nframes_t short_over_length;
|
||||
static jack_nframes_t _long_over_length;
|
||||
static jack_nframes_t _short_over_length;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <pbd/undo.h>
|
||||
|
||||
#include <ardour/ardour.h>
|
||||
#include <ardour/logcurve.h>
|
||||
#include <ardour/state_manager.h>
|
||||
|
||||
class XMLNode;
|
||||
@@ -36,22 +35,22 @@ class Source;
|
||||
|
||||
enum RegionEditState {
|
||||
EditChangesNothing = 0,
|
||||
EditChangesName = 1,
|
||||
EditChangesID = 2
|
||||
EditChangesName = 1,
|
||||
EditChangesID = 2
|
||||
};
|
||||
|
||||
struct RegionState : public StateManager::State {
|
||||
struct RegionState : public StateManager::State
|
||||
{
|
||||
RegionState (std::string why) : StateManager::State (why) {}
|
||||
|
||||
RegionState (std::string why) : StateManager::State (why) {}
|
||||
|
||||
jack_nframes_t _start;
|
||||
jack_nframes_t _length;
|
||||
jack_nframes_t _position;
|
||||
uint32_t _flags;
|
||||
jack_nframes_t _sync_position;
|
||||
layer_t _layer;
|
||||
string _name;
|
||||
mutable RegionEditState _first_edit;
|
||||
jack_nframes_t _start;
|
||||
jack_nframes_t _length;
|
||||
jack_nframes_t _position;
|
||||
uint32_t _flags;
|
||||
jack_nframes_t _sync_position;
|
||||
layer_t _layer;
|
||||
string _name;
|
||||
mutable RegionEditState _first_edit;
|
||||
};
|
||||
|
||||
class Region : public Stateful, public StateManager
|
||||
@@ -95,7 +94,7 @@ class Region : public Stateful, public StateManager
|
||||
Region (const Region&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags);
|
||||
Region (const Region&);
|
||||
Region (const XMLNode&);
|
||||
~Region();
|
||||
virtual ~Region();
|
||||
|
||||
const PBD::ID& id() const { return _id; }
|
||||
|
||||
@@ -105,9 +104,10 @@ class Region : public Stateful, public StateManager
|
||||
void set_name (string str);
|
||||
|
||||
jack_nframes_t position () const { return _position; }
|
||||
jack_nframes_t start () const { return _start; }
|
||||
jack_nframes_t length() const { return _length; }
|
||||
layer_t layer () const { return _layer; }
|
||||
jack_nframes_t start () const { return _start; }
|
||||
jack_nframes_t length() const { return _length; }
|
||||
layer_t layer () const { return _layer; }
|
||||
|
||||
jack_nframes_t sync_offset(int& dir) const;
|
||||
jack_nframes_t sync_position() const;
|
||||
|
||||
@@ -118,14 +118,13 @@ class Region : public Stateful, public StateManager
|
||||
jack_nframes_t first_frame() const { return _position; }
|
||||
jack_nframes_t last_frame() const { return _position + _length - 1; }
|
||||
|
||||
bool hidden() const { return _flags & Hidden; }
|
||||
bool muted() const { return _flags & Muted; }
|
||||
bool opaque () const { return _flags & Opaque; }
|
||||
bool envelope_active () const { return _flags & EnvelopeActive; }
|
||||
bool locked() const { return _flags & Locked; }
|
||||
bool automatic() const { return _flags & Automatic; }
|
||||
bool hidden() const { return _flags & Hidden; }
|
||||
bool muted() const { return _flags & Muted; }
|
||||
bool opaque () const { return _flags & Opaque; }
|
||||
bool locked() const { return _flags & Locked; }
|
||||
bool automatic() const { return _flags & Automatic; }
|
||||
bool whole_file() const { return _flags & WholeFile ; }
|
||||
Flag flags() const { return _flags; }
|
||||
Flag flags() const { return _flags; }
|
||||
|
||||
virtual bool should_save_state () const { return !(_flags & DoNotSaveState); };
|
||||
|
||||
@@ -139,12 +138,14 @@ class Region : public Stateful, public StateManager
|
||||
OverlapType coverage (jack_nframes_t start, jack_nframes_t end) const {
|
||||
return ARDOUR::coverage (_position, _position + _length - 1, start, end);
|
||||
}
|
||||
|
||||
virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
|
||||
float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt,
|
||||
uint32_t chan_n = 0,
|
||||
jack_nframes_t read_frames = 0,
|
||||
jack_nframes_t skip_frames = 0) const = 0;
|
||||
|
||||
bool equivalent (const Region&) const;
|
||||
bool size_equivalent (const Region&) const;
|
||||
bool overlap_equivalent (const Region&) const;
|
||||
bool region_list_equivalent (const Region&) const;
|
||||
virtual bool source_equivalent (const Region&) const = 0;
|
||||
|
||||
virtual bool speed_mismatch (float) const = 0;
|
||||
|
||||
/* EDITING OPERATIONS */
|
||||
|
||||
@@ -173,7 +174,6 @@ class Region : public Stateful, public StateManager
|
||||
void set_hidden (bool yn);
|
||||
void set_muted (bool yn);
|
||||
void set_opaque (bool yn);
|
||||
void set_envelope_active (bool yn);
|
||||
void set_locked (bool yn);
|
||||
|
||||
virtual uint32_t read_data_count() const { return _read_data_count; }
|
||||
@@ -189,9 +189,9 @@ class Region : public Stateful, public StateManager
|
||||
|
||||
/* serialization */
|
||||
|
||||
XMLNode& get_state ();
|
||||
virtual XMLNode& state (bool);
|
||||
XMLNode& get_state ();
|
||||
int set_state (const XMLNode&);
|
||||
virtual int set_state (const XMLNode&);
|
||||
|
||||
sigc::signal<void,Region*> GoingAway;
|
||||
|
||||
@@ -211,23 +211,6 @@ class Region : public Stateful, public StateManager
|
||||
void set_last_layer_op (uint64_t when);
|
||||
|
||||
protected:
|
||||
|
||||
jack_nframes_t _start;
|
||||
jack_nframes_t _length;
|
||||
jack_nframes_t _position;
|
||||
Flag _flags;
|
||||
jack_nframes_t _sync_position;
|
||||
layer_t _layer;
|
||||
string _name;
|
||||
mutable RegionEditState _first_edit;
|
||||
int _frozen;
|
||||
Glib::Mutex lock;
|
||||
PBD::ID _id;
|
||||
ARDOUR::Playlist* _playlist;
|
||||
mutable uint32_t _read_data_count; // modified in read()
|
||||
Change pending_changed;
|
||||
uint64_t _last_layer_op; // timestamp
|
||||
|
||||
XMLNode& get_short_state (); /* used only by Session */
|
||||
|
||||
/* state management */
|
||||
@@ -251,6 +234,23 @@ class Region : public Stateful, public StateManager
|
||||
virtual bool verify_length (jack_nframes_t) = 0;
|
||||
virtual void recompute_at_start () = 0;
|
||||
virtual void recompute_at_end () = 0;
|
||||
|
||||
|
||||
jack_nframes_t _start;
|
||||
jack_nframes_t _length;
|
||||
jack_nframes_t _position;
|
||||
Flag _flags;
|
||||
jack_nframes_t _sync_position;
|
||||
layer_t _layer;
|
||||
string _name;
|
||||
mutable RegionEditState _first_edit;
|
||||
int _frozen;
|
||||
Glib::Mutex lock;
|
||||
PBD::ID _id;
|
||||
ARDOUR::Playlist* _playlist;
|
||||
mutable uint32_t _read_data_count; // modified in read()
|
||||
Change pending_changed;
|
||||
uint64_t _last_layer_op; // timestamp
|
||||
};
|
||||
|
||||
} /* namespace ARDOUR */
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <ardour/io.h>
|
||||
#include <ardour/session.h>
|
||||
#include <ardour/redirect.h>
|
||||
#include <ardour/types.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
@@ -68,7 +69,9 @@ class Route : public IO
|
||||
};
|
||||
|
||||
|
||||
Route (Session&, std::string name, int input_min, int input_max, int output_min, int output_max, Flag flags = Flag(0));
|
||||
Route (Session&, std::string name, int input_min, int input_max, int output_min, int output_max,
|
||||
Flag flags = Flag(0), DataType default_type = AUDIO);
|
||||
|
||||
Route (Session&, const XMLNode&);
|
||||
virtual ~Route();
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ using std::list;
|
||||
namespace ARDOUR {
|
||||
|
||||
class Route;
|
||||
class Track;
|
||||
class AudioTrack;
|
||||
class Session;
|
||||
|
||||
@@ -90,7 +91,7 @@ class RouteGroup : public Stateful, public sigc::trackable {
|
||||
|
||||
/* to use these, #include <ardour/route_group_specialized.h> */
|
||||
|
||||
template<class T> void apply (void (AudioTrack::*func)(T, void *), T val, void *src);
|
||||
template<class T> void apply (void (Track::*func)(T, void *), T val, void *src);
|
||||
|
||||
/* fills at_set with all members of the group that are AudioTracks */
|
||||
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
namespace ARDOUR {
|
||||
|
||||
template<class T> void
|
||||
RouteGroup::apply (void (AudioTrack::*func)(T, void *), T val, void *src)
|
||||
RouteGroup::apply (void (Track::*func)(T, void *), T val, void *src)
|
||||
{
|
||||
for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) {
|
||||
AudioTrack *at;
|
||||
if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
|
||||
Track *at;
|
||||
if ((at = dynamic_cast<Track*>(*i)) != 0) {
|
||||
(at->*func)(val, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ namespace ARDOUR {
|
||||
class Port;
|
||||
class AudioEngine;
|
||||
class Slave;
|
||||
class Diskstream;
|
||||
class AudioDiskstream;
|
||||
class Route;
|
||||
class AuxInput;
|
||||
@@ -157,17 +158,17 @@ class Session : public sigc::trackable, public Stateful
|
||||
Clear
|
||||
};
|
||||
|
||||
Type type;
|
||||
Action action;
|
||||
jack_nframes_t action_frame;
|
||||
jack_nframes_t target_frame;
|
||||
float speed;
|
||||
Type type;
|
||||
Action action;
|
||||
jack_nframes_t action_frame;
|
||||
jack_nframes_t target_frame;
|
||||
float speed;
|
||||
|
||||
union {
|
||||
void* ptr;
|
||||
bool yes_or_no;
|
||||
Session::SlaveSource slave;
|
||||
Route* route;
|
||||
void* ptr;
|
||||
bool yes_or_no;
|
||||
Session::SlaveSource slave;
|
||||
Route* route;
|
||||
};
|
||||
|
||||
list<AudioRange> audio_range;
|
||||
@@ -269,30 +270,18 @@ class Session : public sigc::trackable, public Stateful
|
||||
vector<Sample*>& get_silent_buffers (uint32_t howmany);
|
||||
vector<Sample*>& get_send_buffers () { return _send_buffers; }
|
||||
|
||||
AudioDiskstream *diskstream_by_id (const PBD::ID& id);
|
||||
AudioDiskstream *diskstream_by_name (string name);
|
||||
Diskstream* diskstream_by_id (const PBD::ID& id);
|
||||
Diskstream* diskstream_by_name (string name);
|
||||
|
||||
bool have_captured() const { return _have_captured; }
|
||||
|
||||
void refill_all_diskstream_buffers ();
|
||||
uint32_t diskstream_buffer_size() const { return dstream_buffer_size; }
|
||||
|
||||
/* XXX fix required here when we get new diskstream types *, but
|
||||
not sure of the direction to take this in until then.
|
||||
*/
|
||||
|
||||
uint32_t get_next_diskstream_id() const { return n_audio_diskstreams(); }
|
||||
uint32_t n_audio_diskstreams() const;
|
||||
uint32_t get_next_diskstream_id() const { return n_diskstreams(); }
|
||||
uint32_t n_diskstreams() const;
|
||||
|
||||
typedef list<AudioDiskstream *> AudioDiskstreamList;
|
||||
|
||||
Session::AudioDiskstreamList audio_disk_streams() const {
|
||||
Glib::RWLock::ReaderLock lm (diskstream_lock);
|
||||
return audio_diskstreams; /* XXX yes, force a copy */
|
||||
}
|
||||
|
||||
void foreach_audio_diskstream (void (AudioDiskstream::*func)(void));
|
||||
template<class T> void foreach_audio_diskstream (T *obj, void (T::*func)(AudioDiskstream&));
|
||||
typedef list<Diskstream *> DiskstreamList;
|
||||
|
||||
typedef std::list<boost::shared_ptr<Route> > RouteList;
|
||||
|
||||
@@ -356,7 +345,7 @@ class Session : public sigc::trackable, public Stateful
|
||||
sigc::signal<void> HaltOnXrun;
|
||||
|
||||
sigc::signal<void,boost::shared_ptr<Route> > RouteAdded;
|
||||
sigc::signal<void,AudioDiskstream*> AudioDiskstreamAdded;
|
||||
sigc::signal<void,Diskstream*> DiskstreamAdded; // FIXME: make a shared_ptr
|
||||
|
||||
void request_roll ();
|
||||
void request_bounded_roll (jack_nframes_t start, jack_nframes_t end);
|
||||
@@ -368,15 +357,14 @@ class Session : public sigc::trackable, public Stateful
|
||||
void goto_start () { request_locate (start_location->start(), false); }
|
||||
void use_rf_shuttle_speed ();
|
||||
void request_transport_speed (float speed);
|
||||
void request_overwrite_buffer (AudioDiskstream*);
|
||||
void request_diskstream_speed (AudioDiskstream&, float speed);
|
||||
void request_overwrite_buffer (Diskstream*);
|
||||
void request_diskstream_speed (Diskstream&, float speed);
|
||||
void request_input_change_handling ();
|
||||
|
||||
bool locate_pending() const { return static_cast<bool>(post_transport_work&PostTransportLocate); }
|
||||
bool transport_locked () const;
|
||||
|
||||
int wipe ();
|
||||
int wipe_diskstream (AudioDiskstream *);
|
||||
|
||||
int remove_region_from_region_list (Region&);
|
||||
|
||||
@@ -553,9 +541,6 @@ class Session : public sigc::trackable, public Stateful
|
||||
|
||||
void resort_routes ();
|
||||
void resort_routes_using (boost::shared_ptr<RouteList>);
|
||||
void resort_routes_proxy (void* src) {
|
||||
resort_routes ();
|
||||
}
|
||||
|
||||
AudioEngine &engine() { return _engine; };
|
||||
|
||||
@@ -636,7 +621,7 @@ class Session : public sigc::trackable, public Stateful
|
||||
string path_from_region_name (string name, string identifier);
|
||||
|
||||
AudioRegion* find_whole_file_parent (AudioRegion&);
|
||||
void find_equivalent_playlist_regions (AudioRegion&, std::vector<AudioRegion*>& result);
|
||||
void find_equivalent_playlist_regions (Region&, std::vector<Region*>& result);
|
||||
|
||||
AudioRegion *XMLRegionFactory (const XMLNode&, bool full);
|
||||
|
||||
@@ -713,8 +698,6 @@ class Session : public sigc::trackable, public Stateful
|
||||
sigc::signal<void,Playlist*> PlaylistAdded;
|
||||
sigc::signal<void,Playlist*> PlaylistRemoved;
|
||||
|
||||
Playlist *get_playlist (string name);
|
||||
|
||||
uint32_t n_playlists() const;
|
||||
|
||||
template<class T> void foreach_playlist (T *obj, void (T::*func)(Playlist *));
|
||||
@@ -739,7 +722,7 @@ class Session : public sigc::trackable, public Stateful
|
||||
|
||||
boost::shared_ptr<Auditioner> the_auditioner() { return auditioner; }
|
||||
void audition_playlist ();
|
||||
void audition_region (AudioRegion&);
|
||||
void audition_region (Region&);
|
||||
void cancel_audition ();
|
||||
bool is_auditioning () const;
|
||||
|
||||
@@ -980,7 +963,7 @@ class Session : public sigc::trackable, public Stateful
|
||||
void set_frame_rate (jack_nframes_t nframes);
|
||||
|
||||
protected:
|
||||
friend class AudioDiskstream;
|
||||
friend class Diskstream;
|
||||
void stop_butler ();
|
||||
void wait_till_butler_finished();
|
||||
|
||||
@@ -1442,12 +1425,12 @@ class Session : public sigc::trackable, public Stateful
|
||||
bool waiting_to_start;
|
||||
|
||||
void set_auto_loop (bool yn);
|
||||
void overwrite_some_buffers (AudioDiskstream*);
|
||||
void overwrite_some_buffers (Diskstream*);
|
||||
void flush_all_redirects ();
|
||||
void locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
|
||||
void start_locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
|
||||
void force_locate (jack_nframes_t frame, bool with_roll = false);
|
||||
void set_diskstream_speed (AudioDiskstream*, float speed);
|
||||
void set_diskstream_speed (Diskstream*, float speed);
|
||||
void set_transport_speed (float speed, bool abort = false);
|
||||
void stop_transport (bool abort = false);
|
||||
void start_transport ();
|
||||
@@ -1478,10 +1461,10 @@ class Session : public sigc::trackable, public Stateful
|
||||
|
||||
/* disk-streams */
|
||||
|
||||
AudioDiskstreamList audio_diskstreams;
|
||||
DiskstreamList diskstreams;
|
||||
mutable Glib::RWLock diskstream_lock;
|
||||
uint32_t dstream_buffer_size;
|
||||
void add_diskstream (AudioDiskstream*);
|
||||
void add_diskstream (Diskstream*);
|
||||
int load_diskstreams (const XMLNode&);
|
||||
|
||||
/* routes stuff */
|
||||
@@ -1549,7 +1532,7 @@ class Session : public sigc::trackable, public Stateful
|
||||
Playlist *XMLPlaylistFactory (const XMLNode&);
|
||||
|
||||
void playlist_length_changed (Playlist *);
|
||||
void diskstream_playlist_changed (AudioDiskstream *);
|
||||
void diskstream_playlist_changed (Diskstream *);
|
||||
|
||||
/* NAMED SELECTIONS */
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2002 Paul Davis
|
||||
|
||||
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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef __ardour_session_diskstream_h__
|
||||
#define __ardour_session_diskstream_h__
|
||||
|
||||
#include <ardour/session.h>
|
||||
#include <ardour/audio_diskstream.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
template<class T> void
|
||||
Session::foreach_audio_diskstream (T *obj, void (T::*func)(AudioDiskstream&))
|
||||
{
|
||||
Glib::RWLock::ReaderLock lm (diskstream_lock);
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); i++) {
|
||||
if (!(*i)->hidden()) {
|
||||
(obj->*func) (**i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
#endif /* __ardour_session_diskstream_h__ */
|
||||
158
libs/ardour/ardour/track.h
Normal file
158
libs/ardour/ardour/track.h
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
Copyright (C) 2006 Paul Davis
|
||||
|
||||
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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ardour_track_h__
|
||||
#define __ardour_track_h__
|
||||
|
||||
#include <ardour/route.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class Session;
|
||||
class Diskstream;
|
||||
class Playlist;
|
||||
class RouteGroup;
|
||||
|
||||
class Track : public Route
|
||||
{
|
||||
public:
|
||||
Track (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal, DataType default_type = AUDIO);
|
||||
|
||||
virtual ~Track ();
|
||||
|
||||
int set_name (string str, void *src);
|
||||
|
||||
virtual int roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
jack_nframes_t offset, int declick, bool can_record, bool rec_monitors_input) = 0;
|
||||
|
||||
virtual int no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
jack_nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input) = 0;
|
||||
|
||||
virtual int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
jack_nframes_t offset, bool can_record, bool rec_monitors_input) = 0;
|
||||
|
||||
void toggle_monitor_input ();
|
||||
|
||||
bool can_record() const { return true; }
|
||||
|
||||
Diskstream& diskstream() const { return *_diskstream; }
|
||||
|
||||
virtual int use_diskstream (string name) = 0;
|
||||
virtual int use_diskstream (const PBD::ID& id) = 0;
|
||||
|
||||
TrackMode mode() const { return _mode; }
|
||||
void set_mode (TrackMode m);
|
||||
|
||||
jack_nframes_t update_total_latency();
|
||||
void set_latency_delay (jack_nframes_t);
|
||||
|
||||
enum FreezeState {
|
||||
NoFreeze,
|
||||
Frozen,
|
||||
UnFrozen
|
||||
};
|
||||
|
||||
FreezeState freeze_state() const;
|
||||
|
||||
virtual void freeze (InterThreadInfo&) = 0;
|
||||
virtual void unfreeze () = 0;
|
||||
|
||||
virtual void bounce (InterThreadInfo&) = 0;
|
||||
virtual void bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo&) = 0;
|
||||
|
||||
XMLNode& get_state();
|
||||
XMLNode& get_template();
|
||||
virtual int set_state(const XMLNode& node) = 0;
|
||||
|
||||
PBD::Controllable& rec_enable_control() { return _rec_enable_control; }
|
||||
|
||||
bool record_enabled() const;
|
||||
void set_record_enable (bool yn, void *src);
|
||||
|
||||
void set_meter_point (MeterPoint, void* src);
|
||||
|
||||
sigc::signal<void> ModeChanged;
|
||||
sigc::signal<void> DiskstreamChanged;
|
||||
sigc::signal<void> FreezeChange;
|
||||
|
||||
protected:
|
||||
Track (Session& sess, const XMLNode& node, DataType default_type = AUDIO);
|
||||
|
||||
virtual XMLNode& state (bool full) = 0;
|
||||
|
||||
virtual void passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter) = 0;
|
||||
|
||||
virtual uint32_t n_process_buffers () = 0;
|
||||
|
||||
Diskstream *_diskstream;
|
||||
MeterPoint _saved_meter_point;
|
||||
TrackMode _mode;
|
||||
|
||||
//private: (FIXME)
|
||||
struct FreezeRecordInsertInfo {
|
||||
FreezeRecordInsertInfo(XMLNode& st, boost::shared_ptr<Insert> ins)
|
||||
: state (st), insert (ins) {}
|
||||
|
||||
XMLNode state;
|
||||
boost::shared_ptr<Insert> insert;
|
||||
PBD::ID id;
|
||||
UndoAction memento;
|
||||
};
|
||||
|
||||
struct FreezeRecord {
|
||||
FreezeRecord()
|
||||
: playlist(0)
|
||||
, have_mementos(false)
|
||||
{}
|
||||
|
||||
~FreezeRecord();
|
||||
|
||||
Playlist* playlist;
|
||||
vector<FreezeRecordInsertInfo*> insert_info;
|
||||
bool have_mementos;
|
||||
FreezeState state;
|
||||
};
|
||||
|
||||
struct RecEnableControllable : public PBD::Controllable {
|
||||
RecEnableControllable (Track&);
|
||||
|
||||
void set_value (float);
|
||||
float get_value (void) const;
|
||||
|
||||
Track& track;
|
||||
};
|
||||
|
||||
//virtual void diskstream_record_enable_changed (void *src) = 0;
|
||||
//virtual void diskstream_input_channel_changed (void *src) = 0;
|
||||
|
||||
//virtual void input_change_handler (void *src) = 0;
|
||||
|
||||
virtual void set_state_part_two () = 0;
|
||||
|
||||
FreezeRecord _freeze_record;
|
||||
XMLNode* pending_state;
|
||||
sigc::connection recenable_connection;
|
||||
sigc::connection ic_connection;
|
||||
RecEnableControllable _rec_enable_control;
|
||||
bool _destructive;
|
||||
};
|
||||
|
||||
}; /* namespace ARDOUR*/
|
||||
|
||||
#endif /* __ardour_track_h__ */
|
||||
@@ -243,6 +243,12 @@ namespace ARDOUR {
|
||||
PeakDatum min;
|
||||
PeakDatum max;
|
||||
};
|
||||
|
||||
enum DataType {
|
||||
NIL = 0,
|
||||
AUDIO,
|
||||
MIDI
|
||||
};
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (C) 2000-2003 Paul Davis
|
||||
Copyright (C) 2000-2006 Paul Davis
|
||||
|
||||
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
|
||||
@@ -14,8 +14,6 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: diskstream.cc 567 2006-06-07 14:54:12Z trutkin $
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
@@ -23,6 +21,7 @@
|
||||
#include <unistd.h>
|
||||
#include <cmath>
|
||||
#include <cerrno>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <climits>
|
||||
#include <fcntl.h>
|
||||
@@ -55,32 +54,30 @@ using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
jack_nframes_t AudioDiskstream::disk_io_chunk_frames;
|
||||
size_t AudioDiskstream::_working_buffers_size = 0;
|
||||
Sample* AudioDiskstream::_mixdown_buffer = 0;
|
||||
gain_t* AudioDiskstream::_gain_buffer = 0;
|
||||
char* AudioDiskstream::_conversion_buffer = 0;
|
||||
|
||||
sigc::signal<void,AudioDiskstream*> AudioDiskstream::AudioDiskstreamCreated;
|
||||
sigc::signal<void,list<AudioFileSource*>*> AudioDiskstream::DeleteSources;
|
||||
sigc::signal<void> AudioDiskstream::DiskOverrun;
|
||||
sigc::signal<void> AudioDiskstream::DiskUnderrun;
|
||||
|
||||
AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Flag flag)
|
||||
: _name (name),
|
||||
_session (sess)
|
||||
AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Diskstream::Flag flag)
|
||||
: Diskstream(sess, name, flag)
|
||||
, deprecated_io_node(NULL)
|
||||
{
|
||||
/* prevent any write sources from being created */
|
||||
|
||||
in_set_state = true;
|
||||
|
||||
init (flag);
|
||||
init(flag);
|
||||
use_new_playlist ();
|
||||
|
||||
in_set_state = false;
|
||||
|
||||
AudioDiskstreamCreated (this); /* EMIT SIGNAL */
|
||||
DiskstreamCreated (this); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node)
|
||||
: _session (sess)
|
||||
|
||||
: Diskstream(sess, node)
|
||||
, deprecated_io_node(NULL)
|
||||
{
|
||||
in_set_state = true;
|
||||
init (Recordable);
|
||||
@@ -96,7 +93,7 @@ AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node)
|
||||
use_destructive_playlist ();
|
||||
}
|
||||
|
||||
AudioDiskstreamCreated (this); /* EMIT SIGNAL */
|
||||
DiskstreamCreated (this); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
void
|
||||
@@ -129,43 +126,9 @@ AudioDiskstream::init_channel (ChannelInfo &chan)
|
||||
|
||||
|
||||
void
|
||||
AudioDiskstream::init (Flag f)
|
||||
AudioDiskstream::init (Diskstream::Flag f)
|
||||
{
|
||||
_refcnt = 0;
|
||||
_flags = f;
|
||||
_io = 0;
|
||||
_alignment_style = ExistingMaterial;
|
||||
_persistent_alignment_style = ExistingMaterial;
|
||||
first_input_change = true;
|
||||
_playlist = 0;
|
||||
i_am_the_modifier = 0;
|
||||
g_atomic_int_set (&_record_enabled, 0);
|
||||
was_recording = false;
|
||||
capture_start_frame = 0;
|
||||
capture_captured = 0;
|
||||
_visible_speed = 1.0f;
|
||||
_actual_speed = 1.0f;
|
||||
_buffer_reallocation_required = false;
|
||||
_seek_required = false;
|
||||
first_recordable_frame = max_frames;
|
||||
last_recordable_frame = max_frames;
|
||||
_roll_delay = 0;
|
||||
_capture_offset = 0;
|
||||
_processed = false;
|
||||
_slaved = false;
|
||||
adjust_capture_position = 0;
|
||||
last_possibly_recording = 0;
|
||||
loop_location = 0;
|
||||
wrap_buffer_size = 0;
|
||||
speed_buffer_size = 0;
|
||||
last_phase = 0;
|
||||
phi = (uint64_t) (0x1000000);
|
||||
file_frame = 0;
|
||||
playback_sample = 0;
|
||||
playback_distance = 0;
|
||||
_read_data_count = 0;
|
||||
_write_data_count = 0;
|
||||
deprecated_io_node = 0;
|
||||
Diskstream::init(f);
|
||||
|
||||
/* there are no channels at this point, so these
|
||||
two calls just get speed_buffer_size and wrap_buffer
|
||||
@@ -175,13 +138,8 @@ AudioDiskstream::init (Flag f)
|
||||
set_block_size (_session.get_block_size());
|
||||
allocate_temporary_buffers ();
|
||||
|
||||
pending_overwrite = false;
|
||||
overwrite_frame = 0;
|
||||
overwrite_queued = false;
|
||||
input_change_pending = NoChange;
|
||||
|
||||
add_channel ();
|
||||
_n_channels = 1;
|
||||
assert(_n_channels == 1);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -215,26 +173,33 @@ AudioDiskstream::~AudioDiskstream ()
|
||||
{
|
||||
Glib::Mutex::Lock lm (state_lock);
|
||||
|
||||
if (_playlist) {
|
||||
_playlist->unref ();
|
||||
}
|
||||
|
||||
for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
|
||||
for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan)
|
||||
destroy_channel((*chan));
|
||||
}
|
||||
|
||||
channels.clear();
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::handle_input_change (IOChange change, void *src)
|
||||
AudioDiskstream::allocate_working_buffers()
|
||||
{
|
||||
Glib::Mutex::Lock lm (state_lock);
|
||||
assert(disk_io_frames() > 0);
|
||||
|
||||
if (!(input_change_pending & change)) {
|
||||
input_change_pending = IOChange (input_change_pending|change);
|
||||
_session.request_input_change_handling ();
|
||||
}
|
||||
_working_buffers_size = disk_io_frames();
|
||||
_mixdown_buffer = new Sample[_working_buffers_size];
|
||||
_gain_buffer = new gain_t[_working_buffers_size];
|
||||
_conversion_buffer = new char[_working_buffers_size * 4];
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::free_working_buffers()
|
||||
{
|
||||
delete _mixdown_buffer;
|
||||
delete _gain_buffer;
|
||||
delete _conversion_buffer;
|
||||
_working_buffers_size = 0;
|
||||
_mixdown_buffer = 0;
|
||||
_gain_buffer = 0;
|
||||
_conversion_buffer = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -332,9 +297,9 @@ AudioDiskstream::find_and_use_playlist (const string& name)
|
||||
Playlist* pl;
|
||||
AudioPlaylist* playlist;
|
||||
|
||||
if ((pl = _session.get_playlist (name)) == 0) {
|
||||
error << string_compose(_("AudioDiskstream: Session doesn't know about a Playlist called \"%1\""), name) << endmsg;
|
||||
return -1;
|
||||
if ((pl = _session.playlist_by_name (name)) == 0) {
|
||||
playlist = new AudioPlaylist(_session, name);
|
||||
pl = playlist;
|
||||
}
|
||||
|
||||
if ((playlist = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
|
||||
@@ -346,57 +311,15 @@ AudioDiskstream::find_and_use_playlist (const string& name)
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::use_playlist (AudioPlaylist* playlist)
|
||||
AudioDiskstream::use_playlist (Playlist* playlist)
|
||||
{
|
||||
{
|
||||
Glib::Mutex::Lock lm (state_lock);
|
||||
assert(dynamic_cast<AudioPlaylist*>(playlist));
|
||||
|
||||
if (playlist == _playlist) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
plstate_connection.disconnect();
|
||||
plmod_connection.disconnect ();
|
||||
plgone_connection.disconnect ();
|
||||
|
||||
if (_playlist) {
|
||||
_playlist->unref();
|
||||
}
|
||||
|
||||
_playlist = playlist;
|
||||
_playlist->ref();
|
||||
|
||||
if (!in_set_state && recordable()) {
|
||||
reset_write_sources (false);
|
||||
}
|
||||
|
||||
plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &AudioDiskstream::playlist_changed));
|
||||
plmod_connection = _playlist->Modified.connect (mem_fun (*this, &AudioDiskstream::playlist_modified));
|
||||
plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &AudioDiskstream::playlist_deleted));
|
||||
}
|
||||
|
||||
if (!overwrite_queued) {
|
||||
_session.request_overwrite_buffer (this);
|
||||
overwrite_queued = true;
|
||||
}
|
||||
|
||||
PlaylistChanged (); /* EMIT SIGNAL */
|
||||
_session.set_dirty ();
|
||||
Diskstream::use_playlist(playlist);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::playlist_deleted (Playlist* pl)
|
||||
{
|
||||
/* this catches an ordering issue with session destruction. playlists
|
||||
are destroyed before diskstreams. we have to invalidate any handles
|
||||
we have to the playlist.
|
||||
*/
|
||||
|
||||
_playlist = 0;
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::use_new_playlist ()
|
||||
{
|
||||
@@ -424,6 +347,8 @@ AudioDiskstream::use_new_playlist ()
|
||||
int
|
||||
AudioDiskstream::use_copy_playlist ()
|
||||
{
|
||||
assert(audio_playlist());
|
||||
|
||||
if (destructive()) {
|
||||
return 0;
|
||||
}
|
||||
@@ -438,7 +363,7 @@ AudioDiskstream::use_copy_playlist ()
|
||||
|
||||
newname = Playlist::bump_name (_playlist->name(), _session);
|
||||
|
||||
if ((playlist = new AudioPlaylist (*_playlist, newname)) != 0) {
|
||||
if ((playlist = new AudioPlaylist (*audio_playlist(), newname)) != 0) {
|
||||
playlist->set_orig_diskstream_id (id());
|
||||
return use_playlist (playlist);
|
||||
} else {
|
||||
@@ -488,110 +413,13 @@ AudioDiskstream::use_destructive_playlist ()
|
||||
|
||||
for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
|
||||
(*chan).write_source = dynamic_cast<AudioFileSource*>(®ion->source (n));
|
||||
assert((*chan).write_source);
|
||||
(*chan).write_source->set_allow_remove_if_empty (false);
|
||||
}
|
||||
|
||||
/* the source list will never be reset for a destructive track */
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_io (IO& io)
|
||||
{
|
||||
_io = &io;
|
||||
set_align_style_from_io ();
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::set_name (string str, void *src)
|
||||
{
|
||||
if (str != _name) {
|
||||
_playlist->set_name (str);
|
||||
_name = str;
|
||||
|
||||
if (!in_set_state && recordable()) {
|
||||
/* rename existing capture files so that they have the correct name */
|
||||
return rename_write_sources ();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_speed (double sp)
|
||||
{
|
||||
_session.request_diskstream_speed (*this, sp);
|
||||
|
||||
/* to force a rebuffering at the right place */
|
||||
playlist_modified();
|
||||
}
|
||||
|
||||
bool
|
||||
AudioDiskstream::realtime_set_speed (double sp, bool global)
|
||||
{
|
||||
bool changed = false;
|
||||
double new_speed = sp * _session.transport_speed();
|
||||
|
||||
if (_visible_speed != sp) {
|
||||
_visible_speed = sp;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (new_speed != _actual_speed) {
|
||||
|
||||
jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() *
|
||||
fabs (new_speed)) + 1;
|
||||
|
||||
if (required_wrap_size > wrap_buffer_size) {
|
||||
_buffer_reallocation_required = true;
|
||||
}
|
||||
|
||||
_actual_speed = new_speed;
|
||||
phi = (uint64_t) (0x1000000 * fabs(_actual_speed));
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
if (!global) {
|
||||
_seek_required = true;
|
||||
}
|
||||
speed_changed (); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
return _buffer_reallocation_required || _seek_required;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::non_realtime_set_speed ()
|
||||
{
|
||||
if (_buffer_reallocation_required)
|
||||
{
|
||||
Glib::Mutex::Lock lm (state_lock);
|
||||
allocate_temporary_buffers ();
|
||||
|
||||
_buffer_reallocation_required = false;
|
||||
}
|
||||
|
||||
if (_seek_required) {
|
||||
if (speed() != 1.0f || speed() != -1.0f) {
|
||||
seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()), true);
|
||||
}
|
||||
else {
|
||||
seek (_session.transport_frame(), true);
|
||||
}
|
||||
|
||||
_seek_required = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::prepare ()
|
||||
{
|
||||
_processed = false;
|
||||
playback_distance = 0;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record)
|
||||
{
|
||||
@@ -755,7 +583,7 @@ AudioDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes
|
||||
returns a non-zero value, in which case, ::commit should not be called.
|
||||
*/
|
||||
|
||||
// If we can't take the state lock return.
|
||||
// If we can't take the state lock return.
|
||||
if (!state_lock.trylock()) {
|
||||
return 1;
|
||||
}
|
||||
@@ -1011,13 +839,6 @@ AudioDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::recover ()
|
||||
{
|
||||
state_lock.unlock();
|
||||
_processed = false;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioDiskstream::commit (jack_nframes_t nframes)
|
||||
{
|
||||
@@ -1156,16 +977,16 @@ AudioDiskstream::seek (jack_nframes_t frame, bool complete_refill)
|
||||
/* can't rec-enable in destructive mode if transport is before start */
|
||||
|
||||
if (destructive() && record_enabled() && frame < _session.current_start_frame()) {
|
||||
disengage_record_enable (this);
|
||||
disengage_record_enable ();
|
||||
}
|
||||
|
||||
playback_sample = frame;
|
||||
file_frame = frame;
|
||||
|
||||
if (complete_refill) {
|
||||
while ((ret = do_refill (0, 0, 0)) > 0);
|
||||
while ((ret = do_refill_with_alloc ()) > 0) ;
|
||||
} else {
|
||||
ret = do_refill (0, 0, 0);
|
||||
ret = do_refill_with_alloc ();
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1257,7 +1078,7 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
|
||||
|
||||
this_read = min(cnt,this_read);
|
||||
|
||||
if (_playlist->read (buf+offset, mixdown_buffer, gain_buffer, workbuf, start, this_read, channel) != this_read) {
|
||||
if (audio_playlist()->read (buf+offset, mixdown_buffer, gain_buffer, workbuf, start, this_read, channel) != this_read) {
|
||||
error << string_compose(_("AudioDiskstream %1: cannot read %2 from playlist at frame %3"), _id, this_read,
|
||||
start) << endmsg;
|
||||
return -1;
|
||||
@@ -1291,14 +1112,27 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * workbuf)
|
||||
AudioDiskstream::do_refill_with_alloc()
|
||||
{
|
||||
Sample* mix_buf = new Sample[disk_io_chunk_frames];
|
||||
float* gain_buf = new float[disk_io_chunk_frames];
|
||||
char* work_buf = new char[disk_io_chunk_frames * 4];
|
||||
|
||||
int ret = _do_refill(mix_buf, gain_buf, work_buf);
|
||||
|
||||
delete [] mix_buf;
|
||||
delete [] gain_buf;
|
||||
delete [] work_buf;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer, char * workbuf)
|
||||
{
|
||||
int32_t ret = 0;
|
||||
jack_nframes_t to_read;
|
||||
RingBufferNPT<Sample>::rw_vector vector;
|
||||
bool free_mixdown;
|
||||
bool free_gain;
|
||||
bool free_workbuf;
|
||||
bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
|
||||
jack_nframes_t total_space;
|
||||
jack_nframes_t zero_fill;
|
||||
@@ -1306,6 +1140,10 @@ AudioDiskstream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * w
|
||||
ChannelList::iterator i;
|
||||
jack_nframes_t ts;
|
||||
|
||||
assert(mixdown_buffer);
|
||||
assert(gain_buffer);
|
||||
assert(workbuf);
|
||||
|
||||
channels.front().playback_buf->get_write_vector (&vector);
|
||||
|
||||
if ((total_space = vector.len[0] + vector.len[1]) == 0) {
|
||||
@@ -1412,33 +1250,6 @@ AudioDiskstream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * w
|
||||
zero_fill = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Please note: the code to allocate buffers isn't run
|
||||
during normal butler thread operation. Its there
|
||||
for other times when we need to call do_refill()
|
||||
from somewhere other than the butler thread.
|
||||
*/
|
||||
|
||||
if (mixdown_buffer == 0) {
|
||||
mixdown_buffer = new Sample[disk_io_chunk_frames];
|
||||
free_mixdown = true;
|
||||
} else {
|
||||
free_mixdown = false;
|
||||
}
|
||||
|
||||
if (gain_buffer == 0) {
|
||||
gain_buffer = new float[disk_io_chunk_frames];
|
||||
free_gain = true;
|
||||
} else {
|
||||
free_gain = false;
|
||||
}
|
||||
|
||||
if (workbuf == 0) {
|
||||
workbuf = new char[disk_io_chunk_frames * 4];
|
||||
free_workbuf = true;
|
||||
} else {
|
||||
free_workbuf = false;
|
||||
}
|
||||
|
||||
jack_nframes_t file_frame_tmp = 0;
|
||||
|
||||
@@ -1507,37 +1318,30 @@ AudioDiskstream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * w
|
||||
file_frame = file_frame_tmp;
|
||||
|
||||
out:
|
||||
if (free_mixdown) {
|
||||
delete [] mixdown_buffer;
|
||||
}
|
||||
if (free_gain) {
|
||||
delete [] gain_buffer;
|
||||
}
|
||||
if (free_workbuf) {
|
||||
delete [] workbuf;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Flush pending data to disk.
|
||||
*
|
||||
* Important note: this function will write *AT MOST* disk_io_chunk_frames
|
||||
* of data to disk. it will never write more than that. If it writes that
|
||||
* much and there is more than that waiting to be written, it will return 1,
|
||||
* otherwise 0 on success or -1 on failure.
|
||||
*
|
||||
* If there is less than disk_io_chunk_frames to be written, no data will be
|
||||
* written at all unless @a force_flush is true.
|
||||
*/
|
||||
int
|
||||
AudioDiskstream::do_flush (char * workbuf, bool force_flush)
|
||||
AudioDiskstream::do_flush (Session::RunContext context, bool force_flush)
|
||||
{
|
||||
char* workbuf = _session.conversion_buffer(context);
|
||||
|
||||
uint32_t to_write;
|
||||
int32_t ret = 0;
|
||||
RingBufferNPT<Sample>::rw_vector vector;
|
||||
RingBufferNPT<CaptureTransition>::rw_vector transvec;
|
||||
jack_nframes_t total;
|
||||
|
||||
/* important note: this function will write *AT MOST*
|
||||
disk_io_chunk_frames of data to disk. it will never
|
||||
write more than that. if its writes that much and there
|
||||
is more than that waiting to be written, it will return 1,
|
||||
otherwise 0 on success or -1 on failure.
|
||||
|
||||
if there is less than disk_io_chunk_frames to be written,
|
||||
no data will be written at all unless `force_flush' is true.
|
||||
*/
|
||||
|
||||
_write_data_count = 0;
|
||||
|
||||
@@ -1552,7 +1356,6 @@ AudioDiskstream::do_flush (char * workbuf, bool force_flush)
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
/* if there are 2+ chunks of disk i/o possible for
|
||||
this track, let the caller know so that it can arrange
|
||||
for us to be called again, ASAP.
|
||||
@@ -1656,21 +1459,6 @@ AudioDiskstream::do_flush (char * workbuf, bool force_flush)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::playlist_changed (Change ignored)
|
||||
{
|
||||
playlist_modified ();
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::playlist_modified ()
|
||||
{
|
||||
if (!i_am_the_modifier && !overwrite_queued) {
|
||||
_session.request_overwrite_buffer (this);
|
||||
overwrite_queued = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
|
||||
{
|
||||
@@ -1684,7 +1472,6 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
|
||||
ChannelList::iterator chan;
|
||||
vector<CaptureInfo*>::iterator ci;
|
||||
uint32_t n = 0;
|
||||
list<AudioFileSource*>* deletion_list;
|
||||
bool mark_write_completed = false;
|
||||
|
||||
finish_capture (true);
|
||||
@@ -1694,7 +1481,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
|
||||
*/
|
||||
|
||||
while (more_work && !err) {
|
||||
switch (do_flush ( _session.conversion_buffer(Session::TransportContext), true)) {
|
||||
switch (do_flush (Session::TransportContext, true)) {
|
||||
case 0:
|
||||
more_work = false;
|
||||
break;
|
||||
@@ -1717,7 +1504,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
|
||||
|
||||
ChannelList::iterator chan;
|
||||
|
||||
deletion_list = new list<AudioFileSource*>;
|
||||
list<Source*>* deletion_list = new list<Source*>;
|
||||
|
||||
for ( chan = channels.begin(); chan != channels.end(); ++chan) {
|
||||
|
||||
@@ -1904,7 +1691,7 @@ AudioDiskstream::finish_capture (bool rec_monitors_input)
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_record_enabled (bool yn, void* src)
|
||||
AudioDiskstream::set_record_enabled (bool yn)
|
||||
{
|
||||
if (!recordable() || !_session.record_enabling_legal()) {
|
||||
return;
|
||||
@@ -1931,17 +1718,17 @@ AudioDiskstream::set_record_enabled (bool yn, void* src)
|
||||
|
||||
if (record_enabled() != yn) {
|
||||
if (yn) {
|
||||
engage_record_enable (src);
|
||||
engage_record_enable ();
|
||||
} else {
|
||||
disengage_record_enable (src);
|
||||
disengage_record_enable ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::engage_record_enable (void* src)
|
||||
AudioDiskstream::engage_record_enable ()
|
||||
{
|
||||
bool rolling = _session.transport_speed() != 0.0f;
|
||||
bool rolling = _session.transport_speed() != 0.0f;
|
||||
|
||||
g_atomic_int_set (&_record_enabled, 1);
|
||||
capturing_sources.clear ();
|
||||
@@ -1958,11 +1745,11 @@ AudioDiskstream::engage_record_enable (void* src)
|
||||
}
|
||||
}
|
||||
|
||||
record_enable_changed (src); /* EMIT SIGNAL */
|
||||
RecordEnableChanged (); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::disengage_record_enable (void* src)
|
||||
AudioDiskstream::disengage_record_enable ()
|
||||
{
|
||||
g_atomic_int_set (&_record_enabled, 0);
|
||||
if (Config->get_use_hardware_monitoring()) {
|
||||
@@ -1973,7 +1760,7 @@ AudioDiskstream::disengage_record_enable (void* src)
|
||||
}
|
||||
}
|
||||
capturing_sources.clear ();
|
||||
record_enable_changed (src); /* EMIT SIGNAL */
|
||||
RecordEnableChanged (); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
|
||||
@@ -1981,7 +1768,7 @@ XMLNode&
|
||||
AudioDiskstream::get_state ()
|
||||
{
|
||||
XMLNode* node = new XMLNode ("AudioDiskstream");
|
||||
char buf[64];
|
||||
char buf[64] = "";
|
||||
LocaleGuard lg (X_("POSIX"));
|
||||
|
||||
snprintf (buf, sizeof(buf), "0x%x", _flags);
|
||||
@@ -2080,8 +1867,7 @@ AudioDiskstream::set_state (const XMLNode& node)
|
||||
}
|
||||
|
||||
// create necessary extra channels
|
||||
// we are always constructed with one
|
||||
// and we always need one
|
||||
// we are always constructed with one and we always need one
|
||||
|
||||
if (nchans > _n_channels) {
|
||||
|
||||
@@ -2311,23 +2097,6 @@ AudioDiskstream::monitor_input (bool yn)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_capture_offset ()
|
||||
{
|
||||
if (_io == 0) {
|
||||
/* can't capture, so forget it */
|
||||
return;
|
||||
}
|
||||
|
||||
_capture_offset = _io->input_latency();
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_persistent_align_style (AlignStyle a)
|
||||
{
|
||||
_persistent_alignment_style = a;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_align_style_from_io ()
|
||||
{
|
||||
@@ -2353,20 +2122,6 @@ AudioDiskstream::set_align_style_from_io ()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_align_style (AlignStyle a)
|
||||
{
|
||||
if (record_enabled() && _session.actively_recording()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (a != _alignment_style) {
|
||||
_alignment_style = a;
|
||||
AlignmentStyleChanged ();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::add_channel ()
|
||||
{
|
||||
@@ -2417,58 +2172,6 @@ AudioDiskstream::capture_buffer_load () const
|
||||
(double) channels.front().capture_buf->bufsize());
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::set_loop (Location *location)
|
||||
{
|
||||
if (location) {
|
||||
if (location->start() >= location->end()) {
|
||||
error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
loop_location = location;
|
||||
|
||||
LoopSet (location); /* EMIT SIGNAL */
|
||||
return 0;
|
||||
}
|
||||
|
||||
jack_nframes_t
|
||||
AudioDiskstream::get_capture_start_frame (uint32_t n)
|
||||
{
|
||||
Glib::Mutex::Lock lm (capture_info_lock);
|
||||
|
||||
if (capture_info.size() > n) {
|
||||
return capture_info[n]->start;
|
||||
}
|
||||
else {
|
||||
return capture_start_frame;
|
||||
}
|
||||
}
|
||||
|
||||
jack_nframes_t
|
||||
AudioDiskstream::get_captured_frames (uint32_t n)
|
||||
{
|
||||
Glib::Mutex::Lock lm (capture_info_lock);
|
||||
|
||||
if (capture_info.size() > n) {
|
||||
return capture_info[n]->frames;
|
||||
}
|
||||
else {
|
||||
return capture_captured;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::punch_in ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::punch_out ()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::use_pending_capture_data (XMLNode& node)
|
||||
{
|
||||
@@ -2564,22 +2267,3 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_roll_delay (jack_nframes_t nframes)
|
||||
{
|
||||
_roll_delay = nframes;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_destructive (bool yn)
|
||||
{
|
||||
if (yn != destructive()) {
|
||||
reset_write_sources (true, true);
|
||||
if (yn) {
|
||||
_flags |= Destructive;
|
||||
} else {
|
||||
_flags &= ~Destructive;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,16 +243,18 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ch
|
||||
|
||||
for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) {
|
||||
|
||||
// FIXME: Should be vector<AudioRegion*>
|
||||
vector<Region*>& r (relevant_regions[*l]);
|
||||
vector<Crossfade*>& x (relevant_xfades[*l]);
|
||||
|
||||
for (vector<Region*>::iterator i = r.begin(); i != r.end(); ++i) {
|
||||
(*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n, read_frames, skip_frames);
|
||||
_read_data_count += (*i)->read_data_count();
|
||||
AudioRegion* const ar = dynamic_cast<AudioRegion*>(*i);
|
||||
assert(ar);
|
||||
ar->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n, read_frames, skip_frames);
|
||||
_read_data_count += ar->read_data_count();
|
||||
}
|
||||
|
||||
for (vector<Crossfade*>::iterator i = x.begin(); i != x.end(); ++i) {
|
||||
|
||||
(*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n);
|
||||
|
||||
/* don't JACK up _read_data_count, since its the same data as we just
|
||||
@@ -880,38 +882,6 @@ AudioPlaylist::crossfade_changed (Change ignored)
|
||||
notify_modified ();
|
||||
}
|
||||
|
||||
void
|
||||
AudioPlaylist::get_equivalent_regions (const AudioRegion& other, vector<AudioRegion*>& results)
|
||||
{
|
||||
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
|
||||
|
||||
AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
|
||||
|
||||
if (ar) {
|
||||
if (Config->get_use_overlap_equivalency()) {
|
||||
if (ar->overlap_equivalent (other)) {
|
||||
results.push_back (ar);
|
||||
} else if (ar->equivalent (other)) {
|
||||
results.push_back (ar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioPlaylist::get_region_list_equivalent_regions (const AudioRegion& other, vector<AudioRegion*>& results)
|
||||
{
|
||||
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
|
||||
|
||||
AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
|
||||
|
||||
if (ar && ar->region_list_equivalent (other)) {
|
||||
results.push_back (ar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AudioPlaylist::region_changed (Change what_changed, Region* region)
|
||||
{
|
||||
|
||||
@@ -41,9 +41,7 @@ using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
|
||||
: Route (sess, name, 1, -1, -1, -1, flag),
|
||||
diskstream (0),
|
||||
_rec_enable_control (*this)
|
||||
: Track (sess, name, flag, mode)
|
||||
{
|
||||
AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
|
||||
|
||||
@@ -59,45 +57,34 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode
|
||||
|
||||
AudioDiskstream* ds = new AudioDiskstream (_session, name, dflags);
|
||||
|
||||
_declickable = true;
|
||||
_freeze_record.state = NoFreeze;
|
||||
_saved_meter_point = _meter_point;
|
||||
_mode = mode;
|
||||
|
||||
set_diskstream (*ds, this);
|
||||
}
|
||||
|
||||
AudioTrack::AudioTrack (Session& sess, const XMLNode& node)
|
||||
: Route (sess, "to be renamed", 0, 0, -1, -1),
|
||||
diskstream (0),
|
||||
_rec_enable_control (*this)
|
||||
: Track (sess, node)
|
||||
{
|
||||
_freeze_record.state = NoFreeze;
|
||||
set_state (node);
|
||||
_declickable = true;
|
||||
_saved_meter_point = _meter_point;
|
||||
}
|
||||
|
||||
AudioTrack::~AudioTrack ()
|
||||
{
|
||||
if (diskstream) {
|
||||
diskstream->unref();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
AudioTrack::deprecated_use_diskstream_connections ()
|
||||
{
|
||||
if (diskstream->deprecated_io_node == 0) {
|
||||
AudioDiskstream& diskstream = audio_diskstream();
|
||||
|
||||
if (diskstream.deprecated_io_node == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const XMLProperty* prop;
|
||||
XMLNode& node (*diskstream->deprecated_io_node);
|
||||
XMLNode& node (*diskstream.deprecated_io_node);
|
||||
|
||||
/* don't do this more than once. */
|
||||
|
||||
diskstream->deprecated_io_node = 0;
|
||||
diskstream.deprecated_io_node = 0;
|
||||
|
||||
set_input_minimum (-1);
|
||||
set_input_maximum (-1);
|
||||
@@ -140,15 +127,15 @@ AudioTrack::deprecated_use_diskstream_connections ()
|
||||
int
|
||||
AudioTrack::set_diskstream (AudioDiskstream& ds, void *src)
|
||||
{
|
||||
if (diskstream) {
|
||||
diskstream->unref();
|
||||
if (_diskstream) {
|
||||
_diskstream->unref();
|
||||
}
|
||||
|
||||
diskstream = &ds.ref();
|
||||
diskstream->set_io (*this);
|
||||
diskstream->set_destructive (_mode == Destructive);
|
||||
_diskstream = &ds.ref();
|
||||
_diskstream->set_io (*this);
|
||||
_diskstream->set_destructive (_mode == Destructive);
|
||||
|
||||
if (diskstream->deprecated_io_node) {
|
||||
if (audio_diskstream().deprecated_io_node) {
|
||||
|
||||
if (!connecting_legal) {
|
||||
ConnectingLegal.connect (mem_fun (*this, &AudioTrack::deprecated_use_diskstream_connections));
|
||||
@@ -157,13 +144,13 @@ AudioTrack::set_diskstream (AudioDiskstream& ds, void *src)
|
||||
}
|
||||
}
|
||||
|
||||
diskstream->set_record_enabled (false, this);
|
||||
diskstream->monitor_input (false);
|
||||
_diskstream->set_record_enabled (false);
|
||||
_diskstream->monitor_input (false);
|
||||
|
||||
ic_connection.disconnect();
|
||||
ic_connection = input_changed.connect (mem_fun (*diskstream, &AudioDiskstream::handle_input_change));
|
||||
ic_connection = input_changed.connect (mem_fun (*_diskstream, &Diskstream::handle_input_change));
|
||||
|
||||
diskstream_changed (src); /* EMIT SIGNAL */
|
||||
DiskstreamChanged (); /* EMIT SIGNAL */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -173,8 +160,8 @@ AudioTrack::use_diskstream (string name)
|
||||
{
|
||||
AudioDiskstream *dstream;
|
||||
|
||||
if ((dstream = _session.diskstream_by_name (name)) == 0) {
|
||||
error << string_compose(_("AudioTrack: diskstream \"%1\" not known by session"), name) << endmsg;
|
||||
if ((dstream = dynamic_cast<AudioDiskstream*>(_session.diskstream_by_name (name))) == 0) {
|
||||
error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), name) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -186,53 +173,18 @@ AudioTrack::use_diskstream (const PBD::ID& id)
|
||||
{
|
||||
AudioDiskstream *dstream;
|
||||
|
||||
if ((dstream = _session.diskstream_by_id (id)) == 0) {
|
||||
error << string_compose(_("AudioTrack: diskstream \"%1\" not known by session"), id) << endmsg;
|
||||
if ((dstream = dynamic_cast<AudioDiskstream*>(_session.diskstream_by_id (id))) == 0) {
|
||||
error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), id) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return set_diskstream (*dstream, this);
|
||||
}
|
||||
|
||||
bool
|
||||
AudioTrack::record_enabled () const
|
||||
AudioDiskstream&
|
||||
AudioTrack::audio_diskstream() const
|
||||
{
|
||||
return diskstream->record_enabled ();
|
||||
}
|
||||
|
||||
void
|
||||
AudioTrack::set_record_enable (bool yn, void *src)
|
||||
{
|
||||
if (_freeze_record.state == Frozen) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_mix_group && src != _mix_group && _mix_group->is_active()) {
|
||||
_mix_group->apply (&AudioTrack::set_record_enable, yn, _mix_group);
|
||||
return;
|
||||
}
|
||||
|
||||
/* keep track of the meter point as it was before we rec-enabled */
|
||||
|
||||
if (!diskstream->record_enabled()) {
|
||||
_saved_meter_point = _meter_point;
|
||||
}
|
||||
|
||||
diskstream->set_record_enabled (yn, src);
|
||||
|
||||
if (diskstream->record_enabled()) {
|
||||
set_meter_point (MeterInput, this);
|
||||
} else {
|
||||
set_meter_point (_saved_meter_point, this);
|
||||
}
|
||||
|
||||
_rec_enable_control.Changed ();
|
||||
}
|
||||
|
||||
void
|
||||
AudioTrack::set_meter_point (MeterPoint p, void *src)
|
||||
{
|
||||
Route::set_meter_point (p, src);
|
||||
return *dynamic_cast<AudioDiskstream*>(_diskstream);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -306,18 +258,6 @@ AudioTrack::set_state (const XMLNode& node)
|
||||
return 0;
|
||||
}
|
||||
|
||||
XMLNode&
|
||||
AudioTrack::get_template ()
|
||||
{
|
||||
return state (false);
|
||||
}
|
||||
|
||||
XMLNode&
|
||||
AudioTrack::get_state ()
|
||||
{
|
||||
return state (true);
|
||||
}
|
||||
|
||||
XMLNode&
|
||||
AudioTrack::state(bool full_state)
|
||||
{
|
||||
@@ -348,7 +288,7 @@ AudioTrack::state(bool full_state)
|
||||
/* Alignment: act as a proxy for the diskstream */
|
||||
|
||||
XMLNode* align_node = new XMLNode (X_("alignment"));
|
||||
switch (diskstream->alignment_style()) {
|
||||
switch (_diskstream->alignment_style()) {
|
||||
case ExistingMaterial:
|
||||
snprintf (buf, sizeof (buf), X_("existing"));
|
||||
break;
|
||||
@@ -379,7 +319,7 @@ AudioTrack::state(bool full_state)
|
||||
diskstream.
|
||||
*/
|
||||
|
||||
diskstream->id().print (buf);
|
||||
_diskstream->id().print (buf);
|
||||
root.add_property ("diskstream-id", buf);
|
||||
|
||||
return root;
|
||||
@@ -451,9 +391,9 @@ AudioTrack::set_state_part_two ()
|
||||
|
||||
if ((prop = fnode->property (X_("style"))) != 0) {
|
||||
if (prop->value() == "existing") {
|
||||
diskstream->set_persistent_align_style (ExistingMaterial);
|
||||
_diskstream->set_persistent_align_style (ExistingMaterial);
|
||||
} else if (prop->value() == "capture") {
|
||||
diskstream->set_persistent_align_style (CaptureTime);
|
||||
_diskstream->set_persistent_align_style (CaptureTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -463,7 +403,7 @@ AudioTrack::set_state_part_two ()
|
||||
uint32_t
|
||||
AudioTrack::n_process_buffers ()
|
||||
{
|
||||
return max ((uint32_t) diskstream->n_channels(), redirect_max_outs);
|
||||
return max ((uint32_t) _diskstream->n_channels(), redirect_max_outs);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -494,7 +434,7 @@ AudioTrack::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nf
|
||||
return 0;
|
||||
}
|
||||
|
||||
diskstream->check_record_status (start_frame, nframes, can_record);
|
||||
audio_diskstream().check_record_status (start_frame, nframes, can_record);
|
||||
|
||||
bool send_silence;
|
||||
|
||||
@@ -513,7 +453,7 @@ AudioTrack::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nf
|
||||
send_silence = true;
|
||||
}
|
||||
} else {
|
||||
if (diskstream->record_enabled()) {
|
||||
if (_diskstream->record_enabled()) {
|
||||
if (Config->get_use_sw_monitoring()) {
|
||||
send_silence = false;
|
||||
} else {
|
||||
@@ -561,7 +501,8 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
|
||||
Sample* b;
|
||||
Sample* tmpb;
|
||||
jack_nframes_t transport_frame;
|
||||
|
||||
AudioDiskstream& diskstream = audio_diskstream();
|
||||
|
||||
{
|
||||
Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
|
||||
if (lm.locked()) {
|
||||
@@ -587,13 +528,13 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
|
||||
playback distance to zero, thus causing diskstream::commit
|
||||
to do nothing.
|
||||
*/
|
||||
return diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input);
|
||||
return diskstream.process (transport_frame, 0, 0, can_record, rec_monitors_input);
|
||||
}
|
||||
|
||||
_silent = false;
|
||||
apply_gain_automation = false;
|
||||
|
||||
if ((dret = diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
|
||||
if ((dret = diskstream.process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
|
||||
|
||||
silence (nframes, offset);
|
||||
|
||||
@@ -606,7 +547,7 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
|
||||
just_meter_input (start_frame, end_frame, nframes, offset);
|
||||
}
|
||||
|
||||
if (diskstream->record_enabled() && !can_record && !_session.get_auto_input()) {
|
||||
if (diskstream.record_enabled() && !can_record && !_session.get_auto_input()) {
|
||||
|
||||
/* not actually recording, but we want to hear the input material anyway,
|
||||
at least potentially (depending on monitoring options)
|
||||
@@ -614,7 +555,7 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
|
||||
|
||||
passthru (start_frame, end_frame, nframes, offset, 0, true);
|
||||
|
||||
} else if ((b = diskstream->playback_buffer(0)) != 0) {
|
||||
} else if ((b = diskstream.playback_buffer(0)) != 0) {
|
||||
|
||||
/*
|
||||
XXX is it true that the earlier test on n_outputs()
|
||||
@@ -636,8 +577,8 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
|
||||
|
||||
for (i = 0, n = 1; i < limit; ++i, ++n) {
|
||||
memcpy (bufs[i], b, sizeof (Sample) * nframes);
|
||||
if (n < diskstream->n_channels()) {
|
||||
tmpb = diskstream->playback_buffer(n);
|
||||
if (n < diskstream.n_channels()) {
|
||||
tmpb = diskstream.playback_buffer(n);
|
||||
if (tmpb!=0) {
|
||||
b = tmpb;
|
||||
}
|
||||
@@ -646,7 +587,7 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
|
||||
|
||||
/* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
|
||||
|
||||
if (!diskstream->record_enabled() && _session.transport_rolling()) {
|
||||
if (!diskstream.record_enabled() && _session.transport_rolling()) {
|
||||
Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
|
||||
|
||||
if (am.locked() && gain_automation_playback()) {
|
||||
@@ -682,37 +623,7 @@ AudioTrack::silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jac
|
||||
|
||||
silence (nframes, offset);
|
||||
|
||||
return diskstream->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
|
||||
}
|
||||
|
||||
void
|
||||
AudioTrack::toggle_monitor_input ()
|
||||
{
|
||||
for (vector<Port*>::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
|
||||
(*i)->request_monitor_input(!(*i)->monitoring_input());
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
AudioTrack::set_name (string str, void *src)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (record_enabled() && _session.actively_recording()) {
|
||||
/* this messes things up if done while recording */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (diskstream->set_name (str, src)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* save state so that the statefile fully reflects any filename changes */
|
||||
|
||||
if ((ret = IO::set_name (str, src)) == 0) {
|
||||
_session.save_state ("");
|
||||
}
|
||||
return ret;
|
||||
return audio_diskstream().process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -726,10 +637,15 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbu
|
||||
gain_t this_gain = _gain;
|
||||
vector<Sample*>::iterator bi;
|
||||
Sample * b;
|
||||
AudioDiskstream& diskstream = audio_diskstream();
|
||||
|
||||
Glib::RWLock::ReaderLock rlock (redirect_lock);
|
||||
|
||||
if (diskstream->playlist()->read (buffers[0], mix_buffer, gain_buffer, workbuf, start, nframes) != nframes) {
|
||||
|
||||
// FIXME
|
||||
AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(diskstream.playlist());
|
||||
assert(apl);
|
||||
|
||||
if (apl->read (buffers[0], mix_buffer, gain_buffer, workbuf, start, nframes) != nframes) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -738,8 +654,8 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbu
|
||||
b = buffers[0];
|
||||
++bi;
|
||||
for (; bi != buffers.end(); ++bi, ++n) {
|
||||
if (n < diskstream->n_channels()) {
|
||||
if (diskstream->playlist()->read ((*bi), mix_buffer, gain_buffer, workbuf, start, nframes, n) != nframes) {
|
||||
if (n < diskstream.n_channels()) {
|
||||
if (apl->read ((*bi), mix_buffer, gain_buffer, workbuf, start, nframes, n) != nframes) {
|
||||
return -1;
|
||||
}
|
||||
b = (*bi);
|
||||
@@ -811,29 +727,6 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbu
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
AudioTrack::set_latency_delay (jack_nframes_t longest_session_latency)
|
||||
{
|
||||
Route::set_latency_delay (longest_session_latency);
|
||||
diskstream->set_roll_delay (_roll_delay);
|
||||
}
|
||||
|
||||
jack_nframes_t
|
||||
AudioTrack::update_total_latency ()
|
||||
{
|
||||
_own_latency = 0;
|
||||
|
||||
for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
|
||||
if ((*i)->active ()) {
|
||||
_own_latency += (*i)->latency ();
|
||||
}
|
||||
}
|
||||
|
||||
set_port_latency (_own_latency);
|
||||
|
||||
return _own_latency;
|
||||
}
|
||||
|
||||
void
|
||||
AudioTrack::bounce (InterThreadInfo& itt)
|
||||
{
|
||||
@@ -858,8 +751,9 @@ AudioTrack::freeze (InterThreadInfo& itt)
|
||||
string dir;
|
||||
AudioRegion* region;
|
||||
string region_name;
|
||||
AudioDiskstream& diskstream = audio_diskstream();
|
||||
|
||||
if ((_freeze_record.playlist = diskstream->playlist()) == 0) {
|
||||
if ((_freeze_record.playlist = dynamic_cast<AudioPlaylist*>(diskstream.playlist())) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -881,7 +775,7 @@ AudioTrack::freeze (InterThreadInfo& itt)
|
||||
}
|
||||
|
||||
if (n == (UINT_MAX-1)) {
|
||||
error << string_compose (X_("There Are too many frozen versions of playlist \"%1\""
|
||||
error << string_compose (X_("There are too many frozen versions of playlist \"%1\""
|
||||
" to create another one"), _freeze_record.playlist->name())
|
||||
<< endmsg;
|
||||
return;
|
||||
@@ -927,13 +821,13 @@ AudioTrack::freeze (InterThreadInfo& itt)
|
||||
(AudioRegion::Flag) (AudioRegion::WholeFile|AudioRegion::DefaultFlags),
|
||||
false);
|
||||
|
||||
new_playlist->set_orig_diskstream_id (diskstream->id());
|
||||
new_playlist->set_orig_diskstream_id (diskstream.id());
|
||||
new_playlist->add_region (*region, 0);
|
||||
new_playlist->set_frozen (true);
|
||||
region->set_locked (true);
|
||||
|
||||
diskstream->use_playlist (dynamic_cast<AudioPlaylist*>(new_playlist));
|
||||
diskstream->set_record_enabled (false, this);
|
||||
diskstream.use_playlist (dynamic_cast<AudioPlaylist*>(new_playlist));
|
||||
diskstream.set_record_enabled (false);
|
||||
|
||||
_freeze_record.state = Frozen;
|
||||
FreezeChange(); /* EMIT SIGNAL */
|
||||
@@ -943,7 +837,7 @@ void
|
||||
AudioTrack::unfreeze ()
|
||||
{
|
||||
if (_freeze_record.playlist) {
|
||||
diskstream->use_playlist (_freeze_record.playlist);
|
||||
audio_diskstream().use_playlist (_freeze_record.playlist);
|
||||
|
||||
if (_freeze_record.have_mementos) {
|
||||
|
||||
@@ -971,46 +865,3 @@ AudioTrack::unfreeze ()
|
||||
FreezeChange (); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
AudioTrack::FreezeRecord::~FreezeRecord ()
|
||||
{
|
||||
for (vector<FreezeRecordInsertInfo*>::iterator i = insert_info.begin(); i != insert_info.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
|
||||
AudioTrack::FreezeState
|
||||
AudioTrack::freeze_state() const
|
||||
{
|
||||
return _freeze_record.state;
|
||||
}
|
||||
|
||||
AudioTrack::RecEnableControllable::RecEnableControllable (AudioTrack& s)
|
||||
: track (s)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AudioTrack::RecEnableControllable::set_value (float val)
|
||||
{
|
||||
bool bval = ((val >= 0.5f) ? true: false);
|
||||
track.set_record_enable (bval, this);
|
||||
}
|
||||
|
||||
float
|
||||
AudioTrack::RecEnableControllable::get_value (void) const
|
||||
{
|
||||
if (track.record_enabled()) { return 1.0f; }
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void
|
||||
AudioTrack::set_mode (TrackMode m)
|
||||
{
|
||||
if (diskstream) {
|
||||
if (_mode != m) {
|
||||
_mode = m;
|
||||
diskstream->set_destructive (m == Destructive);
|
||||
ModeChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <pbd/pthread_utils.h>
|
||||
|
||||
#include <ardour/audioengine.h>
|
||||
#include <ardour/buffer.h>
|
||||
#include <ardour/port.h>
|
||||
#include <ardour/session.h>
|
||||
#include <ardour/cycle_timer.h>
|
||||
@@ -42,8 +43,8 @@ using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
jack_nframes_t Port::short_over_length = 2;
|
||||
jack_nframes_t Port::long_over_length = 10;
|
||||
jack_nframes_t Port::_short_over_length = 2;
|
||||
jack_nframes_t Port::_long_over_length = 10;
|
||||
|
||||
AudioEngine::AudioEngine (string client_name)
|
||||
{
|
||||
@@ -274,8 +275,8 @@ AudioEngine::process_callback (jack_nframes_t nframes)
|
||||
Port *port = (*i);
|
||||
bool x;
|
||||
|
||||
if (port->last_monitor != (x = port->monitoring_input ())) {
|
||||
port->last_monitor = x;
|
||||
if (port->_last_monitor != (x = port->monitoring_input ())) {
|
||||
port->_last_monitor = x;
|
||||
/* XXX I think this is dangerous, due to
|
||||
a likely mutex in the signal handlers ...
|
||||
*/
|
||||
@@ -388,18 +389,19 @@ AudioEngine::remove_session ()
|
||||
}
|
||||
|
||||
Port *
|
||||
AudioEngine::register_audio_input_port (const string& portname)
|
||||
AudioEngine::register_input_port (DataType type, const string& portname)
|
||||
{
|
||||
if (!_running) {
|
||||
if (!_has_run) {
|
||||
fatal << _("register audio input port called before engine was started") << endmsg;
|
||||
fatal << _("register input port called before engine was started") << endmsg;
|
||||
/*NOTREACHED*/
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
jack_port_t *p = jack_port_register (_jack, portname.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
|
||||
jack_port_t *p = jack_port_register (_jack, portname.c_str(),
|
||||
Buffer::type_to_jack_type(type), JackPortIsInput, 0);
|
||||
|
||||
if (p) {
|
||||
|
||||
@@ -419,11 +421,11 @@ AudioEngine::register_audio_input_port (const string& portname)
|
||||
}
|
||||
|
||||
Port *
|
||||
AudioEngine::register_audio_output_port (const string& portname)
|
||||
AudioEngine::register_output_port (DataType type, const string& portname)
|
||||
{
|
||||
if (!_running) {
|
||||
if (!_has_run) {
|
||||
fatal << _("register audio output port called before engine was started") << endmsg;
|
||||
fatal << _("register output port called before engine was started") << endmsg;
|
||||
/*NOTREACHED*/
|
||||
} else {
|
||||
return 0;
|
||||
@@ -432,7 +434,8 @@ AudioEngine::register_audio_output_port (const string& portname)
|
||||
|
||||
jack_port_t *p;
|
||||
|
||||
if ((p = jack_port_register (_jack, portname.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) != 0) {
|
||||
if ((p = jack_port_register (_jack, portname.c_str(),
|
||||
Buffer::type_to_jack_type(type), JackPortIsOutput, 0)) != 0) {
|
||||
Port *newport = new Port (p);
|
||||
ports.insert (ports.begin(), newport);
|
||||
return newport;
|
||||
@@ -446,6 +449,7 @@ AudioEngine::register_audio_output_port (const string& portname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
AudioEngine::unregister_port (Port *port)
|
||||
{
|
||||
@@ -458,7 +462,7 @@ AudioEngine::unregister_port (Port *port)
|
||||
|
||||
if (port) {
|
||||
|
||||
int ret = jack_port_unregister (_jack, port->port);
|
||||
int ret = jack_port_unregister (_jack, port->_port);
|
||||
|
||||
if (ret == 0) {
|
||||
|
||||
@@ -549,7 +553,7 @@ AudioEngine::disconnect (Port *port)
|
||||
}
|
||||
}
|
||||
|
||||
int ret = jack_port_disconnect (_jack, port->port);
|
||||
int ret = jack_port_disconnect (_jack, port->_port);
|
||||
|
||||
if (ret == 0) {
|
||||
remove_connections_for (port);
|
||||
@@ -699,7 +703,6 @@ AudioEngine::n_physical_inputs () const
|
||||
}
|
||||
|
||||
string
|
||||
|
||||
AudioEngine::get_nth_physical (uint32_t n, int flag)
|
||||
{
|
||||
const char ** ports;
|
||||
@@ -747,7 +750,7 @@ AudioEngine::get_port_total_latency (const Port& port)
|
||||
}
|
||||
}
|
||||
|
||||
return jack_port_get_total_latency (_jack, port.port);
|
||||
return jack_port_get_total_latency (_jack, port._port);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -825,7 +828,7 @@ AudioEngine::remove_all_ports ()
|
||||
|
||||
if (_jack) {
|
||||
for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
|
||||
jack_port_unregister (_jack, (*i)->port);
|
||||
jack_port_unregister (_jack, (*i)->_port);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -948,7 +951,7 @@ AudioEngine::reconnect_to_jack ()
|
||||
|
||||
short_name = long_name.substr (long_name.find_last_of (':') + 1);
|
||||
|
||||
if (((*i)->port = jack_port_register (_jack, short_name.c_str(), (*i)->type(), (*i)->flags(), 0)) == 0) {
|
||||
if (((*i)->_port = jack_port_register (_jack, short_name.c_str(), (*i)->type(), (*i)->flags(), 0)) == 0) {
|
||||
error << string_compose (_("could not reregister %1"), (*i)->name()) << endmsg;
|
||||
break;
|
||||
} else {
|
||||
@@ -963,7 +966,7 @@ AudioEngine::reconnect_to_jack ()
|
||||
|
||||
if (i != ports.end()) {
|
||||
for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
|
||||
jack_port_unregister (_jack, (*i)->port);
|
||||
jack_port_unregister (_jack, (*i)->_port);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -48,13 +48,13 @@ using namespace ARDOUR;
|
||||
|
||||
/* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
|
||||
|
||||
Change AudioRegion::FadeInChanged = ARDOUR::new_change();
|
||||
Change AudioRegion::FadeOutChanged = ARDOUR::new_change();
|
||||
Change AudioRegion::FadeInActiveChanged = ARDOUR::new_change();
|
||||
Change AudioRegion::FadeOutActiveChanged = ARDOUR::new_change();
|
||||
Change AudioRegion::FadeInChanged = ARDOUR::new_change();
|
||||
Change AudioRegion::FadeOutChanged = ARDOUR::new_change();
|
||||
Change AudioRegion::FadeInActiveChanged = ARDOUR::new_change();
|
||||
Change AudioRegion::FadeOutActiveChanged = ARDOUR::new_change();
|
||||
Change AudioRegion::EnvelopeActiveChanged = ARDOUR::new_change();
|
||||
Change AudioRegion::ScaleAmplitudeChanged = ARDOUR::new_change();
|
||||
Change AudioRegion::EnvelopeChanged = ARDOUR::new_change();
|
||||
Change AudioRegion::EnvelopeChanged = ARDOUR::new_change();
|
||||
|
||||
AudioRegionState::AudioRegionState (string why)
|
||||
: RegionState (why),
|
||||
@@ -633,12 +633,6 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff
|
||||
return to_read;
|
||||
}
|
||||
|
||||
XMLNode&
|
||||
AudioRegion::get_state ()
|
||||
{
|
||||
return state (true);
|
||||
}
|
||||
|
||||
XMLNode&
|
||||
AudioRegion::state (bool full)
|
||||
{
|
||||
@@ -1139,24 +1133,22 @@ AudioRegion::master_source_names ()
|
||||
}
|
||||
|
||||
bool
|
||||
AudioRegion::region_list_equivalent (const AudioRegion& other) const
|
||||
AudioRegion::source_equivalent (const Region& o) const
|
||||
{
|
||||
return size_equivalent (other) && source_equivalent (other) && _name == other._name;
|
||||
}
|
||||
const AudioRegion* other = dynamic_cast<const AudioRegion*>(&o);
|
||||
if (!other)
|
||||
return false;
|
||||
|
||||
bool
|
||||
AudioRegion::source_equivalent (const AudioRegion& other) const
|
||||
{
|
||||
SourceList::const_iterator i;
|
||||
SourceList::const_iterator io;
|
||||
|
||||
for (i = sources.begin(), io = other.sources.begin(); i != sources.end() && io != other.sources.end(); ++i, ++io) {
|
||||
for (i = sources.begin(), io = other->sources.begin(); i != sources.end() && io != other->sources.end(); ++i, ++io) {
|
||||
if ((*i)->id() != (*io)->id()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = master_sources.begin(), io = other.master_sources.begin(); i != master_sources.end() && io != other.master_sources.end(); ++i, ++io) {
|
||||
for (i = master_sources.begin(), io = other->master_sources.begin(); i != master_sources.end() && io != other->master_sources.end(); ++i, ++io) {
|
||||
if ((*i)->id() != (*io)->id()) {
|
||||
return false;
|
||||
}
|
||||
@@ -1165,27 +1157,6 @@ AudioRegion::source_equivalent (const AudioRegion& other) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioRegion::overlap_equivalent (const AudioRegion& other) const
|
||||
{
|
||||
return coverage (other.first_frame(), other.last_frame()) != OverlapNone;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioRegion::equivalent (const AudioRegion& other) const
|
||||
{
|
||||
return _start == other._start &&
|
||||
_position == other._position &&
|
||||
_length == other._length;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioRegion::size_equivalent (const AudioRegion& other) const
|
||||
{
|
||||
return _start == other._start &&
|
||||
_length == other._length;
|
||||
}
|
||||
|
||||
int
|
||||
AudioRegion::apply (AudioFilter& filter)
|
||||
{
|
||||
|
||||
@@ -44,12 +44,12 @@ Auditioner::Auditioner (Session& s)
|
||||
defer_pan_reset ();
|
||||
|
||||
if (left.length()) {
|
||||
add_output_port (left, this);
|
||||
add_output_port (left, this, AUDIO);
|
||||
}
|
||||
|
||||
if (right.length()) {
|
||||
disk_stream().add_channel();
|
||||
add_output_port (right, this);
|
||||
audio_diskstream().add_channel();
|
||||
add_output_port (right, this, AUDIO);
|
||||
}
|
||||
|
||||
allow_pan_reset ();
|
||||
@@ -67,8 +67,12 @@ Auditioner::~Auditioner ()
|
||||
AudioPlaylist&
|
||||
Auditioner::prepare_playlist ()
|
||||
{
|
||||
diskstream->playlist()->clear (false, false);
|
||||
return *diskstream->playlist();
|
||||
// FIXME auditioner is still audio-only
|
||||
AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(_diskstream->playlist());
|
||||
assert(apl);
|
||||
|
||||
apl->clear (false, false);
|
||||
return *apl;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -82,13 +86,13 @@ Auditioner::audition_current_playlist ()
|
||||
}
|
||||
|
||||
Glib::Mutex::Lock lm (lock);
|
||||
diskstream->seek (0);
|
||||
length = diskstream->playlist()->get_maximum_extent();
|
||||
_diskstream->seek (0);
|
||||
length = _diskstream->playlist()->get_maximum_extent();
|
||||
current_frame = 0;
|
||||
|
||||
/* force a panner reset now that we have all channels */
|
||||
|
||||
_panner->reset (n_outputs(), diskstream->n_channels());
|
||||
_panner->reset (n_outputs(), _diskstream->n_channels());
|
||||
|
||||
g_atomic_int_set (&_active, 1);
|
||||
}
|
||||
@@ -108,23 +112,23 @@ Auditioner::audition_region (AudioRegion& region)
|
||||
the_region = new AudioRegion (region);
|
||||
the_region->set_position (0, this);
|
||||
|
||||
diskstream->playlist()->clear (true, false);
|
||||
diskstream->playlist()->add_region (*the_region, 0, 1, false);
|
||||
_diskstream->playlist()->clear (true, false);
|
||||
_diskstream->playlist()->add_region (*the_region, 0, 1, false);
|
||||
|
||||
while (diskstream->n_channels() < the_region->n_channels()) {
|
||||
diskstream->add_channel ();
|
||||
while (_diskstream->n_channels() < the_region->n_channels()) {
|
||||
audio_diskstream().add_channel ();
|
||||
}
|
||||
|
||||
while (diskstream->n_channels() > the_region->n_channels()) {
|
||||
diskstream->remove_channel ();
|
||||
while (_diskstream->n_channels() > the_region->n_channels()) {
|
||||
audio_diskstream().remove_channel ();
|
||||
}
|
||||
|
||||
/* force a panner reset now that we have all channels */
|
||||
|
||||
_panner->reset (n_outputs(), diskstream->n_channels());
|
||||
_panner->reset (n_outputs(), _diskstream->n_channels());
|
||||
|
||||
length = the_region->length();
|
||||
diskstream->seek (0);
|
||||
_diskstream->seek (0);
|
||||
current_frame = 0;
|
||||
g_atomic_int_set (&_active, 1);
|
||||
}
|
||||
@@ -143,14 +147,14 @@ Auditioner::play_audition (jack_nframes_t nframes)
|
||||
|
||||
this_nframes = min (nframes, length - current_frame);
|
||||
|
||||
diskstream->prepare ();
|
||||
_diskstream->prepare ();
|
||||
|
||||
if ((ret = roll (this_nframes, current_frame, current_frame + nframes, 0, false, false, false)) != 0) {
|
||||
silence (nframes, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
need_butler = diskstream->commit (this_nframes);
|
||||
need_butler = _diskstream->commit (this_nframes);
|
||||
current_frame += this_nframes;
|
||||
|
||||
if (current_frame >= length) {
|
||||
|
||||
401
libs/ardour/diskstream.cc
Normal file
401
libs/ardour/diskstream.cc
Normal file
@@ -0,0 +1,401 @@
|
||||
/*
|
||||
Copyright (C) 2000-2006 Paul Davis
|
||||
|
||||
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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: diskstream.cc 567 2006-06-07 14:54:12Z trutkin $
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <cstdio>
|
||||
#include <unistd.h>
|
||||
#include <cmath>
|
||||
#include <cerrno>
|
||||
#include <string>
|
||||
#include <climits>
|
||||
#include <fcntl.h>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <pbd/error.h>
|
||||
#include <pbd/basename.h>
|
||||
#include <glibmm/thread.h>
|
||||
#include <pbd/xml++.h>
|
||||
|
||||
#include <ardour/ardour.h>
|
||||
#include <ardour/audioengine.h>
|
||||
#include <ardour/diskstream.h>
|
||||
#include <ardour/utils.h>
|
||||
#include <ardour/configuration.h>
|
||||
#include <ardour/audiofilesource.h>
|
||||
#include <ardour/destructive_filesource.h>
|
||||
#include <ardour/send.h>
|
||||
#include <ardour/playlist.h>
|
||||
#include <ardour/cycle_timer.h>
|
||||
#include <ardour/region.h>
|
||||
|
||||
#include "i18n.h"
|
||||
#include <locale.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
jack_nframes_t Diskstream::disk_io_chunk_frames = 0;
|
||||
|
||||
sigc::signal<void,Diskstream*> Diskstream::DiskstreamCreated;
|
||||
sigc::signal<void,list<Source*>*> Diskstream::DeleteSources;
|
||||
sigc::signal<void> Diskstream::DiskOverrun;
|
||||
sigc::signal<void> Diskstream::DiskUnderrun;
|
||||
|
||||
Diskstream::Diskstream (Session &sess, const string &name, Flag flag)
|
||||
: _name (name)
|
||||
, _session (sess)
|
||||
, _playlist(NULL)
|
||||
{
|
||||
init (flag);
|
||||
}
|
||||
|
||||
Diskstream::Diskstream (Session& sess, const XMLNode& node)
|
||||
: _session (sess)
|
||||
, _playlist(NULL)
|
||||
{
|
||||
init (Recordable);
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::init (Flag f)
|
||||
{
|
||||
_refcnt = 0;
|
||||
_flags = f;
|
||||
_io = 0;
|
||||
_alignment_style = ExistingMaterial;
|
||||
_persistent_alignment_style = ExistingMaterial;
|
||||
first_input_change = true;
|
||||
i_am_the_modifier = 0;
|
||||
g_atomic_int_set (&_record_enabled, 0);
|
||||
was_recording = false;
|
||||
capture_start_frame = 0;
|
||||
capture_captured = 0;
|
||||
_visible_speed = 1.0f;
|
||||
_actual_speed = 1.0f;
|
||||
_buffer_reallocation_required = false;
|
||||
_seek_required = false;
|
||||
first_recordable_frame = max_frames;
|
||||
last_recordable_frame = max_frames;
|
||||
_roll_delay = 0;
|
||||
_capture_offset = 0;
|
||||
_processed = false;
|
||||
_slaved = false;
|
||||
adjust_capture_position = 0;
|
||||
last_possibly_recording = 0;
|
||||
loop_location = 0;
|
||||
wrap_buffer_size = 0;
|
||||
speed_buffer_size = 0;
|
||||
last_phase = 0;
|
||||
phi = (uint64_t) (0x1000000);
|
||||
file_frame = 0;
|
||||
playback_sample = 0;
|
||||
playback_distance = 0;
|
||||
_read_data_count = 0;
|
||||
_write_data_count = 0;
|
||||
|
||||
pending_overwrite = false;
|
||||
overwrite_frame = 0;
|
||||
overwrite_queued = false;
|
||||
input_change_pending = NoChange;
|
||||
|
||||
_n_channels = 0;
|
||||
}
|
||||
|
||||
Diskstream::~Diskstream ()
|
||||
{
|
||||
// Taken by derived class destrctors.. should assure locked here somehow?
|
||||
//Glib::Mutex::Lock lm (state_lock);
|
||||
|
||||
if (_playlist)
|
||||
_playlist->unref ();
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::set_io (IO& io)
|
||||
{
|
||||
_io = &io;
|
||||
set_align_style_from_io ();
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::handle_input_change (IOChange change, void *src)
|
||||
{
|
||||
Glib::Mutex::Lock lm (state_lock);
|
||||
|
||||
if (!(input_change_pending & change)) {
|
||||
input_change_pending = IOChange (input_change_pending|change);
|
||||
_session.request_input_change_handling ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::non_realtime_set_speed ()
|
||||
{
|
||||
if (_buffer_reallocation_required)
|
||||
{
|
||||
Glib::Mutex::Lock lm (state_lock);
|
||||
allocate_temporary_buffers ();
|
||||
|
||||
_buffer_reallocation_required = false;
|
||||
}
|
||||
|
||||
if (_seek_required) {
|
||||
if (speed() != 1.0f || speed() != -1.0f) {
|
||||
seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()), true);
|
||||
}
|
||||
else {
|
||||
seek (_session.transport_frame(), true);
|
||||
}
|
||||
|
||||
_seek_required = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Diskstream::realtime_set_speed (double sp, bool global)
|
||||
{
|
||||
bool changed = false;
|
||||
double new_speed = sp * _session.transport_speed();
|
||||
|
||||
if (_visible_speed != sp) {
|
||||
_visible_speed = sp;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (new_speed != _actual_speed) {
|
||||
|
||||
jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() *
|
||||
fabs (new_speed)) + 1;
|
||||
|
||||
if (required_wrap_size > wrap_buffer_size) {
|
||||
_buffer_reallocation_required = true;
|
||||
}
|
||||
|
||||
_actual_speed = new_speed;
|
||||
phi = (uint64_t) (0x1000000 * fabs(_actual_speed));
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
if (!global) {
|
||||
_seek_required = true;
|
||||
}
|
||||
SpeedChanged (); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
return _buffer_reallocation_required || _seek_required;
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::prepare ()
|
||||
{
|
||||
_processed = false;
|
||||
playback_distance = 0;
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::recover ()
|
||||
{
|
||||
state_lock.unlock();
|
||||
_processed = false;
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::set_capture_offset ()
|
||||
{
|
||||
if (_io == 0) {
|
||||
/* can't capture, so forget it */
|
||||
return;
|
||||
}
|
||||
|
||||
_capture_offset = _io->input_latency();
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::set_align_style (AlignStyle a)
|
||||
{
|
||||
if (record_enabled() && _session.actively_recording()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (a != _alignment_style) {
|
||||
_alignment_style = a;
|
||||
AlignmentStyleChanged ();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Diskstream::set_loop (Location *location)
|
||||
{
|
||||
if (location) {
|
||||
if (location->start() >= location->end()) {
|
||||
error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
loop_location = location;
|
||||
|
||||
LoopSet (location); /* EMIT SIGNAL */
|
||||
return 0;
|
||||
}
|
||||
|
||||
jack_nframes_t
|
||||
Diskstream::get_capture_start_frame (uint32_t n)
|
||||
{
|
||||
Glib::Mutex::Lock lm (capture_info_lock);
|
||||
|
||||
if (capture_info.size() > n) {
|
||||
return capture_info[n]->start;
|
||||
}
|
||||
else {
|
||||
return capture_start_frame;
|
||||
}
|
||||
}
|
||||
|
||||
jack_nframes_t
|
||||
Diskstream::get_captured_frames (uint32_t n)
|
||||
{
|
||||
Glib::Mutex::Lock lm (capture_info_lock);
|
||||
|
||||
if (capture_info.size() > n) {
|
||||
return capture_info[n]->frames;
|
||||
}
|
||||
else {
|
||||
return capture_captured;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::set_roll_delay (jack_nframes_t nframes)
|
||||
{
|
||||
_roll_delay = nframes;
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::set_speed (double sp)
|
||||
{
|
||||
_session.request_diskstream_speed (*this, sp);
|
||||
|
||||
/* to force a rebuffering at the right place */
|
||||
playlist_modified();
|
||||
}
|
||||
|
||||
int
|
||||
Diskstream::use_playlist (Playlist* playlist)
|
||||
{
|
||||
{
|
||||
Glib::Mutex::Lock lm (state_lock);
|
||||
|
||||
if (playlist == _playlist) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
plstate_connection.disconnect();
|
||||
plmod_connection.disconnect ();
|
||||
plgone_connection.disconnect ();
|
||||
|
||||
if (_playlist) {
|
||||
_playlist->unref();
|
||||
}
|
||||
|
||||
_playlist = playlist;
|
||||
_playlist->ref();
|
||||
|
||||
if (!in_set_state && recordable()) {
|
||||
reset_write_sources (false);
|
||||
}
|
||||
|
||||
plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &Diskstream::playlist_changed));
|
||||
plmod_connection = _playlist->Modified.connect (mem_fun (*this, &Diskstream::playlist_modified));
|
||||
plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &Diskstream::playlist_deleted));
|
||||
}
|
||||
|
||||
if (!overwrite_queued) {
|
||||
_session.request_overwrite_buffer (this);
|
||||
overwrite_queued = true;
|
||||
}
|
||||
|
||||
PlaylistChanged (); /* EMIT SIGNAL */
|
||||
_session.set_dirty ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::playlist_changed (Change ignored)
|
||||
{
|
||||
playlist_modified ();
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::playlist_modified ()
|
||||
{
|
||||
if (!i_am_the_modifier && !overwrite_queued) {
|
||||
_session.request_overwrite_buffer (this);
|
||||
overwrite_queued = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::playlist_deleted (Playlist* pl)
|
||||
{
|
||||
/* this catches an ordering issue with session destruction. playlists
|
||||
are destroyed before diskstreams. we have to invalidate any handles
|
||||
we have to the playlist.
|
||||
*/
|
||||
|
||||
_playlist = 0;
|
||||
}
|
||||
|
||||
int
|
||||
Diskstream::set_name (string str)
|
||||
{
|
||||
if (str != _name) {
|
||||
assert(playlist());
|
||||
playlist()->set_name (str);
|
||||
_name = str;
|
||||
|
||||
if (!in_set_state && recordable()) {
|
||||
/* rename existing capture files so that they have the correct name */
|
||||
return rename_write_sources ();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::set_destructive (bool yn)
|
||||
{
|
||||
if (yn != destructive()) {
|
||||
reset_write_sources (true, true);
|
||||
if (yn) {
|
||||
_flags |= Destructive;
|
||||
} else {
|
||||
_flags &= ~Destructive;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,11 +97,15 @@ static bool sort_ports_by_name (Port* a, Port* b)
|
||||
}
|
||||
|
||||
|
||||
/** @param default_type The type of port that will be created by ensure_io
|
||||
* and friends if no type is explicitly requested (to avoid breakage).
|
||||
*/
|
||||
IO::IO (Session& s, string name,
|
||||
|
||||
int input_min, int input_max, int output_min, int output_max)
|
||||
int input_min, int input_max, int output_min, int output_max,
|
||||
DataType default_type)
|
||||
: _session (s),
|
||||
_name (name),
|
||||
_default_type(default_type),
|
||||
_gain_control (*this),
|
||||
_gain_automation_curve (0.0, 2.0, 1.0),
|
||||
_input_minimum (input_min),
|
||||
@@ -781,11 +785,20 @@ IO::remove_output_port (Port* port, void* src)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Add an output port.
|
||||
*
|
||||
* @param destination Name of input port to connect new port to.
|
||||
* @param src Source for emitted ConfigurationChanged signal.
|
||||
* @param type Data type of port. Default value (NIL) will use this IO's default type.
|
||||
*/
|
||||
int
|
||||
IO::add_output_port (string destination, void* src)
|
||||
IO::add_output_port (string destination, void* src, DataType type)
|
||||
{
|
||||
Port* our_port;
|
||||
char buf[64];
|
||||
char name[64];
|
||||
|
||||
if (type == NIL)
|
||||
type = _default_type;
|
||||
|
||||
{
|
||||
Glib::Mutex::Lock em(_session.engine().process_lock());
|
||||
@@ -799,14 +812,15 @@ IO::add_output_port (string destination, void* src)
|
||||
|
||||
/* Create a new output port */
|
||||
|
||||
// FIXME: naming scheme for differently typed ports?
|
||||
if (_output_maximum == 1) {
|
||||
snprintf (buf, sizeof (buf), _("%s/out"), _name.c_str());
|
||||
snprintf (name, sizeof (name), _("%s/out"), _name.c_str());
|
||||
} else {
|
||||
snprintf (buf, sizeof (buf), _("%s/out %u"), _name.c_str(), find_output_port_hole());
|
||||
snprintf (name, sizeof (name), _("%s/out %u"), _name.c_str(), find_output_port_hole());
|
||||
}
|
||||
|
||||
if ((our_port = _session.engine().register_audio_output_port (buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
|
||||
if ((our_port = _session.engine().register_output_port (type, name)) == 0) {
|
||||
error << string_compose(_("IO: cannot register output port %1"), name) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -882,11 +896,21 @@ IO::remove_input_port (Port* port, void* src)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/** Add an input port.
|
||||
*
|
||||
* @param type Data type of port. The appropriate Jack port type, and @ref Port will be created.
|
||||
* @param destination Name of input port to connect new port to.
|
||||
* @param src Source for emitted ConfigurationChanged signal.
|
||||
*/
|
||||
int
|
||||
IO::add_input_port (string source, void* src)
|
||||
IO::add_input_port (string source, void* src, DataType type)
|
||||
{
|
||||
Port* our_port;
|
||||
char buf[64];
|
||||
char name[64];
|
||||
|
||||
if (type == NIL)
|
||||
type = _default_type;
|
||||
|
||||
{
|
||||
Glib::Mutex::Lock em (_session.engine().process_lock());
|
||||
@@ -900,14 +924,15 @@ IO::add_input_port (string source, void* src)
|
||||
|
||||
/* Create a new input port */
|
||||
|
||||
// FIXME: naming scheme for differently typed ports?
|
||||
if (_input_maximum == 1) {
|
||||
snprintf (buf, sizeof (buf), _("%s/in"), _name.c_str());
|
||||
snprintf (name, sizeof (name), _("%s/in"), _name.c_str());
|
||||
} else {
|
||||
snprintf (buf, sizeof (buf), _("%s/in %u"), _name.c_str(), find_input_port_hole());
|
||||
snprintf (name, sizeof (name), _("%s/in %u"), _name.c_str(), find_input_port_hole());
|
||||
}
|
||||
|
||||
if ((our_port = _session.engine().register_audio_input_port (buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
|
||||
if ((our_port = _session.engine().register_input_port (type, name)) == 0) {
|
||||
error << string_compose(_("IO: cannot register input port %1"), name) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1001,7 +1026,7 @@ IO::ensure_inputs_locked (uint32_t n, bool clear, void* src)
|
||||
|
||||
char buf[64];
|
||||
|
||||
/* Create a new input port */
|
||||
/* Create a new input port (of the default type) */
|
||||
|
||||
if (_input_maximum == 1) {
|
||||
snprintf (buf, sizeof (buf), _("%s/in"), _name.c_str());
|
||||
@@ -1012,7 +1037,7 @@ IO::ensure_inputs_locked (uint32_t n, bool clear, void* src)
|
||||
|
||||
try {
|
||||
|
||||
if ((input_port = _session.engine().register_audio_input_port (buf)) == 0) {
|
||||
if ((input_port = _session.engine().register_input_port (_default_type, buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
@@ -1101,7 +1126,7 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
|
||||
out_changed = true;
|
||||
}
|
||||
|
||||
/* create any necessary new ports */
|
||||
/* create any necessary new ports (of the default type) */
|
||||
|
||||
while (_ninputs < nin) {
|
||||
|
||||
@@ -1117,7 +1142,7 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
|
||||
}
|
||||
|
||||
try {
|
||||
if ((port = _session.engine().register_audio_input_port (buf)) == 0) {
|
||||
if ((port = _session.engine().register_input_port (_default_type, buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
@@ -1150,7 +1175,7 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
|
||||
}
|
||||
|
||||
try {
|
||||
if ((port = _session.engine().register_audio_output_port (buf)) == 0) {
|
||||
if ((port = _session.engine().register_output_port (_default_type, buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
@@ -1275,7 +1300,7 @@ IO::ensure_outputs_locked (uint32_t n, bool clear, void* src)
|
||||
snprintf (buf, sizeof (buf), _("%s/out %u"), _name.c_str(), find_output_port_hole());
|
||||
}
|
||||
|
||||
if ((output_port = _session.engine().register_audio_output_port (buf)) == 0) {
|
||||
if ((output_port = _session.engine().register_output_port (_default_type, buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -598,6 +598,31 @@ Playlist::remove_region_internal (Region *region, bool delay_sort)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
Playlist::get_equivalent_regions (const Region& other, vector<Region*>& results)
|
||||
{
|
||||
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
|
||||
if (Config->get_use_overlap_equivalency()) {
|
||||
if ((*i)->overlap_equivalent (other)) {
|
||||
results.push_back ((*i));
|
||||
} else if ((*i)->equivalent (other)) {
|
||||
results.push_back ((*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Playlist::get_region_list_equivalent_regions (const Region& other, vector<Region*>& results)
|
||||
{
|
||||
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
|
||||
|
||||
if ((*i) && (*i)->region_list_equivalent (other)) {
|
||||
results.push_back (*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Playlist::partition (jack_nframes_t start, jack_nframes_t end, bool just_top_level)
|
||||
{
|
||||
|
||||
@@ -24,15 +24,15 @@ using namespace ARDOUR;
|
||||
using namespace std;
|
||||
|
||||
Port::Port (jack_port_t *p)
|
||||
: port (p)
|
||||
: _port (p)
|
||||
{
|
||||
if (port == 0) {
|
||||
if (_port == 0) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
_flags = JackPortFlags (jack_port_flags (port));
|
||||
_type = jack_port_type (port);
|
||||
_name = jack_port_name (port);
|
||||
_flags = JackPortFlags (jack_port_flags (_port));
|
||||
_type = jack_port_type (_port);
|
||||
_name = jack_port_name (_port);
|
||||
|
||||
reset ();
|
||||
}
|
||||
@@ -42,9 +42,9 @@ Port::reset ()
|
||||
{
|
||||
reset_buffer ();
|
||||
|
||||
last_monitor = false;
|
||||
silent = false;
|
||||
metering = 0;
|
||||
_last_monitor = false;
|
||||
_silent = false;
|
||||
_metering = 0;
|
||||
|
||||
reset_meters ();
|
||||
}
|
||||
@@ -54,7 +54,7 @@ Port::set_name (string str)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = jack_port_set_name (port, str.c_str())) == 0) {
|
||||
if ((ret = jack_port_set_name (_port, str.c_str())) == 0) {
|
||||
_name = str;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,13 +39,13 @@ using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
Change Region::FadeChanged = ARDOUR::new_change ();
|
||||
Change Region::FadeChanged = ARDOUR::new_change ();
|
||||
Change Region::SyncOffsetChanged = ARDOUR::new_change ();
|
||||
Change Region::MuteChanged = ARDOUR::new_change ();
|
||||
Change Region::OpacityChanged = ARDOUR::new_change ();
|
||||
Change Region::LockChanged = ARDOUR::new_change ();
|
||||
Change Region::LayerChanged = ARDOUR::new_change ();
|
||||
Change Region::HiddenChanged = ARDOUR::new_change ();
|
||||
Change Region::MuteChanged = ARDOUR::new_change ();
|
||||
Change Region::OpacityChanged = ARDOUR::new_change ();
|
||||
Change Region::LockChanged = ARDOUR::new_change ();
|
||||
Change Region::LayerChanged = ARDOUR::new_change ();
|
||||
Change Region::HiddenChanged = ARDOUR::new_change ();
|
||||
|
||||
sigc::signal<void,Region *> Region::CheckNewRegion;
|
||||
|
||||
@@ -990,3 +990,30 @@ Region::set_last_layer_op (uint64_t when)
|
||||
{
|
||||
_last_layer_op = when;
|
||||
}
|
||||
|
||||
bool
|
||||
Region::overlap_equivalent (const Region& other) const
|
||||
{
|
||||
return coverage (other.first_frame(), other.last_frame()) != OverlapNone;
|
||||
}
|
||||
|
||||
bool
|
||||
Region::equivalent (const Region& other) const
|
||||
{
|
||||
return _start == other._start &&
|
||||
_position == other._position &&
|
||||
_length == other._length;
|
||||
}
|
||||
|
||||
bool
|
||||
Region::size_equivalent (const Region& other) const
|
||||
{
|
||||
return _start == other._start &&
|
||||
_length == other._length;
|
||||
}
|
||||
|
||||
bool
|
||||
Region::region_list_equivalent (const Region& other) const
|
||||
{
|
||||
return size_equivalent (other) && source_equivalent (other) && _name == other._name;
|
||||
}
|
||||
|
||||
@@ -20,11 +20,13 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
|
||||
#include <sigc++/bind.h>
|
||||
#include <pbd/xml++.h>
|
||||
|
||||
#include <ardour/timestamps.h>
|
||||
#include <ardour/buffer.h>
|
||||
#include <ardour/audioengine.h>
|
||||
#include <ardour/route.h>
|
||||
#include <ardour/insert.h>
|
||||
@@ -50,8 +52,8 @@ using namespace PBD;
|
||||
uint32_t Route::order_key_cnt = 0;
|
||||
|
||||
|
||||
Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg)
|
||||
: IO (sess, name, input_min, input_max, output_min, output_max),
|
||||
Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, DataType default_type)
|
||||
: IO (sess, name, input_min, input_max, output_min, output_max, default_type),
|
||||
_flags (flg),
|
||||
_solo_control (*this, ToggleControllable::SoloControl),
|
||||
_mute_control (*this, ToggleControllable::MuteControl)
|
||||
@@ -1330,6 +1332,9 @@ Route::state(bool full_state)
|
||||
snprintf (buf, sizeof (buf), "0x%x", _flags);
|
||||
node->add_property("flags", buf);
|
||||
}
|
||||
|
||||
node->add_property("default-type", Buffer::type_to_string(_default_type));
|
||||
|
||||
node->add_property("active", _active?"yes":"no");
|
||||
node->add_property("muted", _muted?"yes":"no");
|
||||
node->add_property("soloed", _soloed?"yes":"no");
|
||||
@@ -1503,6 +1508,11 @@ Route::set_state (const XMLNode& node)
|
||||
} else {
|
||||
_flags = Flag (0);
|
||||
}
|
||||
|
||||
if ((prop = node.property ("default-type")) != 0) {
|
||||
_default_type = Buffer::type_from_string(prop->value());
|
||||
assert(_default_type != NIL);
|
||||
}
|
||||
|
||||
if ((prop = node.property ("phase-invert")) != 0) {
|
||||
set_phase_invert(prop->value()=="yes"?true:false, this);
|
||||
|
||||
@@ -397,6 +397,8 @@ Session::~Session ()
|
||||
delete [] (i->second);
|
||||
}
|
||||
|
||||
AudioDiskstream::free_working_buffers();
|
||||
|
||||
#undef TRACK_DESTRUCTION
|
||||
#ifdef TRACK_DESTRUCTION
|
||||
cerr << "delete named selections\n";
|
||||
@@ -440,10 +442,10 @@ Session::~Session ()
|
||||
}
|
||||
|
||||
#ifdef TRACK_DESTRUCTION
|
||||
cerr << "delete audio_diskstreams\n";
|
||||
cerr << "delete diskstreams\n";
|
||||
#endif /* TRACK_DESTRUCTION */
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ) {
|
||||
AudioDiskstreamList::iterator tmp;
|
||||
for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
|
||||
DiskstreamList::iterator tmp;
|
||||
|
||||
tmp = i;
|
||||
++tmp;
|
||||
@@ -860,7 +862,7 @@ Session::playlist_length_changed (Playlist* pl)
|
||||
}
|
||||
|
||||
void
|
||||
Session::diskstream_playlist_changed (AudioDiskstream* dstream)
|
||||
Session::diskstream_playlist_changed (Diskstream* dstream)
|
||||
{
|
||||
Playlist *playlist;
|
||||
|
||||
@@ -940,7 +942,7 @@ Session::set_auto_input (bool yn)
|
||||
The rarity and short potential lock duration makes this "OK"
|
||||
*/
|
||||
Glib::RWLock::ReaderLock dsm (diskstream_lock);
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
|
||||
if ((*i)->record_enabled ()) {
|
||||
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
|
||||
(*i)->monitor_input (!auto_input);
|
||||
@@ -958,7 +960,7 @@ Session::reset_input_monitor_state ()
|
||||
{
|
||||
if (transport_rolling()) {
|
||||
Glib::RWLock::ReaderLock dsm (diskstream_lock);
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
|
||||
if ((*i)->record_enabled ()) {
|
||||
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
|
||||
(*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
|
||||
@@ -966,7 +968,7 @@ Session::reset_input_monitor_state ()
|
||||
}
|
||||
} else {
|
||||
Glib::RWLock::ReaderLock dsm (diskstream_lock);
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
|
||||
if ((*i)->record_enabled ()) {
|
||||
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
|
||||
(*i)->monitor_input (Config->get_use_hardware_monitoring());
|
||||
@@ -1047,7 +1049,7 @@ Session::auto_loop_changed (Location* location)
|
||||
}
|
||||
else if (seamless_loop && !loop_changing) {
|
||||
|
||||
// schedule a locate-roll to refill the audio_diskstreams at the
|
||||
// schedule a locate-roll to refill the diskstreams at the
|
||||
// previous loop end
|
||||
loop_changing = true;
|
||||
|
||||
@@ -1244,7 +1246,7 @@ Session::enable_record ()
|
||||
*/
|
||||
Glib::RWLock::ReaderLock dsm (diskstream_lock);
|
||||
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
|
||||
if ((*i)->record_enabled ()) {
|
||||
(*i)->monitor_input (true);
|
||||
}
|
||||
@@ -1279,7 +1281,7 @@ Session::disable_record (bool rt_context, bool force)
|
||||
*/
|
||||
Glib::RWLock::ReaderLock dsm (diskstream_lock);
|
||||
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
|
||||
if ((*i)->record_enabled ()) {
|
||||
(*i)->monitor_input (false);
|
||||
}
|
||||
@@ -1306,7 +1308,7 @@ Session::step_back_from_record ()
|
||||
*/
|
||||
Glib::RWLock::ReaderLock dsm (diskstream_lock);
|
||||
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
|
||||
if (auto_input && (*i)->record_enabled ()) {
|
||||
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
|
||||
(*i)->monitor_input (false);
|
||||
@@ -1476,7 +1478,7 @@ Session::set_block_size (jack_nframes_t nframes)
|
||||
(*i)->set_block_size (nframes);
|
||||
}
|
||||
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
|
||||
(*i)->set_block_size (nframes);
|
||||
}
|
||||
|
||||
@@ -1760,7 +1762,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
|
||||
track->set_control_outs (cports);
|
||||
}
|
||||
|
||||
track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes_proxy));
|
||||
track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
|
||||
|
||||
add_route (track);
|
||||
|
||||
@@ -1805,7 +1807,7 @@ Session::new_audio_route (int input_channels, int output_channels)
|
||||
} while (n < (UINT_MAX-1));
|
||||
|
||||
try {
|
||||
shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1));
|
||||
shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), AUDIO));
|
||||
|
||||
if (bus->ensure_io (input_channels, output_channels, false, this)) {
|
||||
error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
|
||||
@@ -1858,7 +1860,7 @@ Session::new_audio_route (int input_channels, int output_channels)
|
||||
}
|
||||
|
||||
catch (failed_constructor &err) {
|
||||
error << _("Session: could not create new route.") << endmsg;
|
||||
error << _("Session: could not create new audio route.") << endmsg;
|
||||
return shared_ptr<Route> ((Route*) 0);
|
||||
}
|
||||
}
|
||||
@@ -1893,14 +1895,14 @@ Session::add_route (shared_ptr<Route> route)
|
||||
}
|
||||
|
||||
void
|
||||
Session::add_diskstream (AudioDiskstream* dstream)
|
||||
Session::add_diskstream (Diskstream* dstream)
|
||||
{
|
||||
/* need to do this in case we're rolling at the time, to prevent false underruns */
|
||||
dstream->do_refill(0, 0, 0);
|
||||
dstream->do_refill_with_alloc();
|
||||
|
||||
{
|
||||
Glib::RWLock::WriterLock lm (diskstream_lock);
|
||||
audio_diskstreams.push_back (dstream);
|
||||
diskstreams.push_back (dstream);
|
||||
}
|
||||
|
||||
/* take a reference to the diskstream, preventing it from
|
||||
@@ -1920,7 +1922,7 @@ Session::add_diskstream (AudioDiskstream* dstream)
|
||||
set_dirty();
|
||||
save_state (_current_snapshot_name);
|
||||
|
||||
AudioDiskstreamAdded (dstream); /* EMIT SIGNAL */
|
||||
DiskstreamAdded (dstream); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1957,18 +1959,19 @@ Session::remove_route (shared_ptr<Route> route)
|
||||
/* writer goes out of scope, forces route list update */
|
||||
}
|
||||
|
||||
// FIXME: audio specific
|
||||
AudioTrack* at;
|
||||
AudioDiskstream* ds = 0;
|
||||
|
||||
if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
|
||||
ds = &at->disk_stream();
|
||||
ds = &at->audio_diskstream();
|
||||
}
|
||||
|
||||
if (ds) {
|
||||
|
||||
{
|
||||
Glib::RWLock::WriterLock lm (diskstream_lock);
|
||||
audio_diskstreams.remove (ds);
|
||||
diskstreams.remove (ds);
|
||||
}
|
||||
|
||||
ds->unref ();
|
||||
@@ -2261,7 +2264,7 @@ Session::get_maximum_extent () const
|
||||
ensure atomicity.
|
||||
*/
|
||||
|
||||
for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
|
||||
Playlist* pl = (*i)->playlist();
|
||||
if ((me = pl->get_maximum_extent()) > max) {
|
||||
max = me;
|
||||
@@ -2271,12 +2274,12 @@ Session::get_maximum_extent () const
|
||||
return max;
|
||||
}
|
||||
|
||||
AudioDiskstream *
|
||||
Diskstream *
|
||||
Session::diskstream_by_name (string name)
|
||||
{
|
||||
Glib::RWLock::ReaderLock lm (diskstream_lock);
|
||||
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
|
||||
if ((*i)->name() == name) {
|
||||
return* i;
|
||||
}
|
||||
@@ -2285,12 +2288,12 @@ Session::diskstream_by_name (string name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
AudioDiskstream *
|
||||
Diskstream *
|
||||
Session::diskstream_by_id (const PBD::ID& id)
|
||||
{
|
||||
Glib::RWLock::ReaderLock lm (diskstream_lock);
|
||||
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
|
||||
if ((*i)->id() == id) {
|
||||
return *i;
|
||||
}
|
||||
@@ -2555,18 +2558,10 @@ Session::find_whole_file_parent (AudioRegion& child)
|
||||
}
|
||||
|
||||
void
|
||||
Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
|
||||
Session::find_equivalent_playlist_regions (Region& region, vector<Region*>& result)
|
||||
{
|
||||
for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
|
||||
|
||||
AudioPlaylist* pl;
|
||||
|
||||
if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pl->get_region_list_equivalent_regions (region, result);
|
||||
}
|
||||
for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
|
||||
(*i)->get_region_list_equivalent_regions (region, result);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -2618,7 +2613,7 @@ Session::remove_last_capture ()
|
||||
|
||||
Glib::RWLock::ReaderLock lm (diskstream_lock);
|
||||
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
|
||||
list<Region*>& l = (*i)->last_capture_regions();
|
||||
|
||||
if (!l.empty()) {
|
||||
@@ -2925,18 +2920,6 @@ Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bo
|
||||
|
||||
/* Playlist management */
|
||||
|
||||
Playlist *
|
||||
Session::get_playlist (string name)
|
||||
{
|
||||
Playlist* ret = 0;
|
||||
|
||||
if ((ret = playlist_by_name (name)) == 0) {
|
||||
ret = new AudioPlaylist (*this, name);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Playlist *
|
||||
Session::playlist_by_name (string name)
|
||||
{
|
||||
@@ -3066,11 +3049,14 @@ Session::audition_playlist ()
|
||||
}
|
||||
|
||||
void
|
||||
Session::audition_region (AudioRegion& r)
|
||||
Session::audition_region (Region& r)
|
||||
{
|
||||
Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
|
||||
ev->set_ptr (&r);
|
||||
queue_event (ev);
|
||||
AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
|
||||
if (ar) {
|
||||
Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
|
||||
ev->set_ptr (ar);
|
||||
queue_event (ev);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3155,12 +3141,12 @@ Session::set_all_mute (bool yn)
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Session::n_audio_diskstreams () const
|
||||
Session::n_diskstreams () const
|
||||
{
|
||||
Glib::RWLock::ReaderLock lm (diskstream_lock);
|
||||
uint32_t n = 0;
|
||||
|
||||
for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
|
||||
if (!(*i)->hidden()) {
|
||||
n++;
|
||||
}
|
||||
@@ -3168,17 +3154,6 @@ Session::n_audio_diskstreams () const
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
Session::foreach_audio_diskstream (void (AudioDiskstream::*func)(void))
|
||||
{
|
||||
Glib::RWLock::ReaderLock lm (diskstream_lock);
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
if (!(*i)->hidden()) {
|
||||
((*i)->*func)();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::graph_reordered ()
|
||||
{
|
||||
@@ -3198,7 +3173,7 @@ Session::graph_reordered ()
|
||||
reflect any changes in latencies within the graph.
|
||||
*/
|
||||
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
|
||||
(*i)->set_capture_offset ();
|
||||
}
|
||||
}
|
||||
@@ -3481,7 +3456,7 @@ Session::reset_native_file_format ()
|
||||
//RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
|
||||
Glib::RWLock::ReaderLock lm2 (diskstream_lock);
|
||||
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
|
||||
(*i)->reset_write_sources (false);
|
||||
}
|
||||
}
|
||||
@@ -3592,7 +3567,7 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
|
||||
|
||||
/* call tree *MUST* hold route_lock */
|
||||
|
||||
if ((playlist = track.disk_stream().playlist()) == 0) {
|
||||
if ((playlist = track.diskstream().playlist()) == 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -3602,7 +3577,7 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
|
||||
goto out;
|
||||
}
|
||||
|
||||
nchans = track.disk_stream().n_channels();
|
||||
nchans = track.audio_diskstream().n_channels();
|
||||
|
||||
dir = discover_best_sound_dir ();
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user