mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-24 15:37:48 +01:00
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:
parent
d0cd7d0048
commit
40bc1c239e
12 changed files with 300 additions and 141 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ recent_sessions.cc
|
|||
redirect.cc
|
||||
region.cc
|
||||
region_factory.cc
|
||||
resampled_source.cc
|
||||
reverse.cc
|
||||
route.cc
|
||||
route_group.cc
|
||||
|
|
|
|||
48
libs/ardour/ardour/importable_source.h
Normal file
48
libs/ardour/ardour/importable_source.h
Normal 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__ */
|
||||
49
libs/ardour/ardour/resampled_source.h
Normal file
49
libs/ardour/ardour/resampled_source.h
Normal 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__ */
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
108
libs/ardour/resampled_source.cc
Normal file
108
libs/ardour/resampled_source.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue