add destructive outlines, more action usage and state fixups in GUI
git-svn-id: svn://localhost/trunk/ardour2@247 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
a20f41ab39
commit
d20534e846
|
@ -59,6 +59,16 @@
|
|||
<menuitem action='brush-at-mouse'/>
|
||||
<separator/>
|
||||
<menuitem action='ToggleFollowPlayhead'/>
|
||||
<separator/>
|
||||
<menu action='TransportOptions'>
|
||||
<menuitem action='ToggleTimeMaster'/>
|
||||
<menuitem action='TogglePunchIn'/>
|
||||
<menuitem action='TogglePunchOut'/>
|
||||
<menuitem action='ToggleAutoInput'/>
|
||||
<menuitem action='ToggleAutoPlay'/>
|
||||
<menuitem action='ToggleAutoReturn'/>
|
||||
<menuitem action='ToggleClick'/>
|
||||
</menu>
|
||||
</menu>
|
||||
<menu name='Edit' action='Edit'>
|
||||
<menuitem action='undo'/>
|
||||
|
|
|
@ -652,92 +652,6 @@ ARDOUR_UI::update_wall_clock ()
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_auto_play ()
|
||||
|
||||
{
|
||||
toggle_some_session_state (auto_play_button,
|
||||
&Session::get_auto_play,
|
||||
&Session::set_auto_play);
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_auto_return ()
|
||||
|
||||
{
|
||||
toggle_some_session_state (auto_return_button,
|
||||
&Session::get_auto_return,
|
||||
&Session::set_auto_return);
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_click ()
|
||||
{
|
||||
toggle_some_session_state (click_button,
|
||||
&Session::get_clicking,
|
||||
&Session::set_clicking);
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_session_auto_loop ()
|
||||
{
|
||||
if (session) {
|
||||
if (session->get_auto_loop()) {
|
||||
if (session->transport_rolling()) {
|
||||
transport_roll();
|
||||
}
|
||||
else {
|
||||
session->request_auto_loop (false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
session->request_auto_loop (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_session_punch_in ()
|
||||
{
|
||||
if (session) {
|
||||
session->set_punch_in (!session->get_punch_in());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_punch_out ()
|
||||
{
|
||||
toggle_some_session_state (punch_out_button,
|
||||
&Session::get_punch_out,
|
||||
&Session::set_punch_out);
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_punch_in ()
|
||||
{
|
||||
toggle_some_session_state (punch_in_button,
|
||||
&Session::get_punch_in,
|
||||
&Session::set_punch_in);
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::map_button_state ()
|
||||
{
|
||||
map_some_session_state (auto_return_button,
|
||||
&Session::get_auto_return);
|
||||
map_some_session_state (auto_play_button,
|
||||
&Session::get_auto_play);
|
||||
map_some_session_state (auto_input_button,
|
||||
&Session::get_auto_input);
|
||||
map_some_session_state (punch_in_button,
|
||||
&Session::get_punch_in);
|
||||
map_some_session_state (punch_out_button,
|
||||
&Session::get_punch_out);
|
||||
map_some_session_state (click_button,
|
||||
&Session::get_clicking);
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::control_methods_adjusted ()
|
||||
|
||||
|
@ -789,38 +703,6 @@ ARDOUR_UI::map_some_session_state (ToggleButton& button,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_some_session_state (ToggleButton& button,
|
||||
bool (Session::*get)() const,
|
||||
void (Session::*set)(bool))
|
||||
|
||||
{
|
||||
bool button_state;
|
||||
bool session_state;
|
||||
|
||||
if (session == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
button_state = button.get_active ();
|
||||
session_state = (session->*get)();
|
||||
|
||||
if (button_state != session_state) {
|
||||
(session->*set) (button_state);
|
||||
#if 0
|
||||
|
||||
/* check that it worked, and reverse
|
||||
the button state if it didn't
|
||||
*/
|
||||
|
||||
if ((session->*get)() != button_state) {
|
||||
button->set_active (!button_state);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
gint
|
||||
ARDOUR_UI::session_menu (GdkEventButton *ev)
|
||||
{
|
||||
|
|
|
@ -299,14 +299,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
|
|||
void engine_stopped ();
|
||||
void engine_running ();
|
||||
|
||||
void map_some_session_state (Gtk::ToggleButton& button,
|
||||
bool (ARDOUR::Session::*get)() const);
|
||||
|
||||
void toggle_some_session_state (Gtk::ToggleButton& button,
|
||||
bool (ARDOUR::Session::*get)() const,
|
||||
void (ARDOUR::Session::*set)(bool));
|
||||
void map_button_state ();
|
||||
|
||||
void clear_meters ();
|
||||
|
||||
static gint _blink (void *);
|
||||
|
|
|
@ -381,14 +381,12 @@ ARDOUR_UI::setup_transport ()
|
|||
ARDOUR_UI::instance()->tooltips().set_tip (primary_clock, _("Primary clock"));
|
||||
ARDOUR_UI::instance()->tooltips().set_tip (secondary_clock, _("secondary clock"));
|
||||
|
||||
/* options: XXX these should all be actions with the buttons as proxies */
|
||||
|
||||
auto_return_button.signal_toggled().connect (mem_fun(*this,&ARDOUR_UI::toggle_auto_return));
|
||||
auto_play_button.signal_toggled().connect (mem_fun(*this,&ARDOUR_UI::toggle_auto_play));
|
||||
auto_input_button.signal_toggled().connect (mem_fun(*this,&ARDOUR_UI::toggle_auto_input));
|
||||
click_button.signal_toggled().connect (mem_fun(*this,&ARDOUR_UI::toggle_click));
|
||||
punch_in_button.signal_toggled().connect (mem_fun(*this,&ARDOUR_UI::toggle_punch_in));
|
||||
punch_out_button.signal_toggled().connect (mem_fun(*this,&ARDOUR_UI::toggle_punch_out));
|
||||
ActionManager::get_action ("Transport", "ToggleAutoReturn")->connect_proxy (auto_return_button);
|
||||
ActionManager::get_action ("Transport", "ToggleAutoPlay")->connect_proxy (auto_play_button);
|
||||
ActionManager::get_action ("Transport", "ToggleAutoInput")->connect_proxy (auto_input_button);
|
||||
ActionManager::get_action ("Transport", "ToggleClick")->connect_proxy (click_button);
|
||||
ActionManager::get_action ("Transport", "TogglePunchIn")->connect_proxy (punch_in_button);
|
||||
ActionManager::get_action ("Transport", "TogglePunchOut")->connect_proxy (punch_out_button);
|
||||
|
||||
preroll_button.unset_flags (CAN_FOCUS);
|
||||
preroll_button.set_events (preroll_button.get_events() & ~(Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK));
|
||||
|
|
|
@ -110,8 +110,6 @@ ARDOUR_UI::connect_to_session (Session *s)
|
|||
/* Clocks are on by default after we are connected to a session, so show that here.
|
||||
*/
|
||||
|
||||
map_button_state ();
|
||||
|
||||
connect_dependents_to_session (s);
|
||||
|
||||
start_clocking ();
|
||||
|
@ -258,15 +256,6 @@ ARDOUR_UI::toggle_options_window ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_auto_input ()
|
||||
|
||||
{
|
||||
toggle_some_session_state (auto_input_button,
|
||||
&Session::get_auto_input,
|
||||
&Session::set_auto_input);
|
||||
}
|
||||
|
||||
int
|
||||
ARDOUR_UI::create_location_ui ()
|
||||
{
|
||||
|
|
|
@ -70,6 +70,7 @@ ARDOUR_UI::install_actions ()
|
|||
ActionManager::register_action (main_actions, X_("Cleanup"), _("Cleanup"));
|
||||
ActionManager::register_action (main_actions, X_("Sync"), _("Sync"));
|
||||
ActionManager::register_action (main_actions, X_("Options"), _("Options"));
|
||||
ActionManager::register_action (main_actions, X_("TransportOptions"), _("Options"));
|
||||
|
||||
/* the real actions */
|
||||
|
||||
|
@ -242,19 +243,31 @@ ARDOUR_UI::install_actions ()
|
|||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::transport_sensitive_actions.push_back (act);
|
||||
|
||||
act = ActionManager::register_toggle_action (transport_actions, X_("TogglePunchIn"), _("punch in"), mem_fun(*this, &ARDOUR_UI::toggle_punch_in));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::transport_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_toggle_action (transport_actions, X_("TogglePunchOut"), _("punch out"), mem_fun(*this, &ARDOUR_UI::toggle_punch_out));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::transport_sensitive_actions.push_back (act);
|
||||
|
||||
/* XXX the newline in the displayed name of this action is really wrong, but its because we want the button
|
||||
that proxies for this action to be more compact. It would be nice to find a way to override the action
|
||||
name appearance on the button.
|
||||
/* XXX the newline in the displayed names of these action is really wrong, but its because we want the button
|
||||
that proxies for these action to be more compact. It would be nice to find a way to override the action
|
||||
name appearance on the buttons.
|
||||
*/
|
||||
|
||||
act = ActionManager::register_action (transport_actions, X_("ToggleTimeMaster"), _("time\nmaster"), mem_fun(*this, &ARDOUR_UI::toggle_time_master));
|
||||
act = ActionManager::register_toggle_action (transport_actions, X_("TogglePunchIn"), _("punch\nin"), mem_fun(*this, &ARDOUR_UI::toggle_punch_in));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::transport_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_toggle_action (transport_actions, X_("TogglePunchOut"), _("punch\nout"), mem_fun(*this, &ARDOUR_UI::toggle_punch_out));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::transport_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_toggle_action (transport_actions, X_("ToggleClick"), _("click"), mem_fun(*this, &ARDOUR_UI::toggle_click));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::transport_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoInput"), _("auto\ninput"), mem_fun(*this, &ARDOUR_UI::toggle_auto_input));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::transport_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoPlay"), _("auto\nplay"), mem_fun(*this, &ARDOUR_UI::toggle_auto_play));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::transport_sensitive_actions.push_back (act);
|
||||
act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoReturn"), _("auto\nreturn"), mem_fun(*this, &ARDOUR_UI::toggle_auto_return));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
ActionManager::transport_sensitive_actions.push_back (act);
|
||||
|
||||
act = ActionManager::register_toggle_action (transport_actions, X_("ToggleTimeMaster"), _("time\nmaster"), mem_fun(*this, &ARDOUR_UI::toggle_time_master));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
|
||||
act = ActionManager::register_action (common_actions, X_("SendAllMidiFeedback"), _("send all midi feedback"), mem_fun(*this, &ARDOUR_UI::send_all_midi_feedback));
|
||||
|
@ -391,6 +404,7 @@ ARDOUR_UI::install_actions ()
|
|||
act = ActionManager::register_action (option_actions, X_("UnmuteNewFullCrossfades"), _("Unmute new full crossfades"), mem_fun (*this, &ARDOUR_UI::toggle_UnmuteNewFullCrossfades));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
|
||||
|
||||
#ifdef NEW_ACTIONS
|
||||
act = ActionManager::register_action (option_actions, X_("SetRegionLayerMode", _("SetRegionLayerMode"), mem_fun (*this, &ARDOUR_UI::toggle_SetRegionLayerMode)));
|
||||
ActionManager::session_sensitive_actions.push_back (act);
|
||||
|
|
|
@ -134,6 +134,58 @@ ARDOUR_UI::toggle_ManuallyConnectNewTrackOutputs()
|
|||
toggle_session_state ("options", "AutoConnectNewTrackOutputsToHardware", bind (mem_fun (session, &Session::set_output_auto_connect), Session::AutoConnectOption (0)));
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_auto_input ()
|
||||
{
|
||||
toggle_session_state ("Transport", "ToggleAutoInput", &Session::set_auto_input, &Session::get_auto_input);
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_auto_play ()
|
||||
{
|
||||
toggle_session_state ("Transport", "ToggleAutoPlay", &Session::set_auto_play, &Session::get_auto_play);
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_auto_return ()
|
||||
{
|
||||
toggle_session_state ("Transport", "ToggleAutoReturn", &Session::set_auto_return, &Session::get_auto_return);
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_click ()
|
||||
{
|
||||
toggle_session_state ("Transport", "ToggleClick", &Session::set_clicking, &Session::get_clicking);
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_session_auto_loop ()
|
||||
{
|
||||
if (session) {
|
||||
if (session->get_auto_loop()) {
|
||||
if (session->transport_rolling()) {
|
||||
transport_roll();
|
||||
} else {
|
||||
session->request_auto_loop (false);
|
||||
}
|
||||
} else {
|
||||
session->request_auto_loop (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_punch_in ()
|
||||
{
|
||||
toggle_session_state ("Transport", "TogglePunchIn", &Session::set_punch_in, &Session::get_punch_in);
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_punch_out ()
|
||||
{
|
||||
toggle_session_state ("Transport", "TogglePunchOut", &Session::set_punch_out, &Session::get_punch_out);
|
||||
}
|
||||
|
||||
void
|
||||
ARDOUR_UI::toggle_UseHardwareMonitoring()
|
||||
{
|
||||
|
@ -313,6 +365,12 @@ ARDOUR_UI::setup_options ()
|
|||
session_control_changed (Session::SoloingModel);
|
||||
session_control_changed (Session::LayeringModel);
|
||||
session_control_changed (Session::CrossfadingModel);
|
||||
session_control_changed (Session::PunchOut);
|
||||
session_control_changed (Session::PunchIn);
|
||||
session_control_changed (Session::AutoPlay);
|
||||
session_control_changed (Session::AutoReturn);
|
||||
session_control_changed (Session::AutoInput);
|
||||
session_control_changed (Session::Clicking);
|
||||
|
||||
session->ControlChanged.connect (mem_fun (*this, &ARDOUR_UI::queue_session_control_changed));
|
||||
}
|
||||
|
@ -406,34 +464,31 @@ ARDOUR_UI::session_control_changed (Session::ControlType t)
|
|||
break;
|
||||
|
||||
|
||||
// BUTTON STATE: fix me in the future to use actions
|
||||
|
||||
|
||||
case Session::AutoPlay:
|
||||
map_some_session_state (auto_play_button, &Session::get_auto_play);
|
||||
map_some_session_state ("Transport", "ToggleAutoPlay", &Session::get_auto_play);
|
||||
break;
|
||||
|
||||
case Session::AutoLoop:
|
||||
break;
|
||||
|
||||
case Session::AutoReturn:
|
||||
map_some_session_state (auto_return_button, &Session::get_auto_return);
|
||||
map_some_session_state ("Transport", "ToggleAutoReturn", &Session::get_auto_return);
|
||||
break;
|
||||
|
||||
case Session::AutoInput:
|
||||
map_some_session_state (auto_input_button, &Session::get_auto_input);
|
||||
map_some_session_state ("Transport", "ToggleAutoInput", &Session::get_auto_input);
|
||||
break;
|
||||
|
||||
case Session::PunchOut:
|
||||
map_some_session_state (punch_in_button, &Session::get_punch_out);
|
||||
map_some_session_state ("Transport", "TogglePunchOut", &Session::get_punch_out);
|
||||
break;
|
||||
|
||||
case Session::PunchIn:
|
||||
map_some_session_state (punch_in_button, &Session::get_punch_in);
|
||||
map_some_session_state ("Transport", "TogglePunchIn", &Session::get_punch_in);
|
||||
break;
|
||||
|
||||
case Session::Clicking:
|
||||
map_some_session_state (click_button, &Session::get_clicking);
|
||||
map_some_session_state ("Transport", "ToggleClick", &Session::get_clicking);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -35,6 +35,7 @@ crossfade.cc
|
|||
curve.cc
|
||||
cycle_timer.cc
|
||||
default_click.cc
|
||||
destructive_filesource.cc
|
||||
diskstream.cc
|
||||
filesource.cc
|
||||
gain.cc
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2002 Paul Davis
|
||||
Copyright (C) 2002-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
|
||||
|
@ -56,6 +56,10 @@ class AudioTrack : public Route
|
|||
int use_diskstream (string name);
|
||||
int use_diskstream (id_t id);
|
||||
|
||||
bool destructive() const { return _destructive; }
|
||||
void set_destructive (bool yn);
|
||||
sigc::signal<void> DestructiveChanged;
|
||||
|
||||
jack_nframes_t update_total_latency();
|
||||
void set_latency_delay (jack_nframes_t);
|
||||
|
||||
|
@ -155,6 +159,8 @@ class AudioTrack : public Route
|
|||
};
|
||||
|
||||
MIDIRecEnableControl _midi_rec_enable_control;
|
||||
|
||||
bool _destructive;
|
||||
};
|
||||
|
||||
}; /* namespace ARDOUR*/
|
||||
|
|
52
libs/ardour/ardour/destructive_filesource.h
Normal file
52
libs/ardour/ardour/destructive_filesource.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
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$
|
||||
*/
|
||||
|
||||
#ifndef __ardour_destructive_file_source_h__
|
||||
#define __ardour_destructive_file_source_h__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <ardour/filesource.h>
|
||||
|
||||
struct tm;
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class DestructiveFileSource : public FileSource {
|
||||
public:
|
||||
DestructiveFileSource (std::string path, jack_nframes_t rate, bool repair_first = false);
|
||||
DestructiveFileSource (const XMLNode&, jack_nframes_t rate);
|
||||
~DestructiveFileSource ();
|
||||
|
||||
int seek (jack_nframes_t frame);
|
||||
void mark_capture_start ();
|
||||
void mark_capture_end ();
|
||||
void clear_capture_marks();
|
||||
|
||||
jack_nframes_t write (Sample *src, jack_nframes_t cnt);
|
||||
|
||||
private:
|
||||
bool _capture_start;
|
||||
bool _capture_end;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* __ardour_destructive_file_source_h__ */
|
|
@ -60,7 +60,8 @@ class DiskStream : public Stateful, public sigc::trackable
|
|||
public:
|
||||
enum Flag {
|
||||
Recordable = 0x1,
|
||||
Hidden = 0x2
|
||||
Hidden = 0x2,
|
||||
Destructive = 0x4
|
||||
};
|
||||
|
||||
DiskStream (Session &, const string& name, Flag f = Recordable);
|
||||
|
@ -92,6 +93,9 @@ class DiskStream : public Stateful, public sigc::trackable
|
|||
|
||||
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);
|
||||
|
@ -150,11 +154,6 @@ class DiskStream : public Stateful, public sigc::trackable
|
|||
|
||||
AudioPlaylist *playlist () { return _playlist; }
|
||||
|
||||
FileSource *fades_source (uint32_t n=0) {
|
||||
if (n < channels.size())
|
||||
return channels[n].fades_source;
|
||||
return 0;
|
||||
}
|
||||
FileSource *write_source (uint32_t n=0) {
|
||||
if (n < channels.size())
|
||||
return channels[n].write_source;
|
||||
|
@ -245,7 +244,7 @@ class DiskStream : public Stateful, public sigc::trackable
|
|||
void set_block_size (jack_nframes_t);
|
||||
int internal_playback_seek (jack_nframes_t distance);
|
||||
int can_internal_playback_seek (jack_nframes_t distance);
|
||||
void reset_write_sources (bool);
|
||||
void reset_write_sources (bool, bool force = false);
|
||||
void non_realtime_input_change ();
|
||||
|
||||
uint32_t read_data_count() const { return _read_data_count; }
|
||||
|
|
|
@ -72,7 +72,7 @@ class FileSource : public Source {
|
|||
|
||||
static void set_search_path (string);
|
||||
|
||||
private:
|
||||
protected:
|
||||
int fd;
|
||||
string _path;
|
||||
bool remove_at_unref;
|
||||
|
|
|
@ -686,7 +686,7 @@ class Session : public sigc::trackable, public Stateful
|
|||
sigc::signal<void,Source *> SourceAdded;
|
||||
sigc::signal<void,Source *> SourceRemoved;
|
||||
|
||||
FileSource *create_file_source (ARDOUR::DiskStream&, int32_t chan);
|
||||
FileSource *create_file_source (ARDOUR::DiskStream&, int32_t chan, bool destructive);
|
||||
Source *get_source (ARDOUR::id_t);
|
||||
|
||||
/* playlist management */
|
||||
|
|
|
@ -1096,3 +1096,15 @@ AudioTrack::MIDIRecEnableControl::write_feedback (MIDI::byte* buf, int32_t& bufs
|
|||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void
|
||||
AudioTrack::set_destructive (bool yn)
|
||||
{
|
||||
if (diskstream) {
|
||||
if (_destructive != yn) {
|
||||
diskstream->set_destructive (yn);
|
||||
_destructive = yn;
|
||||
DestructiveChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
155
libs/ardour/destructive_filesource.cc
Normal file
155
libs/ardour/destructive_filesource.cc
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
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$
|
||||
*/
|
||||
|
||||
/* This is is very hacky way to get pread and pwrite declarations.
|
||||
First, include <features.h> so that we can avoid its #undef __USE_UNIX98.
|
||||
Then define __USE_UNIX98, include <unistd.h>, and then undef it
|
||||
again. If #define _XOPEN_SOURCE actually worked, I'd use that, but
|
||||
despite claims in the header that it does, it doesn't.
|
||||
|
||||
features.h isn't available on osx and it compiles fine without it.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_FEATURES_H
|
||||
#include <features.h>
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
// #define _XOPEN_SOURCE 500
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#define __USE_UNIX98
|
||||
#include <unistd.h>
|
||||
#undef __USE_UNIX98
|
||||
#endif
|
||||
|
||||
// darwin supports 64 by default and doesn't provide wrapper functions.
|
||||
#if defined (__APPLE__)
|
||||
typedef off_t off64_t;
|
||||
#define open64 open
|
||||
#define close64 close
|
||||
#define lseek64 lseek
|
||||
#define pread64 pread
|
||||
#define pwrite64 pwrite
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <pbd/error.h>
|
||||
#include <ardour/destructive_filesource.h>
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
|
||||
DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate, bool repair_first)
|
||||
: FileSource (path, rate, repair_first)
|
||||
{
|
||||
_capture_start = false;
|
||||
_capture_end = false;
|
||||
}
|
||||
|
||||
DestructiveFileSource::DestructiveFileSource (const XMLNode& node, jack_nframes_t rate)
|
||||
: FileSource (node, rate)
|
||||
{
|
||||
_capture_start = false;
|
||||
_capture_end = false;
|
||||
}
|
||||
|
||||
DestructiveFileSource::~DestructiveFileSource()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
DestructiveFileSource::seek (jack_nframes_t frame)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
DestructiveFileSource::mark_capture_start ()
|
||||
{
|
||||
_capture_start = true;
|
||||
}
|
||||
|
||||
void
|
||||
DestructiveFileSource::mark_capture_end()
|
||||
{
|
||||
_capture_end = true;
|
||||
}
|
||||
|
||||
void
|
||||
DestructiveFileSource::clear_capture_marks ()
|
||||
{
|
||||
_capture_start = false;
|
||||
_capture_end = false;
|
||||
}
|
||||
|
||||
jack_nframes_t
|
||||
DestructiveFileSource::write (Sample* data, jack_nframes_t cnt)
|
||||
{
|
||||
{
|
||||
LockMonitor lm (_lock, __LINE__, __FILE__);
|
||||
|
||||
int32_t byte_cnt = cnt * sizeof (Sample);
|
||||
int32_t byte_pos = data_offset + (_length * sizeof (Sample));
|
||||
jack_nframes_t oldlen;
|
||||
|
||||
if (::pwrite64 (fd, (char *) data, byte_cnt, byte_pos) != (off64_t) byte_cnt) {
|
||||
error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
oldlen = _length;
|
||||
_length += cnt;
|
||||
_write_data_count = byte_cnt;
|
||||
|
||||
if (_build_peakfiles) {
|
||||
PeakBuildRecord *pbr = 0;
|
||||
|
||||
if (pending_peak_builds.size()) {
|
||||
pbr = pending_peak_builds.back();
|
||||
}
|
||||
|
||||
if (pbr && pbr->frame + pbr->cnt == oldlen) {
|
||||
|
||||
/* the last PBR extended to the start of the current write,
|
||||
so just extend it again.
|
||||
*/
|
||||
|
||||
pbr->cnt += cnt;
|
||||
} else {
|
||||
pending_peak_builds.push_back (new PeakBuildRecord (oldlen, cnt));
|
||||
}
|
||||
|
||||
_peaks_built = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (_build_peakfiles) {
|
||||
queue_for_peaks (*this);
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
|
@ -42,6 +42,7 @@
|
|||
#include <ardour/utils.h>
|
||||
#include <ardour/configuration.h>
|
||||
#include <ardour/filesource.h>
|
||||
#include <ardour/destructive_filesource.h>
|
||||
#include <ardour/send.h>
|
||||
#include <ardour/audioplaylist.h>
|
||||
#include <ardour/cycle_timer.h>
|
||||
|
@ -99,7 +100,6 @@ DiskStream::init_channel (ChannelInfo &chan)
|
|||
chan.capture_wrap_buffer = 0;
|
||||
chan.speed_buffer = 0;
|
||||
chan.peak_power = 0.0f;
|
||||
chan.fades_source = 0;
|
||||
chan.write_source = 0;
|
||||
chan.source = 0;
|
||||
chan.current_capture_buffer = 0;
|
||||
|
@ -1060,8 +1060,12 @@ DiskStream::seek (jack_nframes_t frame, bool complete_refill)
|
|||
for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
|
||||
(*chan).playback_buf->reset ();
|
||||
(*chan).capture_buf->reset ();
|
||||
if (destructive()) {
|
||||
DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> ((*chan).write_source);
|
||||
dfs->seek (frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
playback_sample = frame;
|
||||
file_frame = frame;
|
||||
|
||||
|
@ -1775,6 +1779,10 @@ DiskStream::get_state ()
|
|||
char buf[64];
|
||||
LocaleGuard lg (X_("POSIX"));
|
||||
|
||||
if (destructive()) {
|
||||
node->add_property ("destructive", "true");
|
||||
}
|
||||
|
||||
snprintf (buf, sizeof(buf), "%zd", channels.size());
|
||||
node->add_property ("channels", buf);
|
||||
|
||||
|
@ -1849,6 +1857,12 @@ DiskStream::set_state (const XMLNode& node)
|
|||
_name = prop->value();
|
||||
}
|
||||
|
||||
if ((prop = node.property ("destructive")) != 0) {
|
||||
if (prop->value() == "true") {
|
||||
_flags |= Destructive;
|
||||
}
|
||||
}
|
||||
|
||||
if (deprecated_io_node) {
|
||||
if ((prop = deprecated_io_node->property ("id")) != 0) {
|
||||
sscanf (prop->value().c_str(), "%" PRIu64, &_id);
|
||||
|
@ -1966,7 +1980,7 @@ DiskStream::use_new_write_source (uint32_t n)
|
|||
}
|
||||
|
||||
try {
|
||||
if ((chan.write_source = _session.create_file_source (*this, n)) == 0) {
|
||||
if ((chan.write_source = _session.create_file_source (*this, n, destructive())) == 0) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
}
|
||||
|
@ -1983,7 +1997,7 @@ DiskStream::use_new_write_source (uint32_t n)
|
|||
}
|
||||
|
||||
void
|
||||
DiskStream::reset_write_sources (bool mark_write_complete)
|
||||
DiskStream::reset_write_sources (bool mark_write_complete, bool force)
|
||||
{
|
||||
ChannelList::iterator chan;
|
||||
uint32_t n;
|
||||
|
@ -1991,6 +2005,10 @@ DiskStream::reset_write_sources (bool mark_write_complete)
|
|||
if (!recordable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!force && destructive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
capturing_sources.clear ();
|
||||
|
||||
|
@ -2310,3 +2328,16 @@ DiskStream::set_roll_delay (jack_nframes_t nframes)
|
|||
{
|
||||
_roll_delay = nframes;
|
||||
}
|
||||
|
||||
void
|
||||
DiskStream::set_destructive (bool yn)
|
||||
{
|
||||
if (yn != destructive()) {
|
||||
reset_write_sources (true, true);
|
||||
if (yn) {
|
||||
_flags |= Destructive;
|
||||
} else {
|
||||
_flags &= ~Destructive;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include <ardour/audioregion.h>
|
||||
#include <ardour/source.h>
|
||||
#include <ardour/filesource.h>
|
||||
#include <ardour/destructive_filesource.h>
|
||||
#include <ardour/sndfilesource.h>
|
||||
#include <ardour/auditioner.h>
|
||||
#include <ardour/recent_sessions.h>
|
||||
|
@ -2619,7 +2620,7 @@ Session::get_source (ARDOUR::id_t id)
|
|||
}
|
||||
|
||||
FileSource *
|
||||
Session::create_file_source (DiskStream& ds, int32_t chan)
|
||||
Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
|
||||
{
|
||||
string spath;
|
||||
uint32_t cnt;
|
||||
|
@ -2693,7 +2694,11 @@ Session::create_file_source (DiskStream& ds, int32_t chan)
|
|||
|
||||
/* this might throw failed_constructor(), which is OK */
|
||||
|
||||
return new FileSource (spath, frame_rate());
|
||||
if (destructive) {
|
||||
return new DestructiveFileSource (spath, frame_rate());
|
||||
} else {
|
||||
return new FileSource (spath, frame_rate());
|
||||
}
|
||||
}
|
||||
|
||||
/* Playlist management */
|
||||
|
|
|
@ -77,7 +77,6 @@ UndoCommand::clear ()
|
|||
void
|
||||
UndoCommand::undo ()
|
||||
{
|
||||
cerr << "There are " << undo_actions.size() << " actions to undo\n";
|
||||
for (list<UndoAction>::reverse_iterator i = undo_actions.rbegin(); i != undo_actions.rend(); ++i) {
|
||||
(*i)();
|
||||
}
|
||||
|
@ -100,14 +99,12 @@ UndoHistory::add (UndoCommand uc)
|
|||
void
|
||||
UndoHistory::undo (unsigned int n)
|
||||
{
|
||||
cerr << "Undo history undoing " << n << " with a list of " << UndoList.size() << endl;
|
||||
while (n--) {
|
||||
if (UndoList.size() == 0) {
|
||||
return;
|
||||
}
|
||||
UndoCommand uc = UndoList.back ();
|
||||
UndoList.pop_back ();
|
||||
cerr << "undoing command called " << uc.name() << endl;
|
||||
uc.undo ();
|
||||
RedoList.push_back (uc);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user