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:
Paul Davis 2009-07-18 00:50:15 +00:00
parent 9b7e3a892a
commit 932cca703e
16 changed files with 173 additions and 24 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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) {

View file

@ -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));

View file

@ -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();

View file

@ -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;

View file

@ -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;

View file

@ -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;
};
}

View file

@ -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;

View file

@ -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&);
};
}

View file

@ -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 */

View file

@ -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;
}

View file

@ -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 ();
}

View file

@ -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 ();
};