lots of fidgety work to get track renaming to work correctly now that we have to rename audio files too; some GUI tweaks
git-svn-id: svn://localhost/trunk/ardour2@404 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
6097ce578b
commit
5e836403ad
@ -188,6 +188,7 @@ fft_result.cc
|
||||
""")
|
||||
|
||||
glade_files=glob.glob('glade/*.glade')
|
||||
pixmap_files=glob.glob('pixmaps/*.xpm')
|
||||
|
||||
intl_files = gtkardour_files + glade_files + glob.glob('*.h')
|
||||
|
||||
@ -244,19 +245,20 @@ env.Alias('install', env.InstallAs(os.path.join(install_prefix, 'bin')+'/ardour'
|
||||
env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour'), 'ardour2_ui.rc'))
|
||||
env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour'), 'ardour.menus'))
|
||||
env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour'), 'ardour.bindings'))
|
||||
env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour'), 'ardour.colors'))
|
||||
env.Alias('install', env.Install(os.path.join(install_prefix, 'share/ardour'), 'splash.ppm'))
|
||||
env.Alias('install', env.Install(os.path.join(install_prefix, 'share/ardour/pixmaps'), pixmap_files))
|
||||
env.Alias('install', env.Install(os.path.join(install_prefix, 'share/ardour/glade'), glade_files))
|
||||
|
||||
#dist
|
||||
env.Alias ('tarball', env.Distribute (env['DISTTREE'],
|
||||
[ 'SConscript',
|
||||
'i18n.h', 'gettext.h',
|
||||
'editor_xpms', 'misc_xpms',
|
||||
'crossfade_xpms.h', 'meter_xpms.h',
|
||||
'ardour2_ui.rc', 'splash.ppm',
|
||||
'ardour.menus', 'ardour.bindings'
|
||||
'ardour.menus', 'ardour.bindings', 'ardour.colors',
|
||||
'editor_xpms'
|
||||
] +
|
||||
gtkardour_files + vst_files + glade_files +
|
||||
gtkardour_files + vst_files + glade_files + pixmap_files +
|
||||
glob.glob('po/*.po') + glob.glob('*.h')))
|
||||
|
||||
# generate a prototype full-featured ardour_ui.rc file
|
||||
|
@ -1,8 +1,8 @@
|
||||
cWaveForm 0.50 1.0 1.0 0.90
|
||||
cWaveForm 0.0 0.0 0.0 0.80
|
||||
cMutedWaveForm 0.35 0.35 0.35 1.0
|
||||
cSelectedFrameBase 0.63 0.13 0.94 0.2
|
||||
cFrameBase 0.0 0.0 0.0 0.25
|
||||
cAudioTrackBase 0.30 0.30 0.30 0.25
|
||||
cSelectedFrameBase 0.71 0.57 0.66 1.0
|
||||
cFrameBase 0.75 0.75 0.76 1.0
|
||||
cAudioTrackBase 0.79 0.80 0.85 0.41
|
||||
cAudioTrackOutline 0.00 0.00 0.00 1.00
|
||||
cAudioBusBase 0.90 0.82 0.90 0.41
|
||||
cTempoBar 0.64 0.64 0.66 1.0
|
||||
|
@ -427,20 +427,18 @@ Editor::Editor (AudioEngine& eng)
|
||||
edit_packer.set_col_spacings (0);
|
||||
edit_packer.set_row_spacings (0);
|
||||
edit_packer.set_homogeneous (false);
|
||||
edit_packer.set_border_width (0);
|
||||
edit_packer.set_name ("EditorWindow");
|
||||
|
||||
edit_packer.attach (edit_vscrollbar, 0, 1, 1, 3, FILL, FILL|EXPAND, 0, 0);
|
||||
|
||||
edit_packer.attach (edit_hscrollbar, 1, 2, 0, 1, FILL|EXPAND, FILL, 0, 0);
|
||||
edit_packer.attach (time_button_event_box, 1, 2, 0, 1, FILL, FILL, 0, 0);
|
||||
edit_packer.attach (time_canvas_event_box, 2, 3, 0, 1, FILL|EXPAND, FILL, 0, 0);
|
||||
|
||||
edit_packer.attach (time_button_event_box, 0, 1, 1, 2, FILL, FILL, 0, 0);
|
||||
edit_packer.attach (time_canvas_event_box, 1, 2, 1, 2, FILL|EXPAND, FILL, 0, 0);
|
||||
edit_packer.attach (controls_layout, 1, 2, 1, 2, FILL, FILL|EXPAND, 0, 0);
|
||||
edit_packer.attach (track_canvas_event_box, 2, 3, 1, 2, FILL|EXPAND, FILL|EXPAND, 0, 0);
|
||||
|
||||
edit_packer.attach (controls_layout, 0, 1, 2, 3, FILL, FILL|EXPAND, 0, 0);
|
||||
edit_packer.attach (track_canvas_event_box, 1, 2, 2, 3, FILL|EXPAND, FILL|EXPAND, 0, 0);
|
||||
edit_packer.attach (edit_vscrollbar, 2, 3, 2, 3, FILL, FILL|EXPAND, 0, 0);
|
||||
|
||||
edit_frame.set_name ("BaseFrame");
|
||||
edit_frame.set_shadow_type (SHADOW_IN);
|
||||
edit_frame.add (edit_packer);
|
||||
edit_packer.attach (edit_hscrollbar, 2, 3, 2, 3, FILL|EXPAND, FILL, 0, 0);
|
||||
|
||||
zoom_in_button.set_name ("EditorTimeButton");
|
||||
zoom_out_button.set_name ("EditorTimeButton");
|
||||
@ -637,20 +635,31 @@ Editor::Editor (AudioEngine& eng)
|
||||
snapshot_display.get_selection()->signal_changed().connect (mem_fun(*this, &Editor::snapshot_display_selection_changed));
|
||||
snapshot_display.signal_button_press_event().connect (mem_fun (*this, &Editor::snapshot_display_button_press), false);
|
||||
|
||||
the_notebook.append_page (region_list_scroller, _("Regions"));
|
||||
the_notebook.append_page (route_list_scroller, _("Tracks/Busses"));
|
||||
the_notebook.append_page (snapshot_display_scroller, _("Snapshots"));
|
||||
the_notebook.append_page (*edit_group_display_packer, _("Edit Groups"));
|
||||
the_notebook.append_page (named_selection_scroller, _("Chunks"));
|
||||
Gtk::Label* nlabel;
|
||||
|
||||
nlabel = manage (new Label (_("Regions")));
|
||||
nlabel->set_angle (-90);
|
||||
the_notebook.append_page (region_list_scroller, *nlabel);
|
||||
nlabel = manage (new Label (_("Tracks/Busses")));
|
||||
nlabel->set_angle (-90);
|
||||
the_notebook.append_page (route_list_scroller, *nlabel);
|
||||
nlabel = manage (new Label (_("Snapshots")));
|
||||
nlabel->set_angle (-90);
|
||||
the_notebook.append_page (snapshot_display_scroller, *nlabel);
|
||||
nlabel = manage (new Label (_("Edit Groups")));
|
||||
nlabel->set_angle (-90);
|
||||
the_notebook.append_page (*edit_group_display_packer, *nlabel);
|
||||
nlabel = manage (new Label (_("Chunks")));
|
||||
nlabel->set_angle (-90);
|
||||
the_notebook.append_page (named_selection_scroller, *nlabel);
|
||||
|
||||
the_notebook.set_show_tabs (true);
|
||||
the_notebook.set_scrollable (true);
|
||||
the_notebook.popup_enable ();
|
||||
the_notebook.set_tab_pos (Gtk::POS_RIGHT);
|
||||
|
||||
TearOff *notebook_tearoff = manage (new TearOff (the_notebook, true));
|
||||
notebook_tearoff->tearoff_window().set_size_request (200, 400);
|
||||
|
||||
edit_pane.pack1 (edit_frame, true, true);
|
||||
edit_pane.pack2 (*notebook_tearoff, false, true);
|
||||
edit_pane.pack1 (edit_packer, true, true);
|
||||
edit_pane.pack2 (the_notebook, false, true);
|
||||
|
||||
edit_pane.signal_size_allocate().connect_notify (bind (mem_fun(*this, &Editor::pane_allocation_handler), static_cast<Paned*> (&edit_pane)));
|
||||
|
||||
|
@ -672,7 +672,6 @@ class Editor : public PublicEditor
|
||||
Gtk::HBox bottom_hbox;
|
||||
|
||||
Gtk::Table edit_packer;
|
||||
Gtk::Frame edit_frame;
|
||||
Gtk::VScrollbar edit_vscrollbar;
|
||||
|
||||
Gtk::Adjustment vertical_adjustment;
|
||||
|
@ -130,6 +130,7 @@ Editor::initialize_canvas ()
|
||||
time_canvas.set_name ("EditorTimeCanvas");
|
||||
time_canvas.add_events (Gdk::POINTER_MOTION_HINT_MASK);
|
||||
time_canvas.set_flags (CAN_FOCUS);
|
||||
time_canvas.set_center_scroll_region (false);
|
||||
|
||||
meter_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, 0.0);
|
||||
tempo_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height);
|
||||
|
@ -239,11 +239,18 @@ string
|
||||
which_ui_rcfile ()
|
||||
{
|
||||
string rcfile;
|
||||
char* env;
|
||||
|
||||
if ((env = getenv ("ARDOUR2_UI_RC")) != 0 && strlen (env)) {
|
||||
rcfile = env;
|
||||
} else {
|
||||
rcfile = "ardour2_ui.rc";
|
||||
}
|
||||
|
||||
rcfile = find_config_file (rcfile);
|
||||
|
||||
rcfile = find_config_file ("ardour2_ui.rc");
|
||||
|
||||
if (rcfile.length() == 0) {
|
||||
warning << _("Without a UI style file, ardour will look strange.\n Please set ARDOUR_UI_RC to point to a valid UI style file") << endmsg;
|
||||
if (rcfile.empty()) {
|
||||
warning << _("Without a UI style file, ardour will look strange.\n Please set ARDOUR2_UI_RC to point to a valid UI style file") << endmsg;
|
||||
}
|
||||
|
||||
return rcfile;
|
||||
|
@ -100,7 +100,7 @@ class DiskStream : public Stateful, public sigc::trackable
|
||||
jack_nframes_t roll_delay() const { return _roll_delay; }
|
||||
void set_roll_delay (jack_nframes_t);
|
||||
|
||||
void set_name (string str, void* src);
|
||||
int set_name (string str, void* src);
|
||||
|
||||
string input_source (uint32_t n=0) const {
|
||||
if (n < channels.size()) {
|
||||
@ -244,6 +244,7 @@ class DiskStream : public Stateful, public sigc::trackable
|
||||
void set_block_size (jack_nframes_t);
|
||||
int internal_playback_seek (jack_nframes_t distance);
|
||||
int can_internal_playback_seek (jack_nframes_t distance);
|
||||
int rename_write_sources ();
|
||||
void reset_write_sources (bool, bool force = false);
|
||||
void non_realtime_input_change ();
|
||||
|
||||
|
@ -54,12 +54,15 @@ class FileSource : public Source {
|
||||
FileSource (const XMLNode&, jack_nframes_t rate);
|
||||
~FileSource ();
|
||||
|
||||
int set_name (std::string str, bool destructive);
|
||||
|
||||
void set_allow_remove_if_empty (bool yn);
|
||||
|
||||
jack_nframes_t length() const { return _length; }
|
||||
jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
|
||||
jack_nframes_t write (Sample *src, jack_nframes_t cnt, char * workbuf);
|
||||
void mark_for_remove();
|
||||
string peak_path(string audio_path);
|
||||
string old_peak_path(string audio_path);
|
||||
string path() const { return _path; }
|
||||
|
||||
virtual int seek (jack_nframes_t frame) {return 0; }
|
||||
@ -93,7 +96,8 @@ class FileSource : public Source {
|
||||
string _take_id;
|
||||
SampleFormat _sample_format;
|
||||
int _sample_size;
|
||||
|
||||
bool allow_remove_if_empty;
|
||||
|
||||
static char bwf_country_code[3];
|
||||
static char bwf_organization_code[4];
|
||||
static char bwf_serial_number[13];
|
||||
|
@ -253,8 +253,9 @@ class Session : public sigc::trackable, public Stateful
|
||||
static string template_dir ();
|
||||
static void get_template_list (list<string>&);
|
||||
|
||||
static string change_audio_path_by_name (string oldpath, string oldname, string newname, bool destructive);
|
||||
static string peak_path_from_audio_path (string);
|
||||
static string old_peak_path_from_audio_path (string);
|
||||
string audio_path_from_name (string, uint32_t nchans, uint32_t chan, bool destructive);
|
||||
|
||||
void process (jack_nframes_t nframes);
|
||||
|
||||
@ -1498,6 +1499,7 @@ class Session : public sigc::trackable, public Stateful
|
||||
RouteList routes;
|
||||
mutable PBD::NonBlockingRWLock route_lock;
|
||||
void add_route (Route*);
|
||||
uint32_t destructive_index;
|
||||
|
||||
int load_routes (const XMLNode&);
|
||||
Route* XMLRouteFactory (const XMLNode&);
|
||||
|
@ -56,6 +56,7 @@ class Source : public Stateful, public sigc::trackable
|
||||
virtual ~Source ();
|
||||
|
||||
const string& name() const { return _name; }
|
||||
|
||||
ARDOUR::id_t id() const { return _id; }
|
||||
|
||||
/* returns the number of items in this `source' */
|
||||
@ -103,10 +104,11 @@ class Source : public Stateful, public sigc::trackable
|
||||
XMLNode& get_state ();
|
||||
int set_state (const XMLNode&);
|
||||
|
||||
|
||||
static int start_peak_thread ();
|
||||
static void stop_peak_thread ();
|
||||
|
||||
int rename_peakfile (std::string newpath);
|
||||
|
||||
static void set_build_missing_peakfiles (bool yn) {
|
||||
_build_missing_peakfiles = yn;
|
||||
}
|
||||
@ -125,7 +127,6 @@ class Source : public Stateful, public sigc::trackable
|
||||
jack_nframes_t _length;
|
||||
bool next_peak_clear_should_notify;
|
||||
string peakpath;
|
||||
int peakfile; /* fd */
|
||||
time_t _timestamp;
|
||||
string _captured_for;
|
||||
|
||||
@ -138,7 +139,6 @@ class Source : public Stateful, public sigc::trackable
|
||||
int do_build_peak (jack_nframes_t, jack_nframes_t);
|
||||
virtual jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const = 0;
|
||||
virtual string peak_path(string audio_path) = 0;
|
||||
virtual string old_peak_path(string audio_path) = 0;
|
||||
|
||||
static pthread_t peak_thread;
|
||||
static bool have_peak_thread;
|
||||
|
@ -755,13 +755,23 @@ AudioTrack::toggle_monitor_input ()
|
||||
int
|
||||
AudioTrack::set_name (string str, void *src)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (record_enabled() && _session.actively_recording()) {
|
||||
/* this messes things up if done while recording */
|
||||
return -1;
|
||||
}
|
||||
|
||||
diskstream->set_name (str, src);
|
||||
return IO::set_name (str, src);
|
||||
if (diskstream->set_name (str, src)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* save state so that the statefile fully reflects any filename changes */
|
||||
|
||||
if ((ret = IO::set_name (str, src)) == 0) {
|
||||
_session.save_state ("");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -69,7 +69,6 @@ jack_nframes_t DestructiveFileSource::xfade_frames = 64;
|
||||
DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate, bool repair_first, SampleFormat samp_format)
|
||||
: FileSource (path, rate, repair_first, samp_format)
|
||||
{
|
||||
cerr << "DESTRUCTO DISK STREAM, " << _name << endl;
|
||||
if (out_coefficient == 0) {
|
||||
setup_standard_crossfades (rate);
|
||||
}
|
||||
@ -84,7 +83,6 @@ DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate,
|
||||
DestructiveFileSource::DestructiveFileSource (const XMLNode& node, jack_nframes_t rate)
|
||||
: FileSource (node, rate)
|
||||
{
|
||||
cerr << "from XML, DESTRUCTO DISK STREAM, " << _name << endl;
|
||||
if (out_coefficient == 0) {
|
||||
setup_standard_crossfades (rate);
|
||||
}
|
||||
|
@ -69,6 +69,9 @@ DiskStream::DiskStream (Session &sess, const string &name, Flag flag)
|
||||
/* prevent any write sources from being created */
|
||||
|
||||
in_set_state = true;
|
||||
|
||||
|
||||
|
||||
init (flag);
|
||||
use_new_playlist ();
|
||||
in_set_state = false;
|
||||
@ -472,13 +475,27 @@ void
|
||||
DiskStream::use_destructive_playlist ()
|
||||
{
|
||||
/* use the sources associated with the single full-extent region */
|
||||
|
||||
Playlist::RegionList* rl = _playlist->regions_at (0);
|
||||
|
||||
if (rl->empty()) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
AudioRegion* region = dynamic_cast<AudioRegion*> (rl->front());
|
||||
|
||||
if (region == 0) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
delete rl;
|
||||
|
||||
AudioRegion* region = dynamic_cast<AudioRegion*> (_playlist->regions_at (0)->front());
|
||||
uint32_t n;
|
||||
ChannelList::iterator chan;
|
||||
|
||||
for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
|
||||
(*chan).write_source = dynamic_cast<FileSource*>(®ion->source (n));
|
||||
(*chan).write_source->set_allow_remove_if_empty (false);
|
||||
}
|
||||
|
||||
/* the source list will never be reset for a destructive track */
|
||||
@ -491,7 +508,7 @@ DiskStream::set_io (IO& io)
|
||||
set_align_style_from_io ();
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
DiskStream::set_name (string str, void *src)
|
||||
{
|
||||
if (str != _name) {
|
||||
@ -499,12 +516,14 @@ DiskStream::set_name (string str, void *src)
|
||||
_name = str;
|
||||
|
||||
if (!in_set_state && recordable()) {
|
||||
|
||||
/* open new capture files so that they have the correct name */
|
||||
|
||||
reset_write_sources (false);
|
||||
/* rename existing capture files so that they have the correct name */
|
||||
return rename_write_sources ();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -2097,8 +2116,12 @@ DiskStream::set_state (const XMLNode& node)
|
||||
if (!had_playlist) {
|
||||
_playlist->set_orig_diskstream_id (_id);
|
||||
}
|
||||
|
||||
if (capture_pending_node) {
|
||||
|
||||
if (!destructive() && capture_pending_node) {
|
||||
/* destructive streams have one and only one source per channel,
|
||||
and so they never end up in pending capture in any useful
|
||||
sense.
|
||||
*/
|
||||
use_pending_capture_data (*capture_pending_node);
|
||||
}
|
||||
|
||||
@ -2170,6 +2193,10 @@ DiskStream::use_new_write_source (uint32_t n)
|
||||
|
||||
chan.write_source->use ();
|
||||
|
||||
/* do not remove destructive files even if they are empty */
|
||||
|
||||
chan.write_source->set_allow_remove_if_empty (!destructive());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2213,6 +2240,22 @@ DiskStream::reset_write_sources (bool mark_write_complete, bool force)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
DiskStream::rename_write_sources ()
|
||||
{
|
||||
ChannelList::iterator chan;
|
||||
uint32_t n;
|
||||
|
||||
for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
|
||||
if ((*chan).write_source != 0) {
|
||||
(*chan).write_source->set_name (_name, destructive());
|
||||
/* XXX what to do if one of them fails ? */
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
DiskStream::set_block_size (jack_nframes_t nframes)
|
||||
{
|
||||
|
@ -84,12 +84,6 @@ ExternalSource::peak_path (string audio_path)
|
||||
return res;
|
||||
}
|
||||
|
||||
string
|
||||
ExternalSource::old_peak_path (string audio_path)
|
||||
{
|
||||
return peak_path (audio_path);
|
||||
}
|
||||
|
||||
#ifdef HAVE_COREAUDIO
|
||||
|
||||
ExternalSource*
|
||||
|
@ -165,6 +165,7 @@ FileSource::init (string pathstr, bool must_exist, jack_nframes_t rate)
|
||||
fd = -1;
|
||||
remove_at_unref = false;
|
||||
next_peak_clear_should_notify = false;
|
||||
allow_remove_if_empty = true;
|
||||
|
||||
if (pathstr[0] != '/') {
|
||||
|
||||
@ -300,7 +301,7 @@ FileSource::init (string pathstr, bool must_exist, jack_nframes_t rate)
|
||||
}
|
||||
|
||||
if ((ret = initialize_peakfile (new_file, _path))) {
|
||||
error << string_compose (_("FileSource: cannot initialize peakfile for %1"), _path) << endmsg;
|
||||
error << string_compose (_("FileSource: cannot initialize peakfile for %1 as %2"), _path, peakpath) << endmsg;
|
||||
}
|
||||
|
||||
out:
|
||||
@ -325,7 +326,7 @@ FileSource::~FileSource ()
|
||||
|
||||
if (fd >= 0) {
|
||||
|
||||
if (remove_at_unref || is_empty (_path)) {
|
||||
if (remove_at_unref || (is_empty (_path) && allow_remove_if_empty)) {
|
||||
unlink (_path.c_str());
|
||||
unlink (peakpath.c_str());
|
||||
}
|
||||
@ -334,6 +335,41 @@ FileSource::~FileSource ()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FileSource::set_allow_remove_if_empty (bool yn)
|
||||
{
|
||||
allow_remove_if_empty = yn;
|
||||
}
|
||||
|
||||
int
|
||||
FileSource::set_name (string newname, bool destructive)
|
||||
{
|
||||
LockMonitor lm (_lock, __LINE__, __FILE__);
|
||||
string oldpath = _path;
|
||||
string newpath = Session::change_audio_path_by_name (oldpath, _name, newname, destructive);
|
||||
|
||||
if (newpath.empty()) {
|
||||
error << string_compose (_("programming error: %1"), "cannot generate a changed audio path") << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
|
||||
error << string_compose (_("cannot rename audio file for %1 to %2"), _name, newpath) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
_name = basename (newpath);
|
||||
_path = newpath;
|
||||
|
||||
return rename_peakfile (peak_path (_path));
|
||||
}
|
||||
|
||||
string
|
||||
FileSource::peak_path (string audio_path)
|
||||
{
|
||||
return Session::peak_path_from_audio_path (audio_path);
|
||||
}
|
||||
|
||||
int
|
||||
FileSource::discover_chunks (bool silent)
|
||||
{
|
||||
@ -1230,9 +1266,9 @@ FileSource::is_empty (string path)
|
||||
less than 1msec at typical sample rates.
|
||||
*/
|
||||
|
||||
/* NOTE: 700 bytes is the size of a BWF header structure *plus* our minimal coding history */
|
||||
/* NOTE: 698 bytes is the size of a BWF header structure *plus* our minimal coding history */
|
||||
|
||||
return (statbuf.st_size == 0 || statbuf.st_size == wave_header_size || statbuf.st_size == 700);
|
||||
return (statbuf.st_size == 0 || statbuf.st_size == wave_header_size || statbuf.st_size == 698);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1248,18 +1284,6 @@ FileSource::mark_streaming_write_completed ()
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
FileSource::peak_path(string audio_path)
|
||||
{
|
||||
return Session::peak_path_from_audio_path (audio_path);
|
||||
}
|
||||
|
||||
string
|
||||
FileSource::old_peak_path(string audio_path)
|
||||
{
|
||||
return Session::old_peak_path_from_audio_path (audio_path);
|
||||
}
|
||||
|
||||
void
|
||||
FileSource::mark_take (string id)
|
||||
{
|
||||
@ -1470,3 +1494,4 @@ FileSource::repair (string path, jack_nframes_t rate)
|
||||
fclose (in);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -622,6 +622,7 @@ Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
|
||||
if (_session.transport_speed() > 1.5f || _session.transport_speed() < -1.5f) {
|
||||
pan (bufs, nbufs, nframes, offset, speed_quietning);
|
||||
} else {
|
||||
// cerr << "panner state = " << _panner->automation_state() << endl;
|
||||
if (!_panner->empty() &&
|
||||
(_panner->automation_state() & Play ||
|
||||
((_panner->automation_state() & Touch) && !_panner->touching()))) {
|
||||
|
@ -1881,6 +1881,11 @@ Session::add_route (Route* route)
|
||||
_control_out = route;
|
||||
}
|
||||
|
||||
AudioTrack* at = dynamic_cast<AudioTrack*>(route);
|
||||
if (at && at->mode() == Destructive) {
|
||||
destructive_index++;
|
||||
}
|
||||
|
||||
set_dirty();
|
||||
save_state (_current_snapshot_name);
|
||||
|
||||
@ -2601,7 +2606,7 @@ void
|
||||
Session::add_source (Source* source)
|
||||
{
|
||||
pair<SourceList::key_type, SourceList::mapped_type> entry;
|
||||
|
||||
|
||||
{
|
||||
LockMonitor lm (source_lock, __LINE__, __FILE__);
|
||||
entry.first = source->id();
|
||||
@ -2654,8 +2659,109 @@ Session::get_source (ARDOUR::id_t id)
|
||||
return source;
|
||||
}
|
||||
|
||||
FileSource *
|
||||
Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
|
||||
string
|
||||
Session::peak_path_from_audio_path (string audio_path)
|
||||
{
|
||||
/* XXX hardly bombproof! fix me */
|
||||
|
||||
string res;
|
||||
|
||||
res = PBD::dirname (audio_path);
|
||||
res = PBD::dirname (res);
|
||||
res += '/';
|
||||
res += peak_dir_name;
|
||||
res += '/';
|
||||
res += PBD::basename_nosuffix (audio_path);
|
||||
res += ".peak";
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
string
|
||||
Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive)
|
||||
{
|
||||
string look_for;
|
||||
string old_basename = basename_nosuffix (oldname);
|
||||
string new_legalized = legalize_for_path (newname);
|
||||
|
||||
/* note: we know (or assume) the old path is already valid */
|
||||
|
||||
if (destructive) {
|
||||
|
||||
/* destructive file sources have a name of the form:
|
||||
|
||||
/path/to/Tnnnn-NAME(%[LR])?.wav
|
||||
|
||||
the task here is to replace NAME with the new name.
|
||||
*/
|
||||
|
||||
/* find last slash */
|
||||
|
||||
string dir;
|
||||
string prefix;
|
||||
string::size_type slash;
|
||||
string::size_type dash;
|
||||
|
||||
if ((slash = path.find_last_of ('/')) == string::npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
dir = path.substr (0, slash+1);
|
||||
|
||||
/* '-' is not a legal character for the NAME part of the path */
|
||||
|
||||
if ((dash = path.find_last_of ('-')) == string::npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
prefix = path.substr (slash+1, dash-(slash+1));
|
||||
|
||||
path = dir;
|
||||
path += prefix;
|
||||
path += '-';
|
||||
path += new_legalized;
|
||||
path += ".wav"; /* XXX gag me with a spoon */
|
||||
|
||||
} else {
|
||||
|
||||
/* non-destructive file sources have a name of the form:
|
||||
|
||||
/path/to/NAME-nnnnn(%[LR])?.wav
|
||||
|
||||
the task here is to replace NAME with the new name.
|
||||
*/
|
||||
|
||||
/* find last slash */
|
||||
|
||||
string dir;
|
||||
string suffix;
|
||||
string::size_type slash;
|
||||
string::size_type dash;
|
||||
|
||||
if ((slash = path.find_last_of ('/')) == string::npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
dir = path.substr (0, slash+1);
|
||||
|
||||
/* '-' is not a legal character for the NAME part of the path */
|
||||
|
||||
if ((dash = path.find_last_of ('-')) == string::npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
suffix = path.substr (dash);
|
||||
|
||||
path = dir;
|
||||
path += new_legalized;
|
||||
path += suffix;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
string
|
||||
Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive)
|
||||
{
|
||||
string spath;
|
||||
uint32_t cnt;
|
||||
@ -2664,56 +2770,74 @@ Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
|
||||
string legalized;
|
||||
|
||||
buf[0] = '\0';
|
||||
legalized = legalize_for_path (ds.name());
|
||||
legalized = legalize_for_path (name);
|
||||
|
||||
/* find a "version" of the file name that doesn't exist in
|
||||
any of the possible directories.
|
||||
*/
|
||||
|
||||
for (cnt = 1; cnt <= limit; ++cnt) {
|
||||
|
||||
for (cnt = (destructive ? destructive_index + 1 : 1); cnt <= limit; ++cnt) {
|
||||
|
||||
vector<space_and_path>::iterator i;
|
||||
uint32_t existing = 0;
|
||||
|
||||
|
||||
for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
|
||||
|
||||
|
||||
spath = (*i).path;
|
||||
|
||||
|
||||
if (destructive) {
|
||||
spath += tape_dir_name;
|
||||
} else {
|
||||
spath += sound_dir_name;
|
||||
}
|
||||
spath += '/';
|
||||
spath += legalized;
|
||||
|
||||
if (ds.n_channels() < 2) {
|
||||
snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
|
||||
} else if (ds.n_channels() == 2) {
|
||||
if (chan == 0) {
|
||||
snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
|
||||
|
||||
if (destructive) {
|
||||
if (nchan < 2) {
|
||||
snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
|
||||
} else if (nchan == 2) {
|
||||
if (nchan == 0) {
|
||||
snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str());
|
||||
} else {
|
||||
snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str());
|
||||
}
|
||||
} else if (nchan < 26) {
|
||||
snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan);
|
||||
} else {
|
||||
snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
|
||||
snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
|
||||
}
|
||||
} else if (ds.n_channels() < 26) {
|
||||
snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
|
||||
} else {
|
||||
snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
|
||||
|
||||
spath += '/';
|
||||
spath += legalized;
|
||||
|
||||
if (nchan < 2) {
|
||||
snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
|
||||
} else if (nchan == 2) {
|
||||
if (chan == 0) {
|
||||
snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt);
|
||||
} else {
|
||||
snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt);
|
||||
}
|
||||
} else if (nchan < 26) {
|
||||
snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan);
|
||||
} else {
|
||||
snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
|
||||
}
|
||||
}
|
||||
|
||||
if (access (buf, F_OK) == 0) {
|
||||
existing++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (existing == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt > limit) {
|
||||
error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, ds.name()) << endmsg;
|
||||
throw failed_constructor();
|
||||
if (cnt > limit) {
|
||||
error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg;
|
||||
throw failed_constructor();
|
||||
}
|
||||
}
|
||||
|
||||
/* we now have a unique name for the file, but figure out where to
|
||||
@ -2722,7 +2846,11 @@ Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
|
||||
|
||||
string foo = buf;
|
||||
|
||||
spath = discover_best_sound_dir ();
|
||||
if (destructive) {
|
||||
spath = tape_dir ();
|
||||
} else {
|
||||
spath = discover_best_sound_dir ();
|
||||
}
|
||||
|
||||
string::size_type pos = foo.find_last_of ('/');
|
||||
|
||||
@ -2732,6 +2860,14 @@ Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
|
||||
spath += foo.substr (pos + 1);
|
||||
}
|
||||
|
||||
return spath;
|
||||
}
|
||||
|
||||
FileSource *
|
||||
Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
|
||||
{
|
||||
string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
|
||||
|
||||
/* this might throw failed_constructor(), which is OK */
|
||||
|
||||
if (destructive) {
|
||||
@ -2944,40 +3080,6 @@ Session::is_auditioning () const
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string
|
||||
Session::peak_path_from_audio_path (string audio_path)
|
||||
{
|
||||
/* XXX hardly bombproof! fix me */
|
||||
|
||||
string res;
|
||||
|
||||
res = PBD::dirname (audio_path);
|
||||
res = PBD::dirname (res);
|
||||
res += '/';
|
||||
res += peak_dir_name;
|
||||
res += '/';
|
||||
res += PBD::basename_nosuffix (audio_path);
|
||||
res += ".peak";
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
string
|
||||
Session::old_peak_path_from_audio_path (string audio_path)
|
||||
{
|
||||
/* This is a hangover from when audio and peak files
|
||||
lived in the same directory. We need it to to
|
||||
be able to open old sessions.
|
||||
*/
|
||||
|
||||
/* XXX hardly bombproof! fix me */
|
||||
|
||||
string res = audio_path.substr (0, audio_path.find_last_of ('.'));
|
||||
res += ".peak";
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
Session::set_all_solo (bool yn)
|
||||
{
|
||||
|
@ -192,6 +192,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
|
||||
pending_abort = false;
|
||||
layer_model = MoveAddHigher;
|
||||
xfade_model = ShortCrossfade;
|
||||
destructive_index = 0;
|
||||
|
||||
/* allocate conversion buffers */
|
||||
_conversion_buffers[ButlerContext] = new char[DiskStream::disk_io_frames() * 4];
|
||||
@ -401,13 +402,32 @@ Session::setup_raid_path (string path)
|
||||
|
||||
if (colons == 0) {
|
||||
|
||||
/* no multiple search path, just one directory (common case) */
|
||||
/* no multiple search path, just one location (common case) */
|
||||
|
||||
sp.path = path;
|
||||
sp.blocks = 0;
|
||||
session_dirs.push_back (sp);
|
||||
|
||||
string fspath;
|
||||
|
||||
/* sounds dir */
|
||||
|
||||
fspath += sp.path;
|
||||
if (fspath[fspath.length()-1] != '/') {
|
||||
fspath += '/';
|
||||
}
|
||||
fspath += sound_dir_name;
|
||||
fspath += ':';
|
||||
|
||||
/* tape dir */
|
||||
|
||||
fspath += sp.path;
|
||||
if (fspath[fspath.length()-1] != '/') {
|
||||
fspath += '/';
|
||||
}
|
||||
fspath += tape_dir_name;
|
||||
|
||||
FileSource::set_search_path (path + sound_dir_name);
|
||||
FileSource::set_search_path (fspath);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -418,6 +438,9 @@ Session::setup_raid_path (string path)
|
||||
|
||||
sp.blocks = 0;
|
||||
sp.path = remaining.substr (0, colon);
|
||||
session_dirs.push_back (sp);
|
||||
|
||||
/* add sounds to file search path */
|
||||
|
||||
fspath += sp.path;
|
||||
if (fspath[fspath.length()-1] != '/') {
|
||||
@ -426,7 +449,14 @@ Session::setup_raid_path (string path)
|
||||
fspath += sound_dir_name;
|
||||
fspath += ':';
|
||||
|
||||
session_dirs.push_back (sp);
|
||||
/* add tape dir to file search path */
|
||||
|
||||
fspath += sp.path;
|
||||
if (fspath[fspath.length()-1] != '/') {
|
||||
fspath += '/';
|
||||
}
|
||||
fspath += tape_dir_name;
|
||||
fspath += ':';
|
||||
|
||||
remaining = remaining.substr (colon+1);
|
||||
}
|
||||
@ -436,11 +466,19 @@ Session::setup_raid_path (string path)
|
||||
sp.blocks = 0;
|
||||
sp.path = remaining;
|
||||
|
||||
fspath += ':';
|
||||
fspath += sp.path;
|
||||
if (fspath[fspath.length()-1] != '/') {
|
||||
fspath += '/';
|
||||
}
|
||||
fspath += sound_dir_name;
|
||||
fspath += ':';
|
||||
|
||||
fspath += sp.path;
|
||||
if (fspath[fspath.length()-1] != '/') {
|
||||
fspath += '/';
|
||||
}
|
||||
fspath += tape_dir_name;
|
||||
|
||||
session_dirs.push_back (sp);
|
||||
}
|
||||
@ -681,7 +719,7 @@ Session::save_state (string snapshot_name, bool pending)
|
||||
if (!pending) {
|
||||
|
||||
bool was_dirty = dirty();
|
||||
|
||||
|
||||
_state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
|
||||
|
||||
if (was_dirty) {
|
||||
@ -1298,10 +1336,18 @@ Session::state(bool full_state)
|
||||
/* Don't save information about FileSources that are empty */
|
||||
|
||||
FileSource* fs;
|
||||
|
||||
|
||||
if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
|
||||
if (fs->length() == 0) {
|
||||
continue;
|
||||
DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
|
||||
|
||||
/* destructive file sources are OK if they are empty, because
|
||||
we will re-use them every time.
|
||||
*/
|
||||
|
||||
if (!dfs) {
|
||||
if (fs->length() == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ SndFileSource::init (const string& idstr, bool build_peak)
|
||||
_path = file;
|
||||
|
||||
if (build_peak) {
|
||||
if (initialize_peakfile (false, file)) {
|
||||
if (initialize_peakfile (false, _path)) {
|
||||
sf_close (sf);
|
||||
sf = 0;
|
||||
throw failed_constructor ();
|
||||
|
@ -59,7 +59,6 @@ Source::Source (bool announce)
|
||||
_use_cnt = 0;
|
||||
_peaks_built = false;
|
||||
next_peak_clear_should_notify = true;
|
||||
peakfile = -1;
|
||||
_timestamp = 0;
|
||||
_read_data_count = 0;
|
||||
_write_data_count = 0;
|
||||
@ -70,7 +69,6 @@ Source::Source (const XMLNode& node)
|
||||
_use_cnt = 0;
|
||||
_peaks_built = false;
|
||||
next_peak_clear_should_notify = true;
|
||||
peakfile = -1;
|
||||
_timestamp = 0;
|
||||
_read_data_count = 0;
|
||||
_write_data_count = 0;
|
||||
@ -82,9 +80,6 @@ Source::Source (const XMLNode& node)
|
||||
|
||||
Source::~Source ()
|
||||
{
|
||||
if (peakfile >= 0) {
|
||||
close (peakfile);
|
||||
}
|
||||
}
|
||||
|
||||
XMLNode&
|
||||
@ -319,6 +314,25 @@ Source::peaks_ready (sigc::slot<void> the_slot, sigc::connection& conn) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
Source::rename_peakfile (string newpath)
|
||||
{
|
||||
/* caller must hold _lock */
|
||||
|
||||
string oldpath = peakpath;
|
||||
|
||||
if (access (oldpath.c_str(), F_OK) == 0) {
|
||||
if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
|
||||
error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
peakpath = newpath;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Source::initialize_peakfile (bool newfile, string audio_path)
|
||||
{
|
||||
@ -344,33 +358,6 @@ Source::initialize_peakfile (bool newfile, string audio_path)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* older sessions stored peaks in the same directory
|
||||
as the audio. so check there as well.
|
||||
*/
|
||||
|
||||
string oldpeakpath = old_peak_path (audio_path);
|
||||
|
||||
if (stat (oldpeakpath.c_str(), &statbuf)) {
|
||||
|
||||
if (errno == ENOENT) {
|
||||
|
||||
statbuf.st_size = 0;
|
||||
|
||||
} else {
|
||||
|
||||
/* it exists in the audio dir , but there is some kind of error */
|
||||
|
||||
error << string_compose(_("Source: cannot stat peakfile \"%1\" or \"%2\""), peakpath, oldpeakpath) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* we found it in the sound dir, where they lived once upon a time, in a land ... etc. */
|
||||
|
||||
peakpath = oldpeakpath;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* we found it in the peaks dir */
|
||||
@ -391,11 +378,6 @@ Source::initialize_peakfile (bool newfile, string audio_path)
|
||||
}
|
||||
}
|
||||
|
||||
if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
|
||||
error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!newfile && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
|
||||
build_peaks_from_scratch ();
|
||||
}
|
||||
@ -418,7 +400,8 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
|
||||
PeakData* staging = 0;
|
||||
Sample* raw_staging = 0;
|
||||
char * workbuf = 0;
|
||||
|
||||
int peakfile = -1;
|
||||
|
||||
expected_peaks = (cnt / (double) frames_per_peak);
|
||||
scale = npeaks/expected_peaks;
|
||||
|
||||
@ -474,11 +457,21 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
|
||||
|
||||
if (scale == 1.0) {
|
||||
|
||||
// cerr << "DIRECT PEAKS\n";
|
||||
|
||||
off_t first_peak_byte = (start / frames_per_peak) * sizeof (PeakData);
|
||||
|
||||
if ((nread = ::pread (peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte)) != sizeof (PeakData) * npeaks) {
|
||||
/* open, read, close */
|
||||
|
||||
if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
|
||||
error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// cerr << "DIRECT PEAKS\n";
|
||||
|
||||
nread = ::pread (peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte);
|
||||
close (peakfile);
|
||||
|
||||
if (nread != sizeof (PeakData) * npeaks) {
|
||||
cerr << "Source["
|
||||
<< _name
|
||||
<< "]: cannot read peaks from peakfile! (read only "
|
||||
@ -537,6 +530,13 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
|
||||
|
||||
current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
|
||||
|
||||
/* open ... close during out: handling */
|
||||
|
||||
if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
|
||||
error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (nvisual_peaks < npeaks) {
|
||||
|
||||
if (i == stored_peaks_read) {
|
||||
@ -669,6 +669,10 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
|
||||
}
|
||||
|
||||
out:
|
||||
if (peakfile >= 0) {
|
||||
close (peakfile);
|
||||
}
|
||||
|
||||
if (staging) {
|
||||
delete [] staging;
|
||||
}
|
||||
@ -734,7 +738,6 @@ Source::build_peaks ()
|
||||
}
|
||||
|
||||
if (pr_signal) {
|
||||
off_t fend = lseek (peakfile, 0, SEEK_END);
|
||||
PeaksReady (); /* EMIT SIGNAL */
|
||||
}
|
||||
}
|
||||
@ -754,6 +757,7 @@ Source::do_build_peak (jack_nframes_t first_frame, jack_nframes_t cnt)
|
||||
jack_nframes_t frames_read;
|
||||
jack_nframes_t frames_to_read;
|
||||
off_t first_peak_byte;
|
||||
int peakfile = -1;
|
||||
int ret = -1;
|
||||
|
||||
#ifdef DEBUG_PEAK_BUILD
|
||||
@ -772,6 +776,11 @@ Source::do_build_peak (jack_nframes_t first_frame, jack_nframes_t cnt)
|
||||
|
||||
workbuf = new char[max(frames_per_peak, cnt) * 4];
|
||||
|
||||
if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
|
||||
error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (cnt) {
|
||||
|
||||
frames_to_read = min (frames_per_peak, cnt);
|
||||
@ -810,6 +819,9 @@ Source::do_build_peak (jack_nframes_t first_frame, jack_nframes_t cnt)
|
||||
|
||||
out:
|
||||
delete [] peakbuf;
|
||||
if (peakfile >= 0) {
|
||||
close (peakfile);
|
||||
}
|
||||
if (workbuf)
|
||||
delete [] workbuf;
|
||||
return ret;
|
||||
@ -856,13 +868,27 @@ Source::release ()
|
||||
jack_nframes_t
|
||||
Source::available_peaks (double zoom_factor) const
|
||||
{
|
||||
int peakfile;
|
||||
off_t end;
|
||||
|
||||
if (zoom_factor < frames_per_peak) {
|
||||
return length(); // peak data will come from the audio file
|
||||
}
|
||||
|
||||
/* peak data comes from peakfile */
|
||||
|
||||
LockMonitor lm (_lock, __LINE__, __FILE__);
|
||||
off_t end = lseek (peakfile, 0, SEEK_END);
|
||||
if ((peakfile = ::open (peakpath.c_str(), O_RDONLY)) < 0) {
|
||||
error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
LockMonitor lm (_lock, __LINE__, __FILE__);
|
||||
end = lseek (peakfile, 0, SEEK_END);
|
||||
}
|
||||
|
||||
close (peakfile);
|
||||
|
||||
return (end/sizeof(PeakData)) * frames_per_peak;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user