mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-10 23:46:20 +01:00
imported files retain BWF timestamp info (nick murtagh) ; logarithm plugin controls can be properly controlled by generic GUI (nick murtagh); properly delete AU plugin *and* GUI (fixes crashing bug for Carbon-GUI based AU's)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@5374 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
9b7e3a892a
commit
932cca703e
16 changed files with 173 additions and 24 deletions
|
|
@ -51,6 +51,7 @@ opts.AddOptions(
|
|||
PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
|
||||
BoolOption('SURFACES', 'Build support for control surfaces', 1),
|
||||
BoolOption('WIIMOTE', 'Build the wiimote control surface', 0),
|
||||
('LIBDIR', 'Set librarydir (typically lib or lib64)', 'lib'),
|
||||
BoolOption('SYSLIBS', 'USE AT YOUR OWN RISK: CANCELS ALL SUPPORT FROM ARDOUR AUTHORS: Use existing system versions of various libraries instead of internal ones', 0),
|
||||
BoolOption('UNIVERSAL', 'Compile as universal binary. Requires that external libraries are already universal.', 0),
|
||||
BoolOption('VERSIONED', 'Add revision information to ardour/gtk executable name inside the build directory', 0),
|
||||
|
|
@ -736,7 +737,7 @@ if env['FPU_OPTIMIZATION']:
|
|||
opt_flags.append ("-DUSE_X86_64_ASM")
|
||||
debug_flags.append ("-DUSE_X86_64_ASM")
|
||||
if build_host_supports_sse != 1:
|
||||
print "\nWarning: you are building Ardour with SSE support even though your system does not support these instructions. (This may not be an error, especially if you are a package maintainer)"
|
||||
print "\nWarning: you are building Ardour with SSE support even though your system does not support these instructions. (This may not be anerror, especially if you are a package maintainer)"
|
||||
# end optimization section
|
||||
|
||||
# handle x86/x86_64 libdir properly
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ AUPluginUI::AUPluginUI (boost::shared_ptr<PluginInsert> insert)
|
|||
cocoa_window = 0;
|
||||
au_view = 0;
|
||||
packView = 0;
|
||||
editView = 0;
|
||||
|
||||
/* prefer cocoa, fall back to cocoa, but use carbon if its there */
|
||||
|
||||
|
|
@ -126,10 +127,14 @@ AUPluginUI::~AUPluginUI ()
|
|||
RemoveEventHandler(carbon_event_handler);
|
||||
[win removeChildWindow:cocoa_parent];
|
||||
} else if (carbon_window) {
|
||||
/* never parented */
|
||||
/* not parented, just overlaid on top of our window */
|
||||
DisposeWindow (carbon_window);
|
||||
}
|
||||
|
||||
if (editView) {
|
||||
CloseComponent (editView);
|
||||
}
|
||||
|
||||
if (packView) {
|
||||
/* remove whatever we packed into low_box so that GTK doesn't
|
||||
mess with it.
|
||||
|
|
@ -323,11 +328,14 @@ AUPluginUI::create_carbon_view ()
|
|||
|
||||
if ((err = CreateNewWindow(kDocumentWindowClass, attr, &r, &carbon_window)) != noErr) {
|
||||
error << string_compose (_("AUPluginUI: cannot create carbon window (err: %1)"), err) << endmsg;
|
||||
CloseComponent (editView);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((err = GetRootControl(carbon_window, &root_control)) != noErr) {
|
||||
error << string_compose (_("AUPlugin: cannot get root control of carbon window (err: %1)"), err) << endmsg;
|
||||
DisposeWindow (carbon_window);
|
||||
CloseComponent (editView);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -337,6 +345,8 @@ AUPluginUI::create_carbon_view ()
|
|||
|
||||
if ((err = AudioUnitCarbonViewCreate (editView, *au->get_au(), carbon_window, root_control, &location, &size, &viewPane)) != noErr) {
|
||||
error << string_compose (_("AUPluginUI: cannot create carbon plugin view (err: %1)"), err) << endmsg;
|
||||
DisposeWindow (carbon_window);
|
||||
CloseComponent (editView);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -683,8 +683,11 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64
|
|||
ustring region_name;
|
||||
uint32_t input_chan = 0;
|
||||
uint32_t output_chan = 0;
|
||||
bool use_timestamp;
|
||||
|
||||
use_timestamp = (pos == -1);
|
||||
|
||||
if (pos == -1) { // "use timestamp"
|
||||
if (use_timestamp) {
|
||||
if (sources[0]->natural_position() != 0) {
|
||||
pos = sources[0]->natural_position();
|
||||
} else {
|
||||
|
|
@ -697,10 +700,15 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64
|
|||
/* take all the sources we have and package them up as a region */
|
||||
|
||||
region_name = region_name_from_path (paths.front(), (sources.size() > 1), false);
|
||||
|
||||
regions.push_back (boost::dynamic_pointer_cast<AudioRegion>
|
||||
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>
|
||||
(RegionFactory::create (sources, 0, sources[0]->length(), region_name, 0,
|
||||
Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External))));
|
||||
Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
|
||||
|
||||
if (use_timestamp) {
|
||||
ar->special_set_position(sources[0]->natural_position());
|
||||
}
|
||||
|
||||
regions.push_back (ar);
|
||||
|
||||
} else if (target_regions == -1 || target_regions > 1) {
|
||||
|
||||
|
|
@ -718,11 +726,15 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64
|
|||
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*x);
|
||||
|
||||
region_name = region_name_from_path (afs->path(), false, true, sources.size(), n);
|
||||
|
||||
regions.push_back (boost::dynamic_pointer_cast<AudioRegion>
|
||||
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>
|
||||
(RegionFactory::create (just_one, 0, (*x)->length(), region_name, 0,
|
||||
Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External))));
|
||||
Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
|
||||
|
||||
if (use_timestamp) {
|
||||
ar->special_set_position((*x)->natural_position());
|
||||
}
|
||||
|
||||
regions.push_back (ar);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ Editor::add_edit_group (RouteGroup* group)
|
|||
|
||||
TreeModel::Row row = *(group_model->append());
|
||||
row[group_columns.is_active] = group->is_active();
|
||||
row[group_columns.is_visible] = !group->is_hidden();
|
||||
row[group_columns.is_visible] = false;
|
||||
|
||||
in_edit_group_row_change = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <ardour/route.h>
|
||||
#include <ardour/audio_track.h>
|
||||
#include <ardour/route_group.h>
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
|
@ -71,6 +72,14 @@ Editor::handle_new_route (Session::RouteList& routes)
|
|||
row[route_display_columns.visible] = tv->marked_for_display();
|
||||
row[route_display_columns.tv] = tv;
|
||||
|
||||
RouteGroup *group = route->edit_group();
|
||||
if (group) {
|
||||
if (tv->marked_for_display()) {
|
||||
group->set_hidden(false, this);
|
||||
group_flags_changed(this, group);
|
||||
}
|
||||
}
|
||||
|
||||
track_views.push_back (tv);
|
||||
|
||||
if ((atv = dynamic_cast<AudioTimeAxisView*> (tv)) != 0) {
|
||||
|
|
|
|||
|
|
@ -494,6 +494,7 @@ GenericPluginUI::build_control_ui (guint32 port_index, PBD::Controllable* mcontr
|
|||
control_ui->control->set_name (X_("PluginSlider"));
|
||||
control_ui->control->set_style (BarController::LeftToRight);
|
||||
control_ui->control->set_use_parent (true);
|
||||
control_ui->control->set_logarithmic (control_ui->logarithmic);
|
||||
|
||||
control_ui->control->StartGesture.connect (bind (mem_fun(*this, &GenericPluginUI::start_touch), control_ui));
|
||||
control_ui->control->StopGesture.connect (bind (mem_fun(*this, &GenericPluginUI::stop_touch), control_ui));
|
||||
|
|
|
|||
|
|
@ -1233,7 +1233,18 @@ Mixer_UI::add_mix_group (RouteGroup* group)
|
|||
|
||||
TreeModel::Row row = *(group_model->append());
|
||||
row[group_columns.active] = group->is_active();
|
||||
row[group_columns.visible] = true;
|
||||
|
||||
row[group_columns.visible] = false;
|
||||
|
||||
for (list<MixerStrip *>::iterator i = strips.begin(); i != strips.end(); ++i) {
|
||||
if ((*i)->mix_group() == group) {
|
||||
if ((*i)->marked_for_display()) {
|
||||
row[group_columns.visible] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
row[group_columns.group] = group;
|
||||
if (!group->name().empty()) {
|
||||
row[group_columns.text] = group->name();
|
||||
|
|
|
|||
|
|
@ -125,6 +125,8 @@ class AudioFileSource : public AudioSource {
|
|||
|
||||
bool can_be_analysed() const { return _length > 0; }
|
||||
|
||||
virtual void set_timeline_position (int64_t pos);
|
||||
|
||||
static bool find (Glib::ustring path, bool must_exist, bool embedded, bool& is_new, uint16_t& chan,
|
||||
Glib::ustring& found_path, std::string& found_name);
|
||||
|
||||
|
|
@ -164,7 +166,6 @@ class AudioFileSource : public AudioSource {
|
|||
|
||||
static uint64_t header_position_offset;
|
||||
|
||||
virtual void set_timeline_position (int64_t pos);
|
||||
virtual void set_header_timeline_position () = 0;
|
||||
|
||||
bool removable() const;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ class CAImportableSource : public ImportableSource {
|
|||
nframes_t length() const;
|
||||
nframes_t samplerate() const;
|
||||
void seek (nframes_t pos);
|
||||
nframes_t natural_position() const { return 0; }
|
||||
|
||||
protected:
|
||||
mutable CAAudioFile af;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ public:
|
|||
virtual nframes_t length() const = 0;
|
||||
virtual nframes_t samplerate() const = 0;
|
||||
virtual void seek (nframes_t pos) = 0;
|
||||
virtual nframes_t natural_position() const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class ResampledImportableSource : public ImportableSource
|
|||
nframes_t length() const { return source->length(); }
|
||||
nframes_t samplerate() const { return source->samplerate(); }
|
||||
void seek (nframes_t pos) { source->seek (pos); }
|
||||
nframes_t natural_position() const { return source->natural_position(); }
|
||||
|
||||
static const uint32_t blocksize;
|
||||
|
||||
|
|
|
|||
|
|
@ -38,11 +38,13 @@ class SndFileImportableSource : public ImportableSource {
|
|||
nframes_t length() const;
|
||||
nframes_t samplerate() const;
|
||||
void seek (nframes_t pos);
|
||||
nframes_t natural_position() const;
|
||||
|
||||
protected:
|
||||
SF_INFO sf_info;
|
||||
boost::shared_ptr<SNDFILE> in;
|
||||
|
||||
nframes_t timecode;
|
||||
int64_t get_timecode_info (SNDFILE*, SF_BROADCAST_INFO*, bool&);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -193,8 +193,11 @@ map_existing_mono_sources (const vector<string>& new_paths, Session& sess,
|
|||
|
||||
static bool
|
||||
create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess,
|
||||
uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles)
|
||||
uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles,
|
||||
nframes_t timeline_position)
|
||||
{
|
||||
boost::shared_ptr<AudioFileSource> afs;
|
||||
|
||||
for (vector<string>::const_iterator i = new_paths.begin();
|
||||
i != new_paths.end(); ++i)
|
||||
{
|
||||
|
|
@ -215,7 +218,9 @@ create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess,
|
|||
return false;
|
||||
}
|
||||
|
||||
newfiles.push_back(boost::dynamic_pointer_cast<AudioFileSource>(source));
|
||||
afs = boost::dynamic_pointer_cast<AudioFileSource>(source);
|
||||
afs->set_timeline_position(timeline_position);
|
||||
newfiles.push_back(afs);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -337,7 +342,7 @@ Session::import_audiofiles (import_status& status)
|
|||
fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endl;
|
||||
status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
|
||||
} else {
|
||||
status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles);
|
||||
status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, source->natural_position());
|
||||
}
|
||||
|
||||
// copy on cancel/failure so that any files that were created will be removed below
|
||||
|
|
@ -366,7 +371,7 @@ Session::import_audiofiles (import_status& status)
|
|||
|
||||
for (AudioSources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ++x)
|
||||
{
|
||||
(*x)->update_header(0, *now, xnow);
|
||||
(*x)->update_header((*x)->natural_position(), *now, xnow);
|
||||
(*x)->done_with_peakfile_writes ();
|
||||
|
||||
/* now that there is data there, requeue the file for analysis */
|
||||
|
|
|
|||
|
|
@ -1,16 +1,43 @@
|
|||
#include <ardour/sndfileimportable.h>
|
||||
#include <sndfile.h>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <string.h>
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace std;
|
||||
|
||||
/* FIXME: this was copied from sndfilesource.cc, at some point these should be merged */
|
||||
int64_t
|
||||
SndFileImportableSource::get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& exists)
|
||||
{
|
||||
if (sf_command (sf, SFC_GET_BROADCAST_INFO, binfo, sizeof (*binfo)) != SF_TRUE) {
|
||||
exists = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
exists = true;
|
||||
int64_t ret = (uint32_t) binfo->time_reference_high;
|
||||
ret <<= 32;
|
||||
ret |= (uint32_t) binfo->time_reference_low;
|
||||
return ret;
|
||||
}
|
||||
|
||||
SndFileImportableSource::SndFileImportableSource (const string& path)
|
||||
{
|
||||
memset(&sf_info, 0 , sizeof(sf_info));
|
||||
in.reset( sf_open(path.c_str(), SFM_READ, &sf_info), sf_close);
|
||||
if (!in) throw failed_constructor();
|
||||
|
||||
SF_BROADCAST_INFO binfo;
|
||||
bool timecode_exists;
|
||||
|
||||
memset (&binfo, 0, sizeof (binfo));
|
||||
timecode = get_timecode_info (in.get(), &binfo, timecode_exists);
|
||||
|
||||
if (!timecode_exists) {
|
||||
timecode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SndFileImportableSource::~SndFileImportableSource ()
|
||||
|
|
@ -48,3 +75,9 @@ SndFileImportableSource::seek (nframes_t pos)
|
|||
{
|
||||
sf_seek (in.get(), 0, SEEK_SET);
|
||||
}
|
||||
|
||||
nframes_t
|
||||
SndFileImportableSource::natural_position () const
|
||||
{
|
||||
return timecode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <climits>
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
|
|
@ -51,6 +52,7 @@ BarController::BarController (Gtk::Adjustment& adj,
|
|||
switch_on_release = false;
|
||||
with_text = true;
|
||||
use_parent = false;
|
||||
logarithmic = false;
|
||||
|
||||
layout = darea.create_pango_layout("");
|
||||
|
||||
|
|
@ -76,12 +78,72 @@ BarController::BarController (Gtk::Adjustment& adj,
|
|||
|
||||
spinner.signal_activate().connect (mem_fun (*this, &BarController::entry_activated));
|
||||
spinner.signal_focus_out_event().connect (mem_fun (*this, &BarController::entry_focus_out));
|
||||
spinner.signal_output().connect (mem_fun (*this, &BarController::entry_output));
|
||||
spinner.signal_input().connect (mem_fun (*this, &BarController::entry_input));
|
||||
spinner.set_digits (3);
|
||||
spinner.set_numeric (true);
|
||||
|
||||
add (darea);
|
||||
show_all ();
|
||||
}
|
||||
|
||||
/*
|
||||
This is called when we need to update the adjustment with the value
|
||||
from the spinner's text entry.
|
||||
|
||||
We need to use Gtk::Entry::get_text to avoid recursive nastiness :)
|
||||
|
||||
If we're not in logarithmic mode we can return false to use the
|
||||
default conversion.
|
||||
|
||||
In theory we should check for conversion errors but set numeric
|
||||
mode to true on the spinner prevents invalid input.
|
||||
*/
|
||||
int
|
||||
BarController::entry_input (double* new_value)
|
||||
{
|
||||
if (!logarithmic) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// extract a double from the string and take its log
|
||||
Entry *entry = dynamic_cast<Entry *>(&spinner);
|
||||
stringstream stream(entry->get_text());
|
||||
|
||||
double value;
|
||||
stream >> value;
|
||||
|
||||
*new_value = log(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
This is called when we need to update the spinner's text entry
|
||||
with the value of the adjustment.
|
||||
|
||||
We need to use Gtk::Entry::set_text to avoid recursive nastiness :)
|
||||
|
||||
If we're not in logarithmic mode we can return false to use the
|
||||
default conversion.
|
||||
*/
|
||||
bool
|
||||
BarController::entry_output ()
|
||||
{
|
||||
if (!logarithmic) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// generate the exponential and turn it into a string
|
||||
stringstream stream;
|
||||
stream.precision(spinner.get_digits());
|
||||
stream << fixed << exp(spinner.get_adjustment()->get_value());
|
||||
|
||||
Entry *entry = dynamic_cast<Entry *>(&spinner);
|
||||
entry->set_text(stream.str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BarController::drop_grab ()
|
||||
{
|
||||
|
|
@ -436,13 +498,6 @@ BarController::switch_to_spinner ()
|
|||
void
|
||||
BarController::entry_activated ()
|
||||
{
|
||||
string text = spinner.get_text ();
|
||||
float val;
|
||||
|
||||
if (sscanf (text.c_str(), "%f", &val) == 1) {
|
||||
adjustment.set_value (val);
|
||||
}
|
||||
|
||||
switch_to_bar ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ class BarController : public Gtk::Frame
|
|||
void set_use_parent (bool yn);
|
||||
|
||||
void set_sensitive (bool yn);
|
||||
|
||||
void set_logarithmic (bool yn) { logarithmic = yn; }
|
||||
|
||||
Gtk::SpinButton& get_spin_button() { return spinner; }
|
||||
|
||||
|
|
@ -77,6 +79,7 @@ class BarController : public Gtk::Frame
|
|||
GdkWindow* grab_window;
|
||||
Gtk::SpinButton spinner;
|
||||
bool use_parent;
|
||||
bool logarithmic;
|
||||
|
||||
virtual bool button_press (GdkEventButton *);
|
||||
virtual bool button_release (GdkEventButton *);
|
||||
|
|
@ -92,6 +95,9 @@ class BarController : public Gtk::Frame
|
|||
|
||||
void entry_activated ();
|
||||
void drop_grab ();
|
||||
|
||||
int entry_input (double* new_value);
|
||||
bool entry_output ();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue