Merge with 2.0-ongoing R3077.

git-svn-id: svn://localhost/ardour2/branches/3.0@3078 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2008-02-17 17:49:38 +00:00
parent 859e9106e7
commit 8fed7470f5
16 changed files with 186 additions and 78 deletions

View file

@ -371,6 +371,8 @@
<menuitem action='UseHardwareMonitoring'/> <menuitem action='UseHardwareMonitoring'/>
<menuitem action='UseSoftwareMonitoring'/> <menuitem action='UseSoftwareMonitoring'/>
<menuitem action='UseExternalMonitoring'/> <menuitem action='UseExternalMonitoring'/>
<separator/>
<menuitem action='ToggleTapeMachineMode'/>
</menu> </menu>
<menu action='Plugins'> <menu action='Plugins'>
<menuitem action='DisableAllPlugins'/> <menuitem action='DisableAllPlugins'/>
@ -444,6 +446,7 @@
<menuitem action='ShowTrackMeters'/> <menuitem action='ShowTrackMeters'/>
<menuitem action='DefaultNarrowMS'/> <menuitem action='DefaultNarrowMS'/>
<menuitem action='link-region-and-track-selection'/> <menuitem action='link-region-and-track-selection'/>
<menuitem action='RubberbandingSnapsToGrid'/>
<separator/> <separator/>
</menu> </menu>

View file

@ -732,6 +732,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void toggle_ShowTrackMeters (); void toggle_ShowTrackMeters ();
void toggle_only_copy_imported_files (); void toggle_only_copy_imported_files ();
void toggle_use_narrow_ms(); void toggle_use_narrow_ms();
void toggle_rubberbanding_snaps_to_grid ();
void toggle_TapeMachineMode();
void mtc_port_changed (); void mtc_port_changed ();
void map_solo_model (); void map_solo_model ();

View file

@ -418,6 +418,8 @@ ARDOUR_UI::install_actions ()
#ifndef HAVE_LIBLO #ifndef HAVE_LIBLO
act->set_sensitive (false); act->set_sensitive (false);
#endif #endif
act = ActionManager::register_toggle_action (option_actions, X_("ToggleTapeMachineMode"), _("Tape Machine mode"), mem_fun (*this, &ARDOUR_UI::toggle_TapeMachineMode));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::register_toggle_action (option_actions, X_("SyncEditorAndMixerTrackOrder"), _("Sync Editor and Mixer track order"), mem_fun (*this, &ARDOUR_UI::toggle_sync_order_keys)); ActionManager::register_toggle_action (option_actions, X_("SyncEditorAndMixerTrackOrder"), _("Sync Editor and Mixer track order"), mem_fun (*this, &ARDOUR_UI::toggle_sync_order_keys));
ActionManager::register_toggle_action (option_actions, X_("StopPluginsWithTransport"), _("Stop plugins with transport"), mem_fun (*this, &ARDOUR_UI::toggle_StopPluginsWithTransport)); ActionManager::register_toggle_action (option_actions, X_("StopPluginsWithTransport"), _("Stop plugins with transport"), mem_fun (*this, &ARDOUR_UI::toggle_StopPluginsWithTransport));
@ -433,6 +435,8 @@ ARDOUR_UI::install_actions ()
ActionManager::register_toggle_action (option_actions, X_("SecondaryClockDeltaEditCursor"), _("Secondary Clock delta to edit point"), mem_fun (*this, &ARDOUR_UI::toggle_SecondaryClockDeltaEditCursor)); ActionManager::register_toggle_action (option_actions, X_("SecondaryClockDeltaEditCursor"), _("Secondary Clock delta to edit point"), mem_fun (*this, &ARDOUR_UI::toggle_SecondaryClockDeltaEditCursor));
ActionManager::register_toggle_action (option_actions, X_("ShowTrackMeters"), _("Enable Editor Meters"), mem_fun (*this, &ARDOUR_UI::toggle_ShowTrackMeters)); ActionManager::register_toggle_action (option_actions, X_("ShowTrackMeters"), _("Enable Editor Meters"), mem_fun (*this, &ARDOUR_UI::toggle_ShowTrackMeters));
ActionManager::register_toggle_action (option_actions, X_("OnlyCopyImportedFiles"), _("Always copy imported files"), mem_fun (*this, &ARDOUR_UI::toggle_only_copy_imported_files)); ActionManager::register_toggle_action (option_actions, X_("OnlyCopyImportedFiles"), _("Always copy imported files"), mem_fun (*this, &ARDOUR_UI::toggle_only_copy_imported_files));
ActionManager::register_toggle_action (option_actions, X_("RubberbandingSnapsToGrid"), _("Rubberbanding Snaps to Grid"), mem_fun (*this, &ARDOUR_UI::toggle_rubberbanding_snaps_to_grid));
ActionManager::register_toggle_action (option_actions, X_("DefaultNarrowMS"), _("Use narrow mixer strips"), mem_fun (*this, &ARDOUR_UI::toggle_use_narrow_ms)); ActionManager::register_toggle_action (option_actions, X_("DefaultNarrowMS"), _("Use narrow mixer strips"), mem_fun (*this, &ARDOUR_UI::toggle_use_narrow_ms));
RadioAction::Group denormal_group; RadioAction::Group denormal_group;

View file

@ -523,12 +523,24 @@ ARDOUR_UI::toggle_ShowTrackMeters()
ActionManager::toggle_config_state ("options", "ShowTrackMeters", &Configuration::set_show_track_meters, &Configuration::get_show_track_meters); ActionManager::toggle_config_state ("options", "ShowTrackMeters", &Configuration::set_show_track_meters, &Configuration::get_show_track_meters);
} }
void
ARDOUR_UI::toggle_TapeMachineMode ()
{
ActionManager::toggle_config_state ("options", "ToggleTapeMachineMode", &Configuration::set_tape_machine_mode, &Configuration::get_tape_machine_mode);
}
void void
ARDOUR_UI::toggle_use_narrow_ms() ARDOUR_UI::toggle_use_narrow_ms()
{ {
ActionManager::toggle_config_state ("options", "DefaultNarrowMS", &Configuration::set_default_narrow_ms, &Configuration::get_default_narrow_ms); ActionManager::toggle_config_state ("options", "DefaultNarrowMS", &Configuration::set_default_narrow_ms, &Configuration::get_default_narrow_ms);
} }
void
ARDOUR_UI::toggle_rubberbanding_snaps_to_grid ()
{
ActionManager::toggle_config_state ("options", "RubberbandingSnapsToGrid", &Configuration::set_rubberbanding_snaps_to_grid, &Configuration::get_rubberbanding_snaps_to_grid);
}
void void
ARDOUR_UI::mtc_port_changed () ARDOUR_UI::mtc_port_changed ()
{ {
@ -1040,6 +1052,8 @@ ARDOUR_UI::parameter_changed (const char* parameter_name)
ActionManager::map_some_state ("Transport", "ToggleAutoReturn", &Configuration::get_auto_return); ActionManager::map_some_state ("Transport", "ToggleAutoReturn", &Configuration::get_auto_return);
} else if (PARAM_IS ("auto-input")) { } else if (PARAM_IS ("auto-input")) {
ActionManager::map_some_state ("Transport", "ToggleAutoInput", &Configuration::get_auto_input); ActionManager::map_some_state ("Transport", "ToggleAutoInput", &Configuration::get_auto_input);
} else if (PARAM_IS ("tape-machine-mode")) {
ActionManager::map_some_state ("options", "ToggleTapeMachineMode", &Configuration::get_tape_machine_mode);
} else if (PARAM_IS ("punch-out")) { } else if (PARAM_IS ("punch-out")) {
ActionManager::map_some_state ("Transport", "TogglePunchOut", &Configuration::get_punch_out); ActionManager::map_some_state ("Transport", "TogglePunchOut", &Configuration::get_punch_out);
} else if (PARAM_IS ("punch-in")) { } else if (PARAM_IS ("punch-in")) {
@ -1138,7 +1152,11 @@ ARDOUR_UI::parameter_changed (const char* parameter_name)
editor->toggle_meter_updating(); editor->toggle_meter_updating();
} else if (PARAM_IS ("default-narrow_ms")) { } else if (PARAM_IS ("default-narrow_ms")) {
ActionManager::map_some_state ("options", "DefaultNarrowMS", &Configuration::get_default_narrow_ms); ActionManager::map_some_state ("options", "DefaultNarrowMS", &Configuration::get_default_narrow_ms);
} else if (PARAM_IS ("rubberbanding-snaps-to-grid")) {
ActionManager::map_some_state ("options", "RubberbandingSnapsToGrid", &Configuration::get_rubberbanding_snaps_to_grid);
} }
#undef PARAM_IS #undef PARAM_IS
} }

View file

