more changes for the import dialog, with breakout of importable source code into its own files

git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2437 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2007-09-09 13:04:23 +00:00
parent d0cd7d0048
commit 40bc1c239e
12 changed files with 300 additions and 141 deletions

View file

@ -981,7 +981,7 @@ class Editor : public PublicEditor
nframes64_t& pos, int target_regions, int target_tracks, boost::shared_ptr<ARDOUR::AudioTrack>&);
int add_sources (vector<Glib::ustring> paths, ARDOUR::SourceList& sources, nframes64_t& pos, Editing::ImportMode,
int target_regions, int target_tracks, boost::shared_ptr<ARDOUR::AudioTrack>&);
int target_regions, int target_tracks, boost::shared_ptr<ARDOUR::AudioTrack>&, bool add_channel_suffix);
int finish_bringing_in_audio (boost::shared_ptr<ARDOUR::AudioRegion> region, uint32_t, uint32_t, nframes64_t& pos, Editing::ImportMode mode,
boost::shared_ptr<ARDOUR::AudioTrack>& existing_track);

View file

@ -367,7 +367,7 @@ Editor::import_sndfiles (vector<ustring> paths, ImportMode mode, nframes64_t& po
goto out;
}
if (add_sources (paths, import_status.sources, pos, mode, target_regions, target_tracks, track) == 0) {
if (add_sources (paths, import_status.sources, pos, mode, target_regions, target_tracks, track, false) == 0) {
session->save_state ("");
}
@ -523,7 +523,7 @@ Editor::embed_sndfiles (vector<Glib::ustring> paths, bool multifile,
goto out;
}
ret = add_sources (paths, sources, pos, mode, target_regions, target_tracks, track);
ret = add_sources (paths, sources, pos, mode, target_regions, target_tracks, track, true);
out:
track_canvas.get_window()->set_cursor (*current_canvas_cursor);
@ -532,7 +532,7 @@ Editor::embed_sndfiles (vector<Glib::ustring> paths, bool multifile,
int
Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64_t& pos, ImportMode mode,
int target_regions, int target_tracks, boost::shared_ptr<AudioTrack>& track)
int target_regions, int target_tracks, boost::shared_ptr<AudioTrack>& track, bool add_channel_suffix)
{
vector<boost::shared_ptr<AudioRegion> > regions;
ustring region_name;
@ -552,7 +552,7 @@ 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));
region_name = region_name_from_path (paths.front(), (sources.size() > 1), false);
regions.push_back (boost::dynamic_pointer_cast<AudioRegion>
(RegionFactory::create (sources, 0, sources[0]->length(), region_name, 0,
@ -564,15 +564,18 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64
SourceList just_one;
SourceList::iterator x;
uint32_t n;
for (x = sources.begin(); x != sources.end(); ++x) {
for (n = 0, x = sources.begin(); x != sources.end(); ++x, ++n) {
just_one.clear ();
just_one.push_back (*x);
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*x);
region_name = region_name_from_path (afs->path(), false);
region_name = region_name_from_path (afs->path(), false, true, sources.size(), n);
cerr << "got region name " << region_name << endl;
regions.push_back (boost::dynamic_pointer_cast<AudioRegion>
(RegionFactory::create (just_one, 0, (*x)->length(), region_name, 0,
@ -597,10 +600,12 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64
output_chan = input_chan;
}
for (vector<boost::shared_ptr<AudioRegion> >::iterator r = regions.begin(); r != regions.end(); ++r) {
int n = 0;
for (vector<boost::shared_ptr<AudioRegion> >::iterator r = regions.begin(); r != regions.end(); ++r, ++n) {
finish_bringing_in_audio (*r, input_chan, output_chan, pos, mode, track);
if (target_tracks != 1) {
track.reset ();
} else {
@ -652,12 +657,15 @@ Editor::finish_bringing_in_audio (boost::shared_ptr<AudioRegion> region, uint32_
{
if (!existing_track) {
list<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Normal, 1));
if (at.empty()) {
return -1;
}
existing_track = at.front();
existing_track->set_name (basename_nosuffix (region->name()), this);
existing_track->set_name (region->name(), this);
}
boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
existing_track->diskstream()->playlist()->add_region (copy, pos);
break;

View file

@ -134,21 +134,11 @@ Editor::add_audio_region_to_region_display (boost::shared_ptr<AudioRegion> regio
if (region->source()->name()[0] == '/') { // external file
if (region->whole_file()) {
/* XXX there was old code here to try to show an abbreviated version
of the path name for whole file regions.
*/
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(region->source());
str = ".../";
if (afs) {
str = region_name_from_path (afs->path(), region->n_channels() > 1);
} else {
str += region->source()->name();
}
} else {
str = region->name();
}
str = region->name();
} else {

View file

@ -65,8 +65,8 @@ ustring SoundFileBrowser::persistent_folder;
SoundFileBox::SoundFileBox ()
: _session(0),
table (6, 2),
length_clock ("sfboxLengthClock", true, "EditCursorClock", false, true, false),
timecode_clock ("sfboxTimecodeClock", true, "EditCursorClock", false, false, false),
length_clock ("sfboxLengthClock", false, "EditCursorClock", false, true, false),
timecode_clock ("sfboxTimecodeClock", false, "EditCursorClock", false, false, false),
main_box (false, 6),
autoplay_btn (_("Auto-play"))
@ -110,7 +110,7 @@ SoundFileBox::SoundFileBox ()
table.attach (length_clock, 1, 2, 4, 5, FILL, (AttachOptions) 0);
table.attach (timecode_clock, 1, 2, 5, 6, FILL, (AttachOptions) 0);
length_clock.set_mode (AudioClock::MinSec);
length_clock.set_mode (ARDOUR_UI::instance()->secondary_clock.mode());
timecode_clock.set_mode (AudioClock::SMPTE);
hbox = manage (new HBox);
@ -204,7 +204,18 @@ SoundFileBox::setup_labels (const ustring& filename)
preview_label.set_markup (string_compose ("<b>%1</b>", Glib::path_get_basename (filename)));
format_text.set_text (sf_info.format_name);
channels_value.set_text (to_string (sf_info.channels, std::dec));
samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
if (_session && sf_info.samplerate != _session->frame_rate()) {
samplerate.set_markup (string_compose ("<b>%1</b>", _("Sample rate:")));
samplerate_value.set_markup (string_compose (X_("<b>%1 Hz</b>"), sf_info.samplerate));
samplerate_value.set_name ("NewSessionSR1Label");
samplerate.set_name ("NewSessionSR1Label");
} else {
samplerate.set_text (_("Sample rate:"));
samplerate_value.set_text (string_compose (X_("%1 Hz"), sf_info.samplerate));
samplerate_value.set_name ("NewSessionSR2Label");
samplerate.set_name ("NewSessionSR2Label");
}
length_clock.set (sf_info.length, true);
timecode_clock.set (sf_info.timecode, true);
@ -781,6 +792,15 @@ SoundFileChooser::SoundFileChooser (Gtk::Window& parent, string title, ARDOUR::S
found_list_view.get_selection()->set_mode (SELECTION_SINGLE);
}
void
SoundFileChooser::on_hide ()
{
ArdourDialog::on_hide();
if (session) {
session->cancel_audition();
}
}
ustring
SoundFileChooser::get_filename ()
{
@ -903,6 +923,15 @@ SoundFileOmega::get_mode () const
}
}
void
SoundFileOmega::on_hide ()
{
ArdourDialog::on_hide();
if (session) {
session->cancel_audition();
}
}
ImportPosition
SoundFileOmega::get_position() const
{

View file

@ -158,6 +158,9 @@ class SoundFileChooser : public SoundFileBrowser
Glib::ustring get_filename ();
protected:
void on_hide();
private:
// SoundFileBrowser browser;
};
@ -180,6 +183,9 @@ class SoundFileOmega : public SoundFileBrowser
Editing::ImportPosition get_position() const;
Editing::ImportDisposition get_channel_disposition() const;
protected:
void on_hide();
private:
uint32_t selected_track_cnt;

View file

@ -71,6 +71,7 @@ recent_sessions.cc
redirect.cc
region.cc
region_factory.cc
resampled_source.cc
reverse.cc
route.cc
route_group.cc

View file

@ -0,0 +1,48 @@
/*
Copyright (C) 2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_importable_source_h__
#define __ardour_importable_source_h__
#include <sndfile.h>
#include <ardour/types.h>
namespace ARDOUR {
class ImportableSource {
public:
ImportableSource (SNDFILE* sf, SF_INFO* info) : in (sf), sf_info (info) {}
virtual ~ImportableSource() {}
virtual nframes_t read (Sample* buffer, nframes_t nframes) {
nframes_t per_channel = nframes / sf_info->channels;
per_channel = sf_readf_float (in, buffer, per_channel);
return per_channel * sf_info->channels;
}
virtual float ratio() const { return 1.0f; }
protected:
SNDFILE* in;
SF_INFO* sf_info;
};
}
#endif /* __ardour_importable_source_h__ */

View file

@ -0,0 +1,49 @@
/*
Copyright (C) 2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_resampled_source_h__
#define __ardour_resampled_source_h__
#include <samplerate.h>
#include <ardour/importable_source.h>
namespace ARDOUR {
class ResampledImportableSource : public ImportableSource
{
public:
ResampledImportableSource (SNDFILE* sf, SF_INFO* info, nframes_t rate);
~ResampledImportableSource ();
nframes_t read (Sample* buffer, nframes_t nframes);
float ratio() const { return src_data.src_ratio; }
static const uint32_t blocksize;
private:
float* input;
SRC_STATE* src_state;
SRC_DATA src_data;
};
}
#endif /* __ardour_resampled_source_h__ */

View file

@ -53,7 +53,7 @@ int tokenize_fullpath (std::string fullpath, std::string& path, std::string& nam
int touch_file(Glib::ustring path);
Glib::ustring path_expand (Glib::ustring);
Glib::ustring region_name_from_path (Glib::ustring path, bool strip_channels);
Glib::ustring region_name_from_path (Glib::ustring path, bool strip_channels, bool add_channel_suffix = false, uint32_t total = 0, uint32_t this_one = 0);
bool path_is_paired (Glib::ustring path, Glib::ustring& pair_base);
void compute_equal_power_fades (nframes_t nframes, float* in, float* out);

View file

@ -32,6 +32,7 @@
#include <glibmm.h>
#include <pbd/basename.h>
#include <pbd/convert.h>
#include <ardour/ardour.h>
#include <ardour/session.h>
@ -41,72 +42,13 @@
#include <ardour/audioregion.h>
#include <ardour/region_factory.h>
#include <ardour/source_factory.h>
#include <ardour/resampled_source.h>
#include "i18n.h"
using namespace ARDOUR;
using namespace PBD;
#define BLOCKSIZE 4096U
class ImportableSource {
public:
ImportableSource (SNDFILE* sf, SF_INFO* info) : in (sf), sf_info (info) {}
virtual ~ImportableSource() {}
virtual nframes_t read (Sample* buffer, nframes_t nframes) {
nframes_t per_channel = nframes / sf_info->channels;
per_channel = sf_readf_float (in, buffer, per_channel);
return per_channel * sf_info->channels;
}
virtual float ratio() const { return 1.0f; }
protected:
SNDFILE* in;
SF_INFO* sf_info;
};
class ResampledImportableSource : public ImportableSource {
public:
ResampledImportableSource (SNDFILE* sf, SF_INFO* info, nframes_t rate) : ImportableSource (sf, info) {
int err;
sf_seek (in, 0, SEEK_SET) ;
/* Initialize the sample rate converter. */
if ((src_state = src_new (SRC_SINC_BEST_QUALITY, sf_info->channels, &err)) == 0) {
error << string_compose(_("Import: src_new() failed : %1"), src_strerror (err)) << endmsg ;
throw failed_constructor ();
}
src_data.end_of_input = 0 ; /* Set this later. */
/* Start with zero to force load in while loop. */
src_data.input_frames = 0 ;
src_data.data_in = input ;
src_data.src_ratio = ((float) rate) / sf_info->samplerate ;
}
~ResampledImportableSource () {
src_state = src_delete (src_state) ;
}
nframes_t read (Sample* buffer, nframes_t nframes);
float ratio() const { return src_data.src_ratio; }
private:
float input[BLOCKSIZE];
SRC_STATE* src_state;
SRC_DATA src_data;
};
int
Session::import_audiofile (import_status& status)
{
@ -124,11 +66,12 @@ Session::import_audiofile (import_status& status)
vector<string> new_paths;
struct tm* now;
ImportableSource* importable = 0;
const nframes_t nframes = BLOCKSIZE;
const nframes_t nframes = ResampledImportableSource::blocksize;
uint32_t cnt = 1;
status.sources.clear ();
for (vector<Glib::ustring>::iterator p = status.paths.begin(); p != status.paths.end(); ++p) {
for (vector<Glib::ustring>::iterator p = status.paths.begin(); p != status.paths.end(); ++p, ++cnt) {
if ((in = sf_open ((*p).c_str(), SFM_READ, &info)) == 0) {
error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
@ -207,7 +150,20 @@ Session::import_audiofile (import_status& status)
so_far = 0;
status.doing_what = _("converting audio");
if ((nframes_t) info.samplerate != frame_rate()) {
status.doing_what = string_compose (_("converting %1\n(resample from %2KHz to %3KHz)\n(%4 of %5)"),
basepath,
info.samplerate/1000.0f,
frame_rate()/1000.0f,
cnt, status.paths.size());
} else {
status.doing_what = string_compose (_("converting %1\n(%2 of %3)"),
basepath,
cnt, status.paths.size());
}
status.progress = 0.0;
while (!status.cancel) {
@ -305,50 +261,3 @@ Session::import_audiofile (import_status& status)
return ret;
}
nframes_t
ResampledImportableSource::read (Sample* output, nframes_t nframes)
{
int err;
/* If the input buffer is empty, refill it. */
if (src_data.input_frames == 0) {
src_data.input_frames = ImportableSource::read (input, BLOCKSIZE);
/* The last read will not be a full buffer, so set end_of_input. */
if ((nframes_t) src_data.input_frames < BLOCKSIZE) {
src_data.end_of_input = SF_TRUE ;
}
src_data.input_frames /= sf_info->channels;
src_data.data_in = input ;
}
src_data.data_out = output;
if (!src_data.end_of_input) {
src_data.output_frames = nframes / sf_info->channels ;
} else {
src_data.output_frames = src_data.input_frames;
}
if ((err = src_process (src_state, &src_data))) {
error << string_compose(_("Import: %1"), src_strerror (err)) << endmsg ;
return 0 ;
}
/* Terminate if at end */
if (src_data.end_of_input && src_data.output_frames_gen == 0) {
return 0;
}
src_data.data_in += src_data.input_frames_used * sf_info->channels ;
src_data.input_frames -= src_data.input_frames_used ;
return src_data.output_frames_gen * sf_info->channels;
}

View file

@ -0,0 +1,108 @@
/*
Copyright (C) 2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <pbd/error.h>
#include <ardour/resampled_source.h>
#include <pbd/failed_constructor.h>
#include "i18n.h"
using namespace ARDOUR;
using namespace PBD;
const uint32_t ResampledImportableSource::blocksize = 4096U;
ResampledImportableSource::ResampledImportableSource (SNDFILE* sf, SF_INFO* info, nframes_t rate)
: ImportableSource (sf, info)
{
int err;
sf_seek (in, 0, SEEK_SET) ;
/* Initialize the sample rate converter. */
if ((src_state = src_new (SRC_SINC_BEST_QUALITY, sf_info->channels, &err)) == 0) {
error << string_compose(_("Import: src_new() failed : %1"), src_strerror (err)) << endmsg ;
throw failed_constructor ();
}
src_data.end_of_input = 0 ; /* Set this later. */
/* Start with zero to force load in while loop. */
src_data.input_frames = 0 ;
src_data.data_in = input ;
src_data.src_ratio = ((float) rate) / sf_info->samplerate ;
input = new float[blocksize];
}
ResampledImportableSource::~ResampledImportableSource ()
{
src_state = src_delete (src_state) ;
delete [] input;
}
nframes_t
ResampledImportableSource::read (Sample* output, nframes_t nframes)
{
int err;
/* If the input buffer is empty, refill it. */
if (src_data.input_frames == 0) {
src_data.input_frames = ImportableSource::read (input, blocksize);
/* The last read will not be a full buffer, so set end_of_input. */
if ((nframes_t) src_data.input_frames < blocksize) {
src_data.end_of_input = SF_TRUE ;
}
src_data.input_frames /= sf_info->channels;
src_data.data_in = input ;
}
src_data.data_out = output;
if (!src_data.end_of_input) {
src_data.output_frames = nframes / sf_info->channels ;
} else {
src_data.output_frames = src_data.input_frames;
}
if ((err = src_process (src_state, &src_data))) {
error << string_compose(_("Import: %1"), src_strerror (err)) << endmsg ;
return 0 ;
}
/* Terminate if at end */
if (src_data.end_of_input && src_data.output_frames_gen == 0) {
return 0;
}
src_data.data_in += src_data.input_frames_used * sf_info->channels ;
src_data.input_frames -= src_data.input_frames_used ;
return src_data.output_frames_gen * sf_info->channels;
}

View file

@ -208,7 +208,7 @@ touch_file (ustring path)
}
ustring
region_name_from_path (ustring path, bool strip_channels)
region_name_from_path (ustring path, bool strip_channels, bool add_channel_suffix, uint32_t total, uint32_t this_one)
{
path = PBD::basename_nosuffix (path);
@ -225,6 +225,17 @@ region_name_from_path (ustring path, bool strip_channels)
}
}
if (add_channel_suffix) {
path += '%';
if (total > 2) {
path += (char) ('a' + this_one);
} else {
path += (char) (this_one == 0 ? 'L' : 'R');
}
}
return path;
}