@ -809,7 +809,8 @@ AudioRegionView::create_waves ()
ChanCount nchans = atv.get_diskstream()->n_channels(); ChanCount nchans = atv.get_diskstream()->n_channels();
cerr << "creating waves for " << _region->name() << " with wfd = " << wait_for_data << " and channels = " << nchans << endl; cerr << "creating waves for " << _region->name() << " with wfd = " << wait_for_data
<< " and channels = " << nchans.n_audio() << endl;
/* in tmp_waves, set up null pointers for each channel so the vector is allocated */ /* in tmp_waves, set up null pointers for each channel so the vector is allocated */
for (uint32_t n = 0; n < nchans.n_audio(); ++n) { for (uint32_t n = 0; n < nchans.n_audio(); ++n) {
@ -828,6 +829,7 @@ AudioRegionView::create_waves ()
if (wait_for_data) { if (wait_for_data) {
if (audio_region()->audio_source(n)->peaks_ready (bind (mem_fun(*this, &AudioRegionView::peaks_ready_handler), n), data_ready_connection)) { if (audio_region()->audio_source(n)->peaks_ready (bind (mem_fun(*this, &AudioRegionView::peaks_ready_handler), n), data_ready_connection)) {
cerr << "\tData is ready\n";
cerr << "\tData is ready\n"; cerr << "\tData is ready\n";
create_one_wave (n, true); create_one_wave (n, true);
} else { } else {

View file

@ -4597,8 +4597,6 @@ Editor::get_regions_after (RegionSelection& rs, nframes64_t where, const TrackSe
void void
Editor::get_regions_for_action (RegionSelection& rs, bool allow_entered) Editor::get_regions_for_action (RegionSelection& rs, bool allow_entered)
{ {
bool use_regions_at = true;
if (selection->regions.empty()) { if (selection->regions.empty()) {
if (selection->tracks.empty()) { if (selection->tracks.empty()) {

View file

@ -5246,7 +5246,7 @@ Editor::drag_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event)
return; return;
} }
if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier()) && Config->get_rubberbanding_snaps_to_grid()) {
if (drag_info.first_move) { if (drag_info.first_move) {
snap_to (drag_info.grab_frame); snap_to (drag_info.grab_frame);
} }

View file

@ -138,7 +138,7 @@ TempoDialog::init (const BBT_Time& when, double bpm, double note_type, bool mova
when_table.set_homogeneous (true); when_table.set_homogeneous (true);
when_table.set_row_spacings (2); when_table.set_row_spacings (2);
when_table.set_col_spacings (2); when_table.set_col_spacings (2);
when_table.set_border_width (6); when_table.set_border_width (0);
when_table.attach (when_bar_label, 0, 1, 0, 1, AttachOptions(0), FILL|EXPAND); when_table.attach (when_bar_label, 0, 1, 0, 1, AttachOptions(0), FILL|EXPAND);
when_table.attach (when_bar_entry, 1, 2, 0, 1, AttachOptions(0), FILL|EXPAND); when_table.attach (when_bar_entry, 1, 2, 0, 1, AttachOptions(0), FILL|EXPAND);
@ -178,6 +178,10 @@ TempoDialog::init (const BBT_Time& when, double bpm, double note_type, bool mova
bpm_spinner.signal_activate().connect (bind (mem_fun (*this, &TempoDialog::response), RESPONSE_ACCEPT)); bpm_spinner.signal_activate().connect (bind (mem_fun (*this, &TempoDialog::response), RESPONSE_ACCEPT));
bpm_spinner.signal_button_press_event().connect (mem_fun (*this, &TempoDialog::bpm_button_press), false); bpm_spinner.signal_button_press_event().connect (mem_fun (*this, &TempoDialog::bpm_button_press), false);
bpm_spinner.signal_button_release_event().connect (mem_fun (*this, &TempoDialog::bpm_button_release), false); bpm_spinner.signal_button_release_event().connect (mem_fun (*this, &TempoDialog::bpm_button_release), false);
when_bar_entry.signal_activate().connect (bind (mem_fun (*this, &TempoDialog::response), RESPONSE_ACCEPT));
when_bar_entry.signal_key_release_event().connect (mem_fun (*this, &TempoDialog::entry_key_release), false);
when_beat_entry.signal_activate().connect (bind (mem_fun (*this, &TempoDialog::response), RESPONSE_ACCEPT));
when_beat_entry.signal_key_release_event().connect (mem_fun (*this, &TempoDialog::entry_key_release), false);
note_types.signal_changed().connect (mem_fun (*this, &TempoDialog::note_types_change)); note_types.signal_changed().connect (mem_fun (*this, &TempoDialog::note_types_change));
} }
@ -196,6 +200,17 @@ TempoDialog::bpm_button_release (GdkEventButton* ev)
return false; return false;
} }
bool
TempoDialog::entry_key_release (GdkEventKey* ev)
{
if (when_beat_entry.get_text() != "" && when_bar_entry.get_text() != "") {
set_response_sensitive (RESPONSE_ACCEPT, true);
} else {
set_response_sensitive (RESPONSE_ACCEPT, false);
}
return false;
}
double double
TempoDialog::get_bpm () TempoDialog::get_bpm ()
{ {
@ -258,8 +273,6 @@ MeterDialog::MeterDialog (TempoMap& map, nframes_t frame, const string & action)
bpb_frame (_("Meter")), bpb_frame (_("Meter")),
ok_button (action), ok_button (action),
cancel_button (_("Cancel")), cancel_button (_("Cancel")),
when_bar_label (_("Bar"), ALIGN_LEFT, ALIGN_CENTER),
when_beat_label (_("Beat"), ALIGN_LEFT, ALIGN_CENTER),
when_frame (_("Location")) when_frame (_("Location"))
{ {
BBT_Time when; BBT_Time when;
@ -275,8 +288,6 @@ MeterDialog::MeterDialog (MeterSection& section, const string & action)
bpb_frame (_("Meter")), bpb_frame (_("Meter")),
ok_button (action), ok_button (action),
cancel_button (_("Cancel")), cancel_button (_("Cancel")),
when_bar_label (_("Bar"), ALIGN_LEFT, ALIGN_CENTER),
when_beat_label (_("Beat"), ALIGN_LEFT, ALIGN_CENTER),
when_frame (_("Location")) when_frame (_("Location"))
{ {
init (section.start(), section.beats_per_bar(), section.note_divisor(), section.movable()); init (section.start(), section.beats_per_bar(), section.note_divisor(), section.movable());
@ -337,32 +348,14 @@ MeterDialog::init (const BBT_Time& when, double bpb, double note_type, bool mova
if (movable) { if (movable) {
snprintf (buf, sizeof (buf), "%" PRIu32, when.bars); snprintf (buf, sizeof (buf), "%" PRIu32, when.bars);
when_bar_entry.set_text (buf); when_bar_entry.set_text (buf);
snprintf (buf, sizeof (buf), "%" PRIu32, when.beats);
when_beat_entry.set_text (buf);
when_bar_entry.set_name ("MetricEntry"); when_bar_entry.set_name ("MetricEntry");
when_beat_entry.set_name ("MetricEntry");
when_bar_label.set_name ("MetricLabel");
when_beat_label.set_name ("MetricLabel");
Gtkmm2ext::set_size_request_to_display_given_text (when_bar_entry, "999g", 5, 7); Gtkmm2ext::set_size_request_to_display_given_text (when_bar_entry, "999g", 5, 7);
Gtkmm2ext::set_size_request_to_display_given_text (when_beat_entry, "999g", 5, 7);
when_table.set_homogeneous (true);
when_table.set_row_spacings (2);
when_table.set_col_spacings (2);
when_table.set_border_width (6);
when_table.attach (when_bar_label, 0, 1, 0, 1, AttachOptions(0), FILL|EXPAND);
when_table.attach (when_bar_entry, 1, 2, 0, 1, AttachOptions(0), FILL|EXPAND);
when_table.attach (when_beat_label, 0, 1, 1, 2, AttachOptions(0), AttachOptions(0));
when_table.attach (when_beat_entry, 1, 2, 1, 2, AttachOptions(0), AttachOptions(0));
HBox* when_hbox = manage (new HBox()); HBox* when_hbox = manage (new HBox());
Label* when_label = manage(new Label(_("Meter Begins at:"), ALIGN_LEFT, ALIGN_TOP)); Label* when_label = manage(new Label(_("Meter Begins at Bar:"), ALIGN_LEFT, ALIGN_TOP));
when_hbox->pack_end(when_table, PACK_EXPAND_PADDING, 6); when_hbox->pack_end(when_bar_entry, PACK_EXPAND_PADDING, 6);
when_hbox->pack_start(*when_label, PACK_EXPAND_PADDING, 6); when_hbox->pack_start(*when_label, PACK_EXPAND_PADDING, 6);
when_frame.set_name ("MetricDialogFrame"); when_frame.set_name ("MetricDialogFrame");
@ -386,13 +379,17 @@ MeterDialog::init (const BBT_Time& when, double bpb, double note_type, bool mova
set_name ("MetricDialog"); set_name ("MetricDialog");
bpb_entry.signal_activate().connect (bind (mem_fun (*this, &MeterDialog::response), RESPONSE_ACCEPT)); bpb_entry.signal_activate().connect (bind (mem_fun (*this, &MeterDialog::response), RESPONSE_ACCEPT));
bpb_entry.signal_key_press_event().connect (mem_fun (*this, &MeterDialog::bpb_key_press), false); bpb_entry.signal_key_press_event().connect (mem_fun (*this, &MeterDialog::entry_key_press), false);
bpb_entry.signal_key_release_event().connect (mem_fun (*this, &MeterDialog::bpb_key_release)); bpb_entry.signal_key_release_event().connect (mem_fun (*this, &MeterDialog::entry_key_release));
when_bar_entry.signal_activate().connect (bind (mem_fun (*this, &MeterDialog::response), RESPONSE_ACCEPT));
when_bar_entry.signal_key_press_event().connect (mem_fun (*this, &MeterDialog::entry_key_press), false);
when_bar_entry.signal_key_release_event().connect (mem_fun (*this, &MeterDialog::entry_key_release));
note_types.signal_changed().connect (mem_fun (*this, &MeterDialog::note_types_change)); note_types.signal_changed().connect (mem_fun (*this, &MeterDialog::note_types_change));
} }
bool bool
MeterDialog::bpb_key_press (GdkEventKey* ev) MeterDialog::entry_key_press (GdkEventKey* ev)
{ {
switch (ev->keyval) { switch (ev->keyval) {
@ -440,9 +437,9 @@ MeterDialog::bpb_key_press (GdkEventKey* ev)
} }
bool bool
MeterDialog::bpb_key_release (GdkEventKey* ev) MeterDialog::entry_key_release (GdkEventKey* ev)
{ {
if (bpb_entry.get_text() != "") { if (when_bar_entry.get_text() != "" && bpb_entry.get_text() != "") {
set_response_sensitive (RESPONSE_ACCEPT, true); set_response_sensitive (RESPONSE_ACCEPT, true);
} else { } else {
set_response_sensitive (RESPONSE_ACCEPT, false); set_response_sensitive (RESPONSE_ACCEPT, false);
@ -504,9 +501,7 @@ MeterDialog::get_bbt_time (BBT_Time& requested)
return false; return false;
} }
if (sscanf (when_beat_entry.get_text().c_str(), "%" PRIu32, &requested.beats) != 1) { requested.beats = 1;
return false;
}
requested.ticks = 0; requested.ticks = 0;

View file

@ -66,6 +66,7 @@ private:
void bpm_changed (); void bpm_changed ();
bool bpm_button_press (GdkEventButton* ); bool bpm_button_press (GdkEventButton* );
bool bpm_button_release (GdkEventButton* ); bool bpm_button_release (GdkEventButton* );
bool entry_key_release (GdkEventKey* );
void note_types_change (); void note_types_change ();
}; };
@ -78,10 +79,6 @@ struct MeterDialog : public ArdourDialog
Gtk::Button ok_button; Gtk::Button ok_button;
Gtk::Button cancel_button; Gtk::Button cancel_button;
Gtk::Entry when_bar_entry; Gtk::Entry when_bar_entry;
Gtk::Entry when_beat_entry;
Gtk::Label when_bar_label;
Gtk::Label when_beat_label;
Gtk::Table when_table;
Gtk::Frame when_frame; Gtk::Frame when_frame;
char buf[64]; char buf[64];
@ -94,8 +91,8 @@ struct MeterDialog : public ArdourDialog
private: private:
void init (const ARDOUR::BBT_Time&, double, double, bool); void init (const ARDOUR::BBT_Time&, double, double, bool);
bool bpb_key_press (GdkEventKey* ); bool entry_key_press (GdkEventKey* );
bool bpb_key_release (GdkEventKey* ); bool entry_key_release (GdkEventKey* );
void note_types_change (); void note_types_change ();
}; };

View file

@ -88,6 +88,7 @@ CONFIG_VARIABLE (bool, solo_latched, "solo-latched", true)
CONFIG_VARIABLE (bool, latched_record_enable, "latched-record-enable", false) CONFIG_VARIABLE (bool, latched_record_enable, "latched-record-enable", false)
CONFIG_VARIABLE (bool, all_safe, "all-safe", false) CONFIG_VARIABLE (bool, all_safe, "all-safe", false)
CONFIG_VARIABLE (bool, show_solo_mutes, "show-solo-mutes", false) CONFIG_VARIABLE (bool, show_solo_mutes, "show-solo-mutes", false)
CONFIG_VARIABLE (bool, tape_machine_mode, "tape-machine-mode", false)
/* click */ /* click */
@ -155,6 +156,7 @@ CONFIG_VARIABLE (bool, only_copy_imported_files, "only-copy-imported-files", tru
CONFIG_VARIABLE (std::string, keyboard_layout, "keyboard-layout", "ansi") CONFIG_VARIABLE (std::string, keyboard_layout, "keyboard-layout", "ansi")
CONFIG_VARIABLE (std::string, default_bindings, "default-bindings", "ardour") CONFIG_VARIABLE (std::string, default_bindings, "default-bindings", "ardour")
CONFIG_VARIABLE (bool, default_narrow_ms, "default-narrow_ms", false) CONFIG_VARIABLE (bool, default_narrow_ms, "default-narrow_ms", false)
CONFIG_VARIABLE (bool, rubberbanding_snaps_to_grid, "rubberbanding-snaps-to-grid", false)
/* denormal management */ /* denormal management */

View file

@ -1839,8 +1839,8 @@ AudioDiskstream::disengage_record_enable ()
{ {
g_atomic_int_set (&_record_enabled, 0); g_atomic_int_set (&_record_enabled, 0);
boost::shared_ptr<ChannelList> c = channels.reader(); boost::shared_ptr<ChannelList> c = channels.reader();
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
if (Config->get_monitoring_model() == HardwareMonitoring) { if (Config->get_monitoring_model() == HardwareMonitoring) {
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
if ((*chan)->source) { if ((*chan)->source) {
(*chan)->source->ensure_monitor_input (false); (*chan)->source->ensure_monitor_input (false);
} }

View file

@ -457,22 +457,27 @@ AudioTrack::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_fra
send_silence = true; send_silence = true;
} else { } else {
if (Config->get_auto_input()) { if (!Config->get_tape_machine_mode()) {
if (Config->get_monitoring_model() == SoftwareMonitoring) { /*
ADATs work in a strange way..
they monitor input always when stopped.and auto-input is engaged.
*/
if ((Config->get_monitoring_model() == SoftwareMonitoring) && (Config->get_auto_input () || _diskstream->record_enabled())) {
send_silence = false; send_silence = false;
} else { } else {
send_silence = true; send_silence = true;
} }
} else { } else {
if (_diskstream->record_enabled()) { /*
if (Config->get_monitoring_model() == SoftwareMonitoring) { Other machines switch to input on stop if the track is record enabled,
regardless of the auto input setting (auto input only changes the
monitoring state when the transport is rolling)
*/
if ((Config->get_monitoring_model() == SoftwareMonitoring) && _diskstream->record_enabled()) {
send_silence = false; send_silence = false;
} else { } else {
send_silence = true; send_silence = true;
} }
} else {
send_silence = true;
}
} }
} }

View file

@ -1147,11 +1147,11 @@ Session::step_back_from_record ()
if (g_atomic_int_get (&_record_status) == Recording) { if (g_atomic_int_get (&_record_status) == Recording) {
g_atomic_int_set (&_record_status, Enabled); g_atomic_int_set (&_record_status, Enabled);
if (Config->get_monitoring_model() == HardwareMonitoring) { if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) {
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if (Config->get_auto_input() && (*i)->record_enabled ()) { if ((*i)->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl; //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (false); (*i)->monitor_input (false);
} }

View file

@ -64,6 +64,13 @@
"Edit cursor", for example). "Edit cursor", for example).
</para> </para>
<para>
Regions are a somewhat special case in that they may contain <emphasis>
sync points</emphasis>. If a region contains a sync point, the region start
position is ignored and the sync point is aligned to the grid. This allows
you to align a 'hit point' to the desitred grid.
</para>
<variablelist> <variablelist>
<title> Possible Snap Settings </title> <title> Possible Snap Settings </title>
<varlistentry> <varlistentry>

View file

@ -38,17 +38,41 @@
<section id="setup-monitoring"> <section id="setup-monitoring">
<title>Monitoring</title> <title>Monitoring</title>
<para></para> <para>
While monitoring is a broad term, here we use it to refer to the
signal a track delivers to its channel for further processing.
There are two available monitoring states.
These are
'input' (the signal being delivered to a track for potential recording), and
'off-disk' (material you have already recorded, or silence in the absence of a region).
</para>
</section> </section>
<section id="setup-hardware-monitoring"> <section id="setup-hardware-monitoring">
<title>Hardware Monitoring</title> <title>Hardware Monitoring</title>
<para></para> <para>
Some multichannel audio interfaces have the ability to route an input signal
directly to an output with very low or no latency. This is useful if your computer hardware
is connected to the tape sends and returns of a mixing console.
Whenever monitoring is set to input on a track, the track's input port is connected to its
output in hardware (as would happen on a multitrack tape recorder).
Hardware monitoring provides the best quality assurance for an engineer, as the signal path
is exactly the same for input and off-disk monitoring.
Level differences can be heard immediately, as can other gremlins that may ruin your recording.
The hardware monitoring setting is only useful for interfaces supporting this feature.
</para>
</section> </section>
<section id="setup-software-monitoring"> <section id="setup-software-monitoring">
<title>Software Monitoring</title> <title>Software Monitoring</title>
<para></para> <para>
Software monitoring uses software to perform input monitoring.
When set to monitor input, a tracks input signal is passed to its channel
as if it were coming from disk, allowing plugins to be heard while recording.
This introduces an inevitable processing delay, or latency, to the input signal.
The size of the delay depends on the current JACK configuration, which should
be set to as short as possible while recording.
</para>
</section> </section>
<section id="setup-latency"> <section id="setup-latency">
@ -58,12 +82,43 @@
<section id="setup-external-monitoring"> <section id="setup-external-monitoring">
<title>External Monitoring</title> <title>External Monitoring</title>
<para></para> <para>
External Monitoring will silence the output of a track whenever the track is set
to monitor input. It is useful if you are listening to the input signal
using a path outside your computer (eg a mixing console).
</para>
</section>
<section id="setup-external-monitoring">
<title>Tape Machine Mode</title>
<para>
Nearly all traditional tape recorders use the same monitoring model.
Normally only tracks that are record-enabled will monitor input with the
transport stopped.
Tape machine mode emulates this behaviour.
Some simpler machines (like a famous product by Alesis) switch all tracks to
input on stop when auto-input is enabled, regardless of record-enable state.
Disabling Tape Machine Mode switches to a behaviour that mimics this type of recorder.
Be warned that if you disable Tape Machine Mode, many tracks sharing the same input
(in software monitoring mode) will sum that input through the master buss
(potentially including several plugins) whenever the transport is stopped.
Since setting up a sound usually involves listening to the input with the transport
stopped, you might not be hearing the sound you are about to record!
Disabling this mode can also lead to surprising acoustic feedback.
Tape Machine Mode is off by default.
</para>
</section> </section>
<section id="setup-auto-input"> <section id="setup-auto-input">
<title>Auto-Input</title> <title>Auto-Input</title>
<para></para> <para>
When a track is record-enabled, it is set to monitor input
regardless of the transport state. Auto input switches to off-disk monitoring
when play is engaged. When Ardour is actually recording, the track will be set to
monitor input again.
Auto-Input is useful for performing punch-ins. Disable auto-input when performing
'dry runs' of an overdub to allow a performer to hear themselves while the transport is rolling.
</para>
</section> </section>
<section id="setup-track-naming"> <section id="setup-track-naming">
@ -206,6 +261,18 @@
<section id="setup-punch-recording"> <section id="setup-punch-recording">
<title>Punch Recording</title> <title>Punch Recording</title>
<para>
Once you have recorded material onto a track, the simplest way to punch in
(or drop in as it is known elsewhere) is to roll the transport and press the
master record button at the desired in point. Assuming the desired track is
record enabled, its monitoring state will be switched and recording will begin.
Pressing it again disengages record.
If repeatable punch-ins are required, you may use auto punch.
</para>
</section>
<section id="setup-auto-punch">
<title>Auto Punch</title>
<para></para> <para></para>
</section> </section>

View file

@ -26,6 +26,8 @@ import string
import sys import sys
import xml.dom.minidom import xml.dom.minidom
v2paths = True
def get_header_size(filename): def get_header_size(filename):
size = 0 size = 0
file = open(filename, 'r') file = open(filename, 'r')
@ -111,7 +113,7 @@ class Data(object):
sessions[session_name]['collabs'][collab_name]['sounds'] = [] sessions[session_name]['collabs'][collab_name]['sounds'] = []
sessions[session_name]['collabs'][collab_name]['ip'] = ip_address sessions[session_name]['collabs'][collab_name]['ip'] = ip_address
sessions[session_name]['collabs'][collab_name]['port'] = port sessions[session_name]['collabs'][collab_name]['port'] = port
sessions[session_name]['collabs'][collab_name]['v2paths'] = true sessions[session_name]['collabs'][collab_name]['v2paths'] = True
self._data['sessions'] = sessions self._data['sessions'] = sessions
client = ExchangeClientFactory(session_name, collab_name, None, self.debug_mode) client = ExchangeClientFactory(session_name, collab_name, None, self.debug_mode)
@ -130,10 +132,11 @@ class Data(object):
sessions[session_name]['collabs'][self._data['user']] = {} sessions[session_name]['collabs'][self._data['user']] = {}
sessions[session_name]['collabs'][self._data['user']]['snaps'] = [] sessions[session_name]['collabs'][self._data['user']]['snaps'] = []
sessions[session_name]['collabs'][self._data['user']]['sounds'] = [] sessions[session_name]['collabs'][self._data['user']]['sounds'] = []
if os.path.test (os.path.join (session_path,'sounds')): if os.path.isdir (os.path.join (session_path,'sounds')):
sessions[session_name]['collabs'][collab_name]['v2paths'] = False sessions[session_name]['collabs'][self._data['user']]['v2paths'] = False
v2paths = False
else: else:
sessions[session_name]['collabs'][collab_name]['v2paths'] = True sessions[session_name]['collabs'][self._data['user']]['v2paths'] = True
self._data['sessions'] = sessions self._data['sessions'] = sessions
@ -144,7 +147,7 @@ class Data(object):
session_path = sessions[session_name]['path'] session_path = sessions[session_name]['path']
sessions[session_name]['collabs'][self._data['user']]['snaps'] = self._scan_snapshots(session_path) sessions[session_name]['collabs'][self._data['user']]['snaps'] = self._scan_snapshots(session_path)
sessions[session_name]['collabs'][self._data['user']]['sounds'] = self._scan_sounds(session_path) sessions[session_name]['collabs'][self._data['user']]['sounds'] = self._scan_sounds(session_name)
self._data['sessions'] = sessions self._data['sessions'] = sessions
@ -153,17 +156,18 @@ class Data(object):
print self._data['sessions'] print self._data['sessions']
def create_session(self, session_path): def create_session(self, session_path):
sessions = self._data['sessions']
session_name = session_path[session_path.rfind('/', 0, len(session_path)-2)+1: ]
try: try:
os.mkdir(session_path) os.mkdir(session_path)
os.mkdir(os.path.join (session_path,'interchange'))
os.mkdir(os.path.join (session_path,'interchange',session_name))
os.mkdir(os.path.join (session_path,'interchange',session_name,'audiofiles')) os.mkdir(os.path.join (session_path,'interchange',session_name,'audiofiles'))
except OSError: except OSError:
raise_error("Could not create session directory", g_display.window) raise_error("Could not create session directory", g_display.window)
return return
sessions = self._data['sessions']
session_name = session_path[session_path.rfind('/', 0, len(session_path)-2)+1: ]
sessions[session_name] = {} sessions[session_name] = {}
sessions[session_name]['path'] = session_path sessions[session_name]['path'] = session_path
sessions[session_name]['collabs'] = {} sessions[session_name]['collabs'] = {}
@ -235,9 +239,13 @@ class Data(object):
return snaps return snaps
def _scan_sounds(self, session): def _scan_sounds(self, session):
sessions = self._data['sessions']
sounds = [] sounds = []
if v2paths: if v2paths:
files = os.listdir(os.path.join (session,'interchange', session, 'audiofiles')) print session
print os.path.join (sessions[session]['path'],'interchange', session, 'audiofiles')
files = os.listdir(os.path.join (sessions[session]['path'],'interchange', session, 'audiofiles'))
else: else:
files = os.listdir(os.path.join (session,'sounds')) files = os.listdir(os.path.join (session,'sounds'))
pattern = re.compile(r'\.peak$') pattern = re.compile(r'\.peak$')
@ -322,7 +330,7 @@ class ExchangeServer (LineReceiver):
self.error("snapshot: " + data + " doesn't exist on server") self.error("snapshot: " + data + " doesn't exist on server")
elif self.state == "SOUNDFILE" or self.state == "SOUNDFILE_HEADER": elif self.state == "SOUNDFILE" or self.state == "SOUNDFILE_HEADER":
if g_data.get_sounds(self.session_name, g_data.get_user()).count(data): if g_data.get_sounds(self.session_name, g_data.get_user()).count(data):
filename = g_data.get_session_path(self.session_name)+"/sounds/"+data filename = g_data.get_session_path(self.session_name)+"/interchange/"+self.session_name+"/audiofiles/"+data
print filename print filename
if self.state == "SOUNDFILE": if self.state == "SOUNDFILE":
self.sendLine(str(os.stat(filename).st_size)) self.sendLine(str(os.stat(filename).st_size))
@ -450,7 +458,7 @@ class ExchangeClient (LineReceiver):
self.received = 0 self.received = 0
elif self.state == "SOUNDFILE" or self.state == "SOUNDFILE_HEADER": elif self.state == "SOUNDFILE" or self.state == "SOUNDFILE_HEADER":
self.setRawMode() self.setRawMode()
self.filename = g_data.get_session_path(self.session_name)+'/sounds/'+self.sounds[self.sound_index] self.filename = g_data.get_session_path(self.session_name)+"/interchange/"+self.session_name+"/audiofiles/"+self.sounds[self.sound_index]
self.file = open(self.filename, 'w') self.file = open(self.filename, 'w')
self.received = 0 self.received = 0
elif self.state == "ERROR": elif self.state == "ERROR":