summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2008-03-17 20:54:03 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2008-03-17 20:54:03 +0000
commit997e4b1f9cd7ccfc704b7c035051da7f60d831e7 (patch)
tree1236e40183b677abf4a2882e4cfe8e0a345eb24d /libs/ardour
parent19a4b990325577fc949ccd5d5fbad4520eb1df56 (diff)
merge with 2.0-ongoing @ rev 3147
git-svn-id: svn://localhost/ardour2/branches/3.0@3152 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/SConscript3
-rw-r--r--libs/ardour/ardour/audiofilesource.h2
-rw-r--r--libs/ardour/ardour/audioregion.h3
-rw-r--r--libs/ardour/ardour/caimportable.h48
-rw-r--r--libs/ardour/ardour/configuration_vars.h5
-rw-r--r--libs/ardour/ardour/coreaudiosource.h6
-rw-r--r--libs/ardour/ardour/importable_source.h30
-rw-r--r--libs/ardour/ardour/resampled_source.h9
-rw-r--r--libs/ardour/ardour/session.h1
-rw-r--r--libs/ardour/ardour/sndfileimportable.h50
-rw-r--r--libs/ardour/ardour/sndfilesource.h1
-rw-r--r--libs/ardour/audio_diskstream.cc2
-rw-r--r--libs/ardour/audio_unit.cc17
-rw-r--r--libs/ardour/audioengine.cc15
-rw-r--r--libs/ardour/audiofilesource.cc36
-rw-r--r--libs/ardour/audioregion.cc48
-rw-r--r--libs/ardour/caimportable.cc118
-rw-r--r--libs/ardour/coreaudiosource.cc174
-rw-r--r--libs/ardour/crossfade.cc2
-rw-r--r--libs/ardour/globals.cc15
-rw-r--r--libs/ardour/import.cc84
-rw-r--r--libs/ardour/io.cc5
-rw-r--r--libs/ardour/playlist.cc246
-rw-r--r--libs/ardour/rb_effect.cc38
-rw-r--r--libs/ardour/resampled_source.cc27
-rw-r--r--libs/ardour/route.cc22
-rw-r--r--libs/ardour/session.cc13
-rw-r--r--libs/ardour/session_butler.cc2
-rw-r--r--libs/ardour/session_events.cc3
-rw-r--r--libs/ardour/session_state.cc3
-rw-r--r--libs/ardour/session_transport.cc16
-rw-r--r--libs/ardour/sndfileimportable.cc47
-rw-r--r--libs/ardour/sndfilesource.cc61
-rw-r--r--libs/ardour/source_factory.cc121
-rw-r--r--libs/ardour/tempo.cc5
35 files changed, 828 insertions, 450 deletions
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index 4c13c82cf7..b50aecbcb3 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -134,6 +134,7 @@ smf_reader.cc
smf_source.cc
sndfile_helpers.cc
sndfilesource.cc
+sndfileimportable.cc
source.cc
source_factory.cc
tape_file_matcher.cc
@@ -152,7 +153,7 @@ osc_files = [ 'osc.cc' ]
vst_files = [ 'vst_plugin.cc', 'session_vst.cc' ]
lv2_files = [ 'lv2_plugin.cc' ]
audiounit_files = [ 'audio_unit.cc' ]
-coreaudio_files = [ 'coreaudiosource.cc' ]
+coreaudio_files = [ 'coreaudiosource.cc', 'caimportable.cc' ]
extra_sources = [ ]
timefx_sources = [ ]
diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h
index 0e8b6e4fde..de388a06fc 100644
--- a/libs/ardour/ardour/audiofilesource.h
+++ b/libs/ardour/ardour/audiofilesource.h
@@ -170,6 +170,8 @@ class AudioFileSource : public AudioSource {
bool removable() const;
bool writable() const { return _flags & Writable; }
+ static Sample* get_interleave_buffer (nframes_t size);
+
private:
Glib::ustring old_peak_path (Glib::ustring audio_path);
Glib::ustring broken_peak_path (Glib::ustring audio_path);
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h
index e88e10d521..81b7ef7c57 100644
--- a/libs/ardour/ardour/audioregion.h
+++ b/libs/ardour/ardour/audioregion.h
@@ -155,7 +155,8 @@ class AudioRegion : public Region
void recompute_gain_at_end ();
void recompute_gain_at_start ();
- nframes_t _read_at (const SourceList&, Sample *buf, Sample *mixdown_buffer,
+ nframes_t _read_at (const SourceList&, nframes_t limit,
+ Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, nframes_t position, nframes_t cnt,
uint32_t chan_n = 0,
nframes_t read_frames = 0,
diff --git a/libs/ardour/ardour/caimportable.h b/libs/ardour/ardour/caimportable.h
new file mode 100644
index 0000000000..dc7f5769ae
--- /dev/null
+++ b/libs/ardour/ardour/caimportable.h
@@ -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_ca_importable_source_h__
+#define __ardour_ca_importable_source_h__
+
+#include <pbd/failed_constructor.h>
+#include <ardour/types.h>
+#include <ardour/importable_source.h>
+
+#include <appleutility/CAAudioFile.h>
+
+namespace ARDOUR {
+
+class CAImportableSource : public ImportableSource {
+ public:
+ CAImportableSource (const std::string& path);
+ virtual ~CAImportableSource();
+
+ nframes_t read (Sample* buffer, nframes_t nframes);
+ uint32_t channels() const;
+ nframes_t length() const;
+ nframes_t samplerate() const;
+ void seek (nframes_t pos);
+
+ protected:
+ mutable CAAudioFile af;
+};
+
+}
+
+#endif /* __ardour_ca_importable_source_h__ */
diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h
index f21de9be37..732585982d 100644
--- a/libs/ardour/ardour/configuration_vars.h
+++ b/libs/ardour/ardour/configuration_vars.h
@@ -33,8 +33,8 @@ CONFIG_VARIABLE (std::string, midi_port_name, "midi-port-name", "default")
CONFIG_VARIABLE (bool, trace_midi_input, "trace-midi-input", false)
CONFIG_VARIABLE (bool, trace_midi_output, "trace-midi-output", false)
CONFIG_VARIABLE (bool, send_mtc, "send-mtc", false)
-CONFIG_VARIABLE (bool, send_mmc, "send-mmc", false)
-CONFIG_VARIABLE (bool, mmc_control, "mmc-control", false)
+CONFIG_VARIABLE (bool, send_mmc, "send-mmc", true)
+CONFIG_VARIABLE (bool, mmc_control, "mmc-control", true)
CONFIG_VARIABLE (bool, midi_feedback, "midi-feedback", false)
CONFIG_VARIABLE (uint8_t, mmc_receive_device_id, "mmc-receive-device-id", 0)
CONFIG_VARIABLE (uint8_t, mmc_send_device_id, "mmc-send-device-id", 0)
@@ -157,6 +157,7 @@ CONFIG_VARIABLE (std::string, keyboard_layout, "keyboard-layout", "ansi")
CONFIG_VARIABLE (std::string, default_bindings, "default-bindings", "ardour")
CONFIG_VARIABLE (bool, default_narrow_ms, "default-narrow_ms", false)
CONFIG_VARIABLE (bool, rubberbanding_snaps_to_grid, "rubberbanding-snaps-to-grid", false)
+CONFIG_VARIABLE (long, font_scale, "font-scale", 102400)
/* denormal management */
diff --git a/libs/ardour/ardour/coreaudiosource.h b/libs/ardour/ardour/coreaudiosource.h
index ad21188531..d7282b35bd 100644
--- a/libs/ardour/ardour/coreaudiosource.h
+++ b/libs/ardour/ardour/coreaudiosource.h
@@ -21,7 +21,6 @@
#define __coreaudio_source_h__
#include <appleutility/CAAudioFile.h>
-
#include <ardour/audiofilesource.h>
namespace ARDOUR {
@@ -48,11 +47,8 @@ class CoreAudioSource : public AudioFileSource {
mutable CAAudioFile af;
uint16_t n_channels;
- mutable float *tmpbuf;
- mutable nframes_t tmpbufsize;
- mutable Glib::Mutex _tmpbuf_lock;
-
void init ();
+ int safe_read (Sample*, nframes_t start, nframes_t cnt, AudioBufferList&) const;
};
}; /* namespace ARDOUR */
diff --git a/libs/ardour/ardour/importable_source.h b/libs/ardour/ardour/importable_source.h
index 5845d841b6..a33cf567e7 100644
--- a/libs/ardour/ardour/importable_source.h
+++ b/libs/ardour/ardour/importable_source.h
@@ -20,7 +20,6 @@
#ifndef __ardour_importable_source_h__
#define __ardour_importable_source_h__
-#include <sndfile.h>
#include <pbd/failed_constructor.h>
#include <ardour/types.h>
@@ -28,32 +27,15 @@ namespace ARDOUR {
class ImportableSource {
public:
- ImportableSource (const std::string& path)
- : in (sf_open (path.c_str(), SFM_READ, &sf_info), sf_close)
- {
- if (!in) throw failed_constructor();
-
- }
-
+ ImportableSource () {}
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.get(), buffer, per_channel);
- return per_channel * sf_info.channels;
- }
-
+ virtual nframes_t read (Sample* buffer, nframes_t nframes) = 0;
virtual float ratio() const { return 1.0f; }
-
- uint channels() const { return sf_info.channels; }
-
- nframes_t length() const { return sf_info.frames; }
-
- nframes_t samplerate() const { return sf_info.samplerate; }
-
-protected:
- SF_INFO sf_info;
- boost::shared_ptr<SNDFILE> in;
+ virtual uint32_t channels() const = 0;
+ virtual nframes_t length() const = 0;
+ virtual nframes_t samplerate() const = 0;
+ virtual void seek (nframes_t pos) = 0;
};
}
diff --git a/libs/ardour/ardour/resampled_source.h b/libs/ardour/ardour/resampled_source.h
index 8ca56b52d3..6eca4cda98 100644
--- a/libs/ardour/ardour/resampled_source.h
+++ b/libs/ardour/ardour/resampled_source.h
@@ -30,18 +30,21 @@ namespace ARDOUR {
class ResampledImportableSource : public ImportableSource
{
public:
- ResampledImportableSource (const std::string& path,
- nframes_t rate, SrcQuality);
+ ResampledImportableSource (boost::shared_ptr<ImportableSource>, nframes_t rate, SrcQuality);
~ResampledImportableSource ();
nframes_t read (Sample* buffer, nframes_t nframes);
-
float ratio() const { return src_data.src_ratio; }
+ uint32_t channels() const { return source->channels(); }
+ nframes_t length() const { return source->length(); }
+ nframes_t samplerate() const { return source->samplerate(); }
+ void seek (nframes_t pos) { source->seek (pos); }
static const uint32_t blocksize;
private:
+ boost::shared_ptr<ImportableSource> source;
float* input;
SRC_STATE* src_state;
SRC_DATA src_data;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index bc77157e9f..67a641ff59 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -175,6 +175,7 @@ class Session : public PBD::StatefulDestructible
union {
void* ptr;
bool yes_or_no;
+ nframes_t target2_frame;
SlaveSource slave;
Route* route;
};
diff --git a/libs/ardour/ardour/sndfileimportable.h b/libs/ardour/ardour/sndfileimportable.h
new file mode 100644
index 0000000000..5cd84f4f5f
--- /dev/null
+++ b/libs/ardour/ardour/sndfileimportable.h
@@ -0,0 +1,50 @@
+/*
+ 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_sndfile_importable_source_h__
+#define __ardour_sndfile_importable_source_h__
+
+#include <boost/shared_ptr.hpp>
+#include <sndfile.h>
+#include <pbd/failed_constructor.h>
+#include <ardour/types.h>
+#include <ardour/importable_source.h>
+
+namespace ARDOUR {
+
+class SndFileImportableSource : public ImportableSource {
+ public:
+ SndFileImportableSource (const std::string& path);
+ virtual ~SndFileImportableSource();
+
+ nframes_t read (Sample* buffer, nframes_t nframes);
+ uint32_t channels() const;
+ nframes_t length() const;
+ nframes_t samplerate() const;
+ void seek (nframes_t pos);
+
+ protected:
+ SF_INFO sf_info;
+ boost::shared_ptr<SNDFILE> in;
+
+};
+
+}
+
+#endif /* __ardour_sndfile_importable_source_h__ */
diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h
index 4fd71a4c96..dc83fc6ec1 100644
--- a/libs/ardour/ardour/sndfilesource.h
+++ b/libs/ardour/ardour/sndfilesource.h
@@ -102,7 +102,6 @@ class SndFileSource : public AudioFileSource {
void handle_header_position_change ();
static int64_t get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& exists);
- static Sample* get_interleave_buffer (nframes_t size);
};
} // namespace ARDOUR
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 5c32b34e10..e1853e557c 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -2220,7 +2220,7 @@ AudioDiskstream::add_channel (uint32_t how_many)
int
AudioDiskstream::remove_channel_from (boost::shared_ptr<ChannelList> c, uint32_t how_many)
{
- while (--how_many && !c->empty()) {
+ while (how_many-- && !c->empty()) {
delete c->back();
c->pop_back();
}
diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc
index 9132957743..e517964024 100644
--- a/libs/ardour/audio_unit.cc
+++ b/libs/ardour/audio_unit.cc
@@ -93,6 +93,13 @@ AUPlugin::AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAC
streamFormat.mSampleRate = session.frame_rate();
streamFormat.mFormatID = kAudioFormatLinearPCM;
streamFormat.mFormatFlags = kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked|kAudioFormatFlagIsNonInterleaved;
+
+#ifdef __LITTLE_ENDIAN__
+ /* relax */
+#else
+ streamFormat.mFormatFlags |= kAudioFormatFlagIsBigEndian;
+#endif
+
streamFormat.mBitsPerChannel = 32;
streamFormat.mFramesPerPacket = 1;
@@ -130,8 +137,6 @@ AUPlugin::discover_parameters ()
{
/* discover writable parameters */
- cerr << "get param info, there are " << global_elements << " global elements\n";
-
AudioUnitScope scopes[] = {
kAudioUnitScope_Global,
kAudioUnitScope_Output,
@@ -144,8 +149,6 @@ AUPlugin::discover_parameters ()
AUParamInfo param_info (unit->AU(), false, false, scopes[i]);
- cerr << "discovered " << param_info.NumParams() << " parameters in scope " << i << endl;
-
for (uint32_t i = 0; i < param_info.NumParams(); ++i) {
AUParameterDescriptor d;
@@ -328,7 +331,7 @@ AUPlugin::activate ()
if (!initialized) {
OSErr err;
if ((err = unit->Initialize()) != noErr) {
- error << string_compose (_("AUPlugin: cannot initialize plugin (err = %1)"), err) << endmsg;
+ error << string_compose (_("AUPlugin: %1 cannot initialize plugin (err = %2)"), name(), err) << endmsg;
} else {
frames_processed = 0;
initialized = true;
@@ -453,9 +456,10 @@ uint32_t
AUPlugin::output_streams() const
{
if (!(format_set & 0x2)) {
- warning << _("AUPlugin: output_streams() called without any format set!") << endmsg;
+ warning << string_compose (_("AUPlugin: %1 output_streams() called without any format set!"), name()) << endmsg;
return 1;
}
+
return streamFormat.mChannelsPerFrame;
}
@@ -819,7 +823,6 @@ AUPluginInfo::discover_by_description (PluginInfoList& plugs, CAComponentDescrip
info->n_inputs = -1;
info->n_outputs = -1;
-
plugs.push_back (info);
comp = FindNextComponent (comp, &desc);
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 8d2589db0e..bdc1e8f0e4 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -82,9 +82,6 @@ AudioEngine::AudioEngine (string client_name)
if (connect_to_jack (client_name)) {
throw NoBackendAvailable ();
}
-
- start_metering_thread();
-
Port::set_engine (this);
}
@@ -169,6 +166,8 @@ AudioEngine::start ()
} else {
// error << _("cannot activate JACK client") << endmsg;
}
+
+ start_metering_thread();
}
return _running ? 0 : -1;
@@ -179,11 +178,11 @@ AudioEngine::stop (bool forever)
{
if (_running) {
_running = false;
+ stop_metering_thread ();
if (forever) {
jack_client_t* foo = _jack;
_jack = 0;
jack_client_close (foo);
- stop_metering_thread ();
} else {
jack_deactivate (_jack);
}
@@ -455,8 +454,9 @@ void
AudioEngine::start_metering_thread ()
{
if (m_meter_thread == 0) {
+ g_atomic_int_set (&m_meter_exit, 0);
m_meter_thread = Glib::Thread::create (sigc::mem_fun(this, &AudioEngine::meter_thread),
- 500000, true, true, Glib::THREAD_PRIORITY_NORMAL);
+ 500000, true, true, Glib::THREAD_PRIORITY_NORMAL);
}
}
@@ -861,6 +861,8 @@ AudioEngine::halted (void *arg)
AudioEngine* ae = static_cast<AudioEngine *> (arg);
bool was_running = ae->_running;
+ ae->stop_metering_thread ();
+
ae->_running = false;
ae->_buffer_size = 0;
ae->_frame_rate = 0;
@@ -1178,6 +1180,7 @@ AudioEngine::disconnect_from_jack ()
_frame_rate = 0;
if (_running) {
+ stop_metering_thread ();
_running = false;
Stopped(); /* EMIT SIGNAL */
}
@@ -1255,6 +1258,8 @@ AudioEngine::reconnect_to_jack ()
Running (); /* EMIT SIGNAL*/
+ start_metering_thread ();
+
return 0;
}
diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc
index 00e0f925df..268c4e18bb 100644
--- a/libs/ardour/audiofilesource.cc
+++ b/libs/ardour/audiofilesource.cc
@@ -38,6 +38,7 @@
#include <glibmm/miscutils.h>
#include <glibmm/fileutils.h>
+#include <glibmm/thread.h>
#include <ardour/audiofilesource.h>
#include <ardour/sndfile_helpers.h>
@@ -70,6 +71,21 @@ uint64_t AudioFileSource::header_position_offset = 0;
/* XXX maybe this too */
char AudioFileSource::bwf_serial_number[13] = "000000000000";
+struct SizedSampleBuffer {
+ nframes_t size;
+ Sample* buf;
+
+ SizedSampleBuffer (nframes_t sz) : size (sz) {
+ buf = new Sample[size];
+ }
+
+ ~SizedSampleBuffer() {
+ delete [] buf;
+ }
+};
+
+Glib::StaticPrivate<SizedSampleBuffer> thread_interleave_buffer = GLIBMM_STATIC_PRIVATE_INIT;
+
AudioFileSource::AudioFileSource (Session& s, ustring path, Flag flags)
: AudioSource (s, path), _flags (flags),
_channel (0)
@@ -678,6 +694,7 @@ AudioFileSource::safe_file_extension(ustring file)
{
return !(file.rfind(".wav") == ustring::npos &&
file.rfind(".aiff")== ustring::npos &&
+ file.rfind(".caf")== ustring::npos &&
file.rfind(".aif") == ustring::npos &&
file.rfind(".amb") == ustring::npos &&
file.rfind(".snd") == ustring::npos &&
@@ -711,3 +728,22 @@ AudioFileSource::mark_immutable ()
_flags = Flag (_flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy|CanRename));
}
}
+
+
+Sample*
+AudioFileSource::get_interleave_buffer (nframes_t size)
+{
+ SizedSampleBuffer* ssb;
+
+ if ((ssb = thread_interleave_buffer.get()) == 0) {
+ ssb = new SizedSampleBuffer (size);
+ thread_interleave_buffer.set (ssb);
+ }
+
+ if (ssb->size < size) {
+ ssb = new SizedSampleBuffer (size);
+ thread_interleave_buffer.set (ssb);
+ }
+
+ return ssb->buf;
+}
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 5e0cd136ff..7c0893f288 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -291,7 +291,7 @@ nframes64_t
AudioRegion::read (Sample* buf, nframes64_t position, nframes64_t cnt, int channel) const
{
/* raw read, no fades, no gain, nada */
- return _read_at (_sources, buf, 0, 0, _position + position, cnt, channel, 0, 0, true);
+ return _read_at (_sources, _length, buf, 0, 0, _position + position, cnt, channel, 0, 0, true);
}
nframes_t
@@ -300,18 +300,19 @@ AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, n
uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const
{
/* regular diskstream/butler read complete with fades etc */
- return _read_at (_sources, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, read_frames, skip_frames, false);
+ return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, read_frames, skip_frames, false);
}
nframes_t
AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position,
nframes_t cnt, uint32_t chan_n) const
{
- return _read_at (_master_sources, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0);
+ return _read_at (_master_sources, _master_sources.front()->length(), buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0);
}
nframes_t
-AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
+AudioRegion::_read_at (const SourceList& srcs, nframes_t limit,
+ Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
nframes_t position, nframes_t cnt,
uint32_t chan_n,
nframes_t read_frames,
@@ -337,11 +338,11 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff
buf_offset = 0;
}
- if (internal_offset >= _length) {
+ if (internal_offset >= limit) {
return 0; /* read nothing */
}
- if ((to_read = min (cnt, _length - internal_offset)) == 0) {
+ if ((to_read = min (cnt, limit - internal_offset)) == 0) {
return 0; /* read nothing */
}
@@ -394,13 +395,13 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff
if (internal_offset < fade_in_length) {
- nframes_t limit;
+ nframes_t fi_limit;
- limit = min (to_read, fade_in_length - internal_offset);
+ fi_limit = min (to_read, fade_in_length - internal_offset);
- _fade_in->curve().get_vector (internal_offset, internal_offset+limit, gain_buffer, limit);
+ _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit);
- for (nframes_t n = 0; n < limit; ++n) {
+ for (nframes_t n = 0; n < fi_limit; ++n) {
mixdown_buffer[n] *= gain_buffer[n];
}
}
@@ -409,40 +410,40 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff
/* fade out */
if (_flags & FadeOut) {
-
+
/* see if some part of this read is within the fade out */
/* ................. >| REGION
- _length
+ limit
{ } FADE
fade_out_length
^
- _length - fade_out_length
+ limit - fade_out_length
|--------------|
^internal_offset
^internal_offset + to_read
we need the intersection of [internal_offset,internal_offset+to_read] with
- [_length - fade_out_length, _length]
+ [limit - fade_out_length, limit]
*/
nframes_t fade_out_length = (nframes_t) _fade_out->back()->when;
- nframes_t fade_interval_start = max(internal_offset, _length-fade_out_length);
- nframes_t fade_interval_end = min(internal_offset + to_read, _length);
-
+ nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length);
+ nframes_t fade_interval_end = min(internal_offset + to_read, limit);
+
if (fade_interval_end > fade_interval_start) {
/* (part of the) the fade out is in this buffer */
-
- nframes_t limit = fade_interval_end - fade_interval_start;
- nframes_t curve_offset = fade_interval_start - (_length-fade_out_length);
+
+ nframes_t fo_limit = fade_interval_end - fade_interval_start;
+ nframes_t curve_offset = fade_interval_start - (limit-fade_out_length);
nframes_t fade_offset = fade_interval_start - internal_offset;
- _fade_out->curve().get_vector (curve_offset,curve_offset+limit, gain_buffer, limit);
-
- for (nframes_t n = 0, m = fade_offset; n < limit; ++n, ++m) {
+ _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit);
+
+ for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) {
mixdown_buffer[m] *= gain_buffer[n];
}
}
@@ -1020,7 +1021,6 @@ AudioRegion::read_raw_internal (Sample* buf, nframes_t pos, nframes_t cnt) const
return audio_source()->read (buf, pos, cnt);
}
-
int
AudioRegion::exportme (Session& session, ARDOUR::ExportSpecification& spec)
{
diff --git a/libs/ardour/caimportable.cc b/libs/ardour/caimportable.cc
new file mode 100644
index 0000000000..229bfa8809
--- /dev/null
+++ b/libs/ardour/caimportable.cc
@@ -0,0 +1,118 @@
+#include <ardour/caimportable.h>
+#include <sndfile.h>
+#include <pbd/error.h>
+
+#include "i18n.h"
+
+using namespace ARDOUR;
+using namespace std;
+using namespace PBD;
+
+CAImportableSource::CAImportableSource (const string& path)
+{
+ try {
+ af.Open (path.c_str());
+
+ CAStreamBasicDescription file_format (af.GetFileDataFormat());
+ CAStreamBasicDescription client_format (file_format);
+
+ /* set canonial form (PCM, native float packed, 32 bit, with the correct number of channels
+ and interleaved (since we plan to deinterleave ourselves)
+ */
+
+ client_format.SetCanonical(client_format.NumberChannels(), true);
+ af.SetClientFormat (client_format);
+
+ } catch (CAXException& cax) {
+ error << string_compose ("CAImportable: %1", cax.mOperation) << endmsg;
+ throw failed_constructor ();
+ }
+
+}
+
+CAImportableSource::~CAImportableSource ()
+{
+}
+
+nframes_t
+CAImportableSource::read (Sample* buffer, nframes_t nframes)
+{
+ nframes_t nread = 0;
+ AudioBufferList abl;
+ nframes_t per_channel;
+ bool at_end = false;
+
+ abl.mNumberBuffers = 1;
+ abl.mBuffers[0].mNumberChannels = channels();
+
+ per_channel = nframes / abl.mBuffers[0].mNumberChannels;
+
+ while (nread < per_channel) {
+
+ UInt32 new_cnt = per_channel - nread;
+
+ abl.mBuffers[0].mDataByteSize = new_cnt * abl.mBuffers[0].mNumberChannels * sizeof(Sample);
+ abl.mBuffers[0].mData = buffer + nread;
+
+ try {
+ af.Read (new_cnt, &abl);
+ } catch (CAXException& cax) {
+ error << string_compose("CAImportable: %1", cax.mOperation);
+ return -1;
+ }
+
+ if (new_cnt == 0) {
+ /* EOF */
+ at_end = true;
+ break;
+ }
+
+ nread += new_cnt;
+ }
+
+ if (!at_end && nread < per_channel) {
+ return 0;
+ } else {
+ return nread * abl.mBuffers[0].mNumberChannels;
+ }
+}
+
+uint
+CAImportableSource::channels () const
+{
+ return af.GetFileDataFormat().NumberChannels();
+}
+
+nframes_t
+CAImportableSource::length () const
+{
+ return af.GetNumberFrames();
+}
+
+nframes_t
+CAImportableSource::samplerate() const
+{
+ CAStreamBasicDescription client_asbd;
+
+ try {
+ client_asbd = af.GetClientDataFormat ();
+ } catch (CAXException& cax) {
+ error << string_compose ("CAImportable: %1", cax.mOperation) << endmsg;
+ return 0.0;
+ }
+
+ return client_asbd.mSampleRate;
+}
+
+void
+CAImportableSource::seek (nframes_t pos)
+{
+ try {
+ af.Seek (pos);
+ } catch (CAXException& cax) {
+ error << string_compose ("CAImportable: %1 to %2", cax.mOperation, pos) << endmsg;
+ }
+}
+
+
+
diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc
index 703225e502..4383f1a696 100644
--- a/libs/ardour/coreaudiosource.cc
+++ b/libs/ardour/coreaudiosource.cc
@@ -1,5 +1,6 @@
/*
- Copyright (C) 2006 Paul Davis
+ Copyright (C) 2006 Paul Davis
+ Written by Taybin Rutkin
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
@@ -17,6 +18,8 @@
*/
+#include <algorithm>
+
#include <pbd/error.h>
#include <ardour/coreaudiosource.h>
#include <ardour/utils.h>
@@ -28,6 +31,7 @@
#include <AudioToolbox/AudioFormat.h>
+using namespace std;
using namespace ARDOUR;
using namespace PBD;
@@ -48,18 +52,12 @@ CoreAudioSource::CoreAudioSource (Session& s, const string& path, int chn, Flag
void
CoreAudioSource::init ()
{
- tmpbuf = 0;
- tmpbufsize = 0;
-
- cerr << "CoreAudioSource::init() " << name() << endl;
-
/* note that we temporarily truncated _id at the colon */
try {
af.Open(_path.c_str());
- CAStreamBasicDescription file_asbd (af.GetFileDataFormat());
- n_channels = file_asbd.NumberChannels();
- cerr << "number of channels: " << n_channels << endl;
+ CAStreamBasicDescription file_format (af.GetFileDataFormat());
+ n_channels = file_format.NumberChannels();
if (_channel >= n_channels) {
error << string_compose("CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel number (%3)", n_channels, _channel, name()) << endmsg;
@@ -68,92 +66,136 @@ CoreAudioSource::init ()
_length = af.GetNumberFrames();
- CAStreamBasicDescription client_asbd(file_asbd);
- client_asbd.SetCanonical(client_asbd.NumberChannels(), false);
- af.SetClientFormat (client_asbd);
+ CAStreamBasicDescription client_format (file_format);
+
+ /* set canonial form (PCM, native float packed, 32 bit, with the correct number of channels
+ and interleaved (since we plan to deinterleave ourselves)
+ */
+
+ client_format.SetCanonical(client_format.NumberChannels(), true);
+ af.SetClientFormat (client_format);
+
} catch (CAXException& cax) {
- error << string_compose ("CoreAudioSource: %1 (%2)", cax.mOperation, name()) << endmsg;
+
+ error << string_compose(_("CoreAudioSource: cannot open file \"%1\" for %2"),
+ _path, (writable() ? "read+write" : "reading")) << endmsg;
throw failed_constructor ();
}
}
CoreAudioSource::~CoreAudioSource ()
{
- cerr << "CoreAudioSource::~CoreAudioSource() " << name() << endl;
GoingAway (); /* EMIT SIGNAL */
-
- if (tmpbuf) {
- delete [] tmpbuf;
- }
-
- cerr << "deletion done" << endl;
}
-nframes_t
-CoreAudioSource::read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const
+int
+CoreAudioSource::safe_read (Sample* dst, nframes_t start, nframes_t cnt, AudioBufferList& abl) const
{
- try {
- af.Seek (start);
- } catch (CAXException& cax) {
- error << string_compose("CoreAudioSource: %1 to %2 (%3)", cax.mOperation, start, _name.substr (1)) << endmsg;
- return 0;
- }
-
- AudioBufferList abl;
- abl.mNumberBuffers = 1;
- abl.mBuffers[0].mNumberChannels = n_channels;
+ nframes_t nread = 0;
- UInt32 new_cnt = cnt;
- if (n_channels == 1) {
- abl.mBuffers[0].mDataByteSize = cnt * sizeof(Sample);
- abl.mBuffers[0].mData = dst;
+ while (nread < cnt) {
+
+ try {
+ af.Seek (start+nread);
+ } catch (CAXException& cax) {
+ error << string_compose("CoreAudioSource: %1 to %2 (%3)", cax.mOperation, start+nread, _name.substr (1)) << endmsg;
+ return -1;
+ }
+
+ UInt32 new_cnt = cnt - nread;
+
+ abl.mBuffers[0].mDataByteSize = new_cnt * n_channels * sizeof(Sample);
+ abl.mBuffers[0].mData = dst + nread;
+
try {
af.Read (new_cnt, &abl);
} catch (CAXException& cax) {
error << string_compose("CoreAudioSource: %1 (%2)", cax.mOperation, _name);
+ return -1;
}
- _read_data_count = new_cnt * sizeof(float);
- return new_cnt;
- }
-
- UInt32 real_cnt = cnt * n_channels;
- {
- Glib::Mutex::Lock lm (_tmpbuf_lock);
-
- if (tmpbufsize < real_cnt) {
-
- if (tmpbuf) {
- delete [] tmpbuf;
+ if (new_cnt == 0) {
+ /* EOF */
+ if (start+cnt == _length) {
+ /* we really did hit the end */
+ nread = cnt;
}
- tmpbufsize = real_cnt;
- tmpbuf = new float[tmpbufsize];
+ break;
}
- abl.mBuffers[0].mDataByteSize = tmpbufsize * sizeof(Sample);
- abl.mBuffers[0].mData = tmpbuf;
+ nread += new_cnt;
+ }
- cerr << "channel: " << _channel << endl;
+ if (nread < cnt) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+
+nframes_t
+CoreAudioSource::read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const
+{
+ nframes_t file_cnt;
+ AudioBufferList abl;
+
+ abl.mNumberBuffers = 1;
+ abl.mBuffers[0].mNumberChannels = n_channels;
+
+ if (start > _length) {
+
+ /* read starts beyond end of data, just memset to zero */
- try {
- af.Read (real_cnt, &abl);
- } catch (CAXException& cax) {
- error << string_compose("CoreAudioSource: %1 (%2)", cax.mOperation, _name);
- }
- float *ptr = tmpbuf + _channel;
- real_cnt /= n_channels;
+ file_cnt = 0;
+
+ } else if (start + cnt > _length) {
- /* stride through the interleaved data */
+ /* read ends beyond end of data, read some, memset the rest */
+
+ file_cnt = _length - start;
+
+ } else {
- for (uint32_t n = 0; n < real_cnt; ++n) {
- dst[n] = *ptr;
- ptr += n_channels;
+ /* read is entirely within data */
+
+ file_cnt = cnt;
+ }
+
+ if (file_cnt != cnt) {
+ nframes_t delta = cnt - file_cnt;
+ memset (dst+file_cnt, 0, sizeof (Sample) * delta);
+ }
+
+ if (file_cnt) {
+
+ if (n_channels == 1) {
+ if (safe_read (dst, start, file_cnt, abl) == 0) {
+ _read_data_count = cnt * sizeof (Sample);
+ return cnt;
+ }
+ return 0;
}
}
+ Sample* interleave_buf = get_interleave_buffer (file_cnt * n_channels);
+
+ if (safe_read (interleave_buf, start, file_cnt, abl) != 0) {
+ return 0;
+ }
+
_read_data_count = cnt * sizeof(float);
-
- return real_cnt;
+
+ Sample *ptr = interleave_buf + _channel;
+
+ /* stride through the interleaved data */
+
+ for (uint32_t n = 0; n < file_cnt; ++n) {
+ dst[n] = *ptr;
+ ptr += n_channels;
+ }
+
+ return cnt;
}
float
diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc
index f7711b3224..f3dfa28165 100644
--- a/libs/ardour/crossfade.cc
+++ b/libs/ardour/crossfade.cc
@@ -84,7 +84,7 @@ Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<Audio
{
_in = in;
_out = out;
-
+
_anchor_point = ap;
_follow_overlap = false;
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index 02c4a5ced6..9a71303927 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -412,6 +412,21 @@ ARDOUR::get_ardour_revision ()
return "$Rev$";
}
+static bool sae_binding_filter (const string& str, void* arg)
+{
+ /* Not a dotfile, has a prefix before a period, suffix is ".bindings" and contains -sae- */
+
+ return str[0] != '.' && str.length() > 13 && str.find (".bindings") == (str.length() - 9)
+ && str.find ("SAE-") != string::npos;
+}
+
+static bool binding_filter (const string& str, void* arg)
+{
+ /* Not a dotfile, has a prefix before a period, suffix is ".bindings" */
+
+ return str[0] != '.' && str.length() > 9 && str.find (".bindings") == (str.length() - 9);
+}
+
void
ARDOUR::find_bindings_files (map<string,string>& files)
{
diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc
index a0266521d4..a29cc1817b 100644
--- a/libs/ardour/import.cc
+++ b/libs/ardour/import.cc
@@ -48,26 +48,66 @@
#include <ardour/region_factory.h>
#include <ardour/source_factory.h>
#include <ardour/resampled_source.h>
+#include <ardour/sndfileimportable.h>
#include <ardour/analyser.h>
#include <ardour/smf_reader.h>
#include <ardour/smf_source.h>
#include <ardour/tempo.h>
+#ifdef HAVE_COREAUDIO
+#include <ardour/caimportable.h>
+#endif
+
#include "i18n.h"
using namespace ARDOUR;
using namespace PBD;
-static std::auto_ptr<ImportableSource>
+
+static boost::shared_ptr<ImportableSource>
open_importable_source (const string& path, nframes_t samplerate, ARDOUR::SrcQuality quality)
{
- std::auto_ptr<ImportableSource> source(new ImportableSource(path));
+#ifdef HAVE_COREAUDIO
- if (source->samplerate() == samplerate) {
- return source;
- }
+ /* see if we can use CoreAudio to handle the IO */
- return std::auto_ptr<ImportableSource>(new ResampledImportableSource(path, samplerate, quality));
+ try {
+ boost::shared_ptr<CAImportableSource> source(new CAImportableSource(path));
+
+ if (source->samplerate() == samplerate) {
+ return source;
+ }
+
+ /* rewrap as a resampled source */
+
+ return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality));
+ }
+
+ catch (...) {
+
+ /* fall back to SndFile */
+
+#endif
+
+ try {
+ boost::shared_ptr<SndFileImportableSource> source(new SndFileImportableSource(path));
+
+ if (source->samplerate() == samplerate) {
+ return source;
+ }
+
+ /* rewrap as a resampled source */
+
+ return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality));
+ }
+
+ catch (...) {
+ throw; // rethrow
+ }
+
+#ifdef HAVE_COREAUDIO
+ }
+#endif
}
static std::string
@@ -306,7 +346,7 @@ write_midi_data_to_new_files (SMFReader* source, Session::import_status& status,
smfs->session().engine().frame_rate(),
smfs->session().tempo_map().meter_at(timeline_position));
- smfs->update_length(0, (t * source->ppqn()) * frames_per_beat);
+ smfs->update_length(0, (nframes_t) floor ((t * source->ppqn()) * frames_per_beat));
smfs->flush_header();
smfs->flush_footer();
@@ -345,26 +385,24 @@ Session::import_audiofiles (import_status& status)
p != status.paths.end() && !status.cancel;
++p, ++cnt)
{
- std::auto_ptr<ImportableSource> source;
+
+ boost::shared_ptr<ImportableSource> source;
std::auto_ptr<SMFReader> smf_reader;
+ const DataType type = ((*p).rfind(".mid") != string::npos) ?
+ DataType::MIDI : DataType::AUDIO;
- const DataType type = ((*p).rfind(".mid") != string::npos)
- ? DataType::MIDI : DataType::AUDIO;
-
if (type == DataType::AUDIO) {
- try
- {
+ try {
source = open_importable_source (*p, frame_rate(), status.quality);
channels = source->channels();
- } catch (const failed_constructor& err)
- {
+ } catch (const failed_constructor& err) {
error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
status.done = status.cancel = true;
return;
}
+
} else {
- try
- {
+ try {
smf_reader = std::auto_ptr<SMFReader>(new SMFReader(*p));
channels = smf_reader->num_tracks();
} catch (const SMFReader::UnsupportedTime& err) {
@@ -378,11 +416,9 @@ Session::import_audiofiles (import_status& status)
}
}
- vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source,
- *p,
- get_best_session_directory_for_new_source (),
- channels);
-
+ vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source, *p,
+ get_best_session_directory_for_new_source (),
+ channels);
Sources newfiles;
if (status.replace_existing_source) {
@@ -403,9 +439,9 @@ Session::import_audiofiles (import_status& status)
}
}
- if (source.get()) { // audio
+ if (source) { // audio
status.doing_what = compose_status_message (*p, source->samplerate(),
- frame_rate(), cnt, status.paths.size());
+ frame_rate(), cnt, status.paths.size());
write_audio_data_to_new_files (source.get(), status, newfiles);
} else if (smf_reader.get()) { // midi
status.doing_what = string_compose(_("loading MIDI file %1"), *p);
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index f57d5b39de..cb9fedd7a3 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -2119,9 +2119,8 @@ IO::setup_peak_meters()
void
IO::update_meters()
{
- Glib::Mutex::Lock guard (m_meter_signal_lock);
-
- Meter(); /* EMIT SIGNAL */
+ Glib::Mutex::Lock guard (m_meter_signal_lock);
+ Meter(); /* EMIT SIGNAL */
}
void
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 7bc4287a58..f1818420ed 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -331,7 +331,6 @@ Playlist::release_notifications ()
}
}
-
void
Playlist::notify_modified ()
{
@@ -676,53 +675,64 @@ Playlist::partition (nframes_t start, nframes_t end, bool just_top_level)
void
Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, RegionList& thawlist)
{
- RegionLock rlock (this);
- boost::shared_ptr<Region> region;
- boost::shared_ptr<Region> current;
- string new_name;
- RegionList::iterator tmp;
- OverlapType overlap;
- nframes_t pos1, pos2, pos3, pos4;
RegionList new_regions;
- in_partition = true;
-
- /* need to work from a copy, because otherwise the regions we add during the process
- get operated on as well.
- */
-
- RegionList copy = regions;
-
- for (RegionList::iterator i = copy.begin(); i != copy.end(); i = tmp) {
+ {
+ RegionLock rlock (this);
+ boost::shared_ptr<Region> region;
+ boost::shared_ptr<Region> current;
+ string new_name;
+ RegionList::iterator tmp;
+ OverlapType overlap;
+ nframes_t pos1, pos2, pos3, pos4;
- tmp = i;
- ++tmp;
-
- current = *i;
+ in_partition = true;
- if (current->first_frame() == start && current->last_frame() == end) {
- if (cutting) {
- remove_region_internal (current);
- }
- continue;
- }
+ /* need to work from a copy, because otherwise the regions we add during the process
+ get operated on as well.
+ */
- if ((overlap = current->coverage (start, end)) == OverlapNone) {
- continue;
- }
+ RegionList copy = regions;
- pos1 = current->position();
- pos2 = start;
- pos3 = end;
- pos4 = current->last_frame();
+ for (RegionList::iterator i = copy.begin(); i != copy.end(); i = tmp) {
+
+ tmp = i;
+ ++tmp;
+
+ current = *i;
- if (overlap == OverlapInternal) {
+ if (current->first_frame() >= start && current->last_frame() < end) {
+ if (cutting) {
+ remove_region_internal (current);
+ }
+ continue;
+ }
- /* split: we need 3 new regions, the front, middle and end.
- cut: we need 2 regions, the front and end.
+ /* coverage will return OverlapStart if the start coincides
+ with the end point. we do not partition such a region,
+ so catch this special case.
*/
+
+ if (current->first_frame() >= end) {
+ continue;
+ }
+
+ if ((overlap = current->coverage (start, end)) == OverlapNone) {
+ continue;
+ }
+
+ pos1 = current->position();
+ pos2 = start;
+ pos3 = end;
+ pos4 = current->last_frame();
+
+ if (overlap == OverlapInternal) {
- /*
+ /* split: we need 3 new regions, the front, middle and end.
+ cut: we need 2 regions, the front and end.
+ */
+
+ /*
start end
---------------*************************------------
P1 P2 P3 P4
@@ -731,37 +741,37 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
CUT
---------------*****----------------====------------
- */
+ */
- if (!cutting) {
+ if (!cutting) {
- /* "middle" ++++++ */
+ /* "middle" ++++++ */
+
+ _session.region_name (new_name, current->name(), false);
+ region = RegionFactory::create (current, pos2 - pos1, pos3 - pos2, new_name,
+ regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit|Region::RightOfSplit));
+ add_region_internal (region, start);
+ new_regions.push_back (region);
+ }
+ /* "end" ====== */
+
_session.region_name (new_name, current->name(), false);
- region = RegionFactory::create (current, pos2 - pos1, pos3 - pos2, new_name,
- regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit|Region::RightOfSplit));
- add_region_internal (region, start);
+ region = RegionFactory::create (current, pos3 - pos1, pos4 - pos3, new_name,
+ regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
+
+ add_region_internal (region, end);
new_regions.push_back (region);
- }
-
- /* "end" ====== */
-
- _session.region_name (new_name, current->name(), false);
- region = RegionFactory::create (current, pos3 - pos1, pos4 - pos3, new_name,
- regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
-
- add_region_internal (region, end);
- new_regions.push_back (region);
-
- /* "front" ***** */
- current->freeze ();
- thawlist.push_back (current);
- current->trim_end (pos2, this);
-
- } else if (overlap == OverlapEnd) {
-
- /*
+ /* "front" ***** */
+
+ current->freeze ();
+ thawlist.push_back (current);
+ current->trim_end (pos2, this);
+
+ } else if (overlap == OverlapEnd) {
+
+ /*
start end
---------------*************************------------
P1 P2 P4 P3
@@ -769,33 +779,32 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
---------------**************+++++++++++------------
CUT:
---------------**************-----------------------
-
- */
-
- if (!cutting) {
+ */
- /* end +++++ */
+ if (!cutting) {
+
+ /* end +++++ */
+
+ _session.region_name (new_name, current->name(), false);
+ region = RegionFactory::create (current, pos2 - pos1, pos4 - pos2, new_name, (layer_t) regions.size(),
+ Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit));
+ add_region_internal (region, start);
+ new_regions.push_back (region);
+ }
- _session.region_name (new_name, current->name(), false);
- region = RegionFactory::create (current, pos2 - pos1, pos4 - pos2, new_name, (layer_t) regions.size(),
- Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit));
- add_region_internal (region, start);
- new_regions.push_back (region);
- }
-
- /* front ****** */
-
- current->freeze ();
- thawlist.push_back (current);
- current->trim_end (pos2, this);
-
- } else if (overlap == OverlapStart) {
-
- /* split: we need 2 regions: the front and the end.
- cut: just trim current to skip the cut area
- */
+ /* front ****** */
- /*
+ current->freeze ();
+ thawlist.push_back (current);
+ current->trim_end (pos2, this);
+
+ } else if (overlap == OverlapStart) {
+
+ /* split: we need 2 regions: the front and the end.
+ cut: just trim current to skip the cut area
+ */
+
+ /*
start end
---------------*************************------------
P2 P1 P3 P4
@@ -805,31 +814,31 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
CUT:
-------------------*********************------------
- */
+ */
- if (!cutting) {
+ if (!cutting) {
- /* front **** */
- _session.region_name (new_name, current->name(), false);
- region = RegionFactory::create (current, 0, pos3 - pos1, new_name,
- regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
- add_region_internal (region, pos1);
- new_regions.push_back (region);
- }
-
- /* end */
-
- current->freeze ();
- thawlist.push_back (current);
- current->trim_front (pos3, this);
-
- } else if (overlap == OverlapExternal) {
-
- /* split: no split required.
- cut: remove the region.
- */
+ /* front **** */
+ _session.region_name (new_name, current->name(), false);
+ region = RegionFactory::create (current, 0, pos3 - pos1, new_name,
+ regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
+ add_region_internal (region, pos1);
+ new_regions.push_back (region);
+ }
+
+ /* end */
+
+ current->freeze ();
+ thawlist.push_back (current);
+ current->trim_front (pos3, this);
+
+ } else if (overlap == OverlapExternal) {
+
+ /* split: no split required.
+ cut: remove the region.
+ */
- /*
+ /*
start end
---------------*************************------------
P2 P1 P3 P4
@@ -839,16 +848,21 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
CUT:
----------------------------------------------------
- */
-
- if (cutting) {
- remove_region_internal (current);
+ */
+
+ if (cutting) {
+ remove_region_internal (current);
+ }
+ new_regions.push_back (current);
}
- new_regions.push_back (current);
}
- }
+
+ if (current->first_frame() >= current->last_frame()) {
+ PBD::stacktrace (cerr);
+ }
- in_partition = false;
+ in_partition = false;
+ }
for (RegionList::iterator i = new_regions.begin(); i != new_regions.end(); ++i) {
check_dependents (*i, false);
diff --git a/libs/ardour/rb_effect.cc b/libs/ardour/rb_effect.cc
index 9711e5e4dc..4daf5cb33a 100644
--- a/libs/ardour/rb_effect.cc
+++ b/libs/ardour/rb_effect.cc
@@ -74,6 +74,9 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
nframes_t pos = 0;
int avail = 0;
+ // note: this_time_fraction is a ratio of original length. 1.0 = no change,
+ // 0.5 is half as long, 2.0 is twice as long, etc.
+
double this_time_fraction = tsr.time_fraction * region->stretch ();
double this_pitch_fraction = tsr.pitch_fraction * region->shift ();
@@ -81,14 +84,14 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
(RubberBandStretcher::Options) tsr.opts,
this_time_fraction, this_pitch_fraction);
- stretcher.setExpectedInputDuration(region->length());
- stretcher.setDebugLevel(1);
-
tsr.progress = 0.0f;
tsr.done = false;
uint32_t channels = region->n_channels();
- nframes_t duration = region->length();
+ nframes_t duration = region->ancestral_length();
+
+ stretcher.setExpectedInputDuration(duration);
+ stretcher.setDebugLevel(1);
/* the name doesn't need to be super-precise, but allow for 2 fractional
digits just to disambiguate close but not identical FX
@@ -149,8 +152,8 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
if (this_read != this_time) {
error << string_compose
- (_("tempoize: error reading data from %1"),
- nsrcs[i]->name()) << endmsg;
+ (_("tempoize: error reading data from %1 at %2 (wanted %3, got %4)"),
+ region->name(), pos + region->position(), this_time, this_read) << endmsg;
goto out;
}
}
@@ -187,8 +190,8 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
if (this_read != this_time) {
error << string_compose
- (_("tempoize: error reading data from %1"),
- nsrcs[i]->name()) << endmsg;
+ (_("tempoize: error reading data from %1 at %2 (wanted %3, got %4)"),
+ region->name(), pos + region->position(), this_time, this_read) << endmsg;
goto out;
}
}
@@ -257,21 +260,12 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
/* now reset ancestral data for each new region */
for (vector<boost::shared_ptr<AudioRegion> >::iterator x = results.begin(); x != results.end(); ++x) {
- nframes64_t astart = (*x)->ancestral_start();
- nframes64_t alength = (*x)->ancestral_length();
- nframes_t start;
- nframes_t length;
-
- // note: this_time_fraction is a ratio of original length. 1.0 = no change,
- // 0.5 is half as long, 2.0 is twice as long, etc.
-
- float stretch = (*x)->stretch() * (tsr.time_fraction/100.0);
- float shift = (*x)->shift() * tsr.pitch_fraction;
-
- start = (nframes_t) floor (astart + ((astart - (*x)->start()) / stretch));
- length = (nframes_t) floor (alength / stretch);
- (*x)->set_ancestral_data (start, length, stretch, shift);
+ (*x)->set_ancestral_data (region->ancestral_start(),
+ region->ancestral_length(),
+ this_time_fraction,
+ this_pitch_fraction );
+ (*x)->set_master_sources (region->get_master_sources());
}
out:
diff --git a/libs/ardour/resampled_source.cc b/libs/ardour/resampled_source.cc
index b5d23fb4a2..083fde95a1 100644
--- a/libs/ardour/resampled_source.cc
+++ b/libs/ardour/resampled_source.cc
@@ -26,15 +26,14 @@
using namespace ARDOUR;
using namespace PBD;
-const uint32_t ResampledImportableSource::blocksize = 4096U;
+const uint32_t ResampledImportableSource::blocksize = 16384U;
-ResampledImportableSource::ResampledImportableSource (const std::string& path,
- nframes_t rate, SrcQuality srcq)
- : ImportableSource (path)
+ResampledImportableSource::ResampledImportableSource (boost::shared_ptr<ImportableSource> src, nframes_t rate, SrcQuality srcq)
+ : source (src)
{
int err;
- sf_seek (in.get(), 0, SEEK_SET) ;
+ source->seek (0);
/* Initialize the sample rate converter. */
@@ -58,7 +57,7 @@ ResampledImportableSource::ResampledImportableSource (const std::string& path,
break;
}
- if ((src_state = src_new (src_type, sf_info.channels, &err)) == 0) {
+ if ((src_state = src_new (src_type, source->channels(), &err)) == 0) {
error << string_compose(_("Import: src_new() failed : %1"), src_strerror (err)) << endmsg ;
throw failed_constructor ();
}
@@ -70,7 +69,7 @@ ResampledImportableSource::ResampledImportableSource (const std::string& path,
src_data.input_frames = 0 ;
src_data.data_in = input ;
- src_data.src_ratio = ((float) rate) / sf_info.samplerate ;
+ src_data.src_ratio = ((float) rate) / source->samplerate();
input = new float[blocksize];
}
@@ -90,22 +89,22 @@ ResampledImportableSource::read (Sample* output, nframes_t nframes)
if (src_data.input_frames == 0) {
- src_data.input_frames = ImportableSource::read (input, blocksize);
+ src_data.input_frames = source->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.end_of_input = true;
}
- src_data.input_frames /= sf_info.channels;
- src_data.data_in = input ;
+ src_data.input_frames /= source->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 ;
+ src_data.output_frames = nframes / source->channels();
} else {
src_data.output_frames = src_data.input_frames;
}
@@ -121,9 +120,9 @@ ResampledImportableSource::read (Sample* output, nframes_t nframes)
return 0;
}
- src_data.data_in += src_data.input_frames_used * sf_info.channels ;
+ src_data.data_in += src_data.input_frames_used * source->channels();
src_data.input_frames -= src_data.input_frames_used ;
- return src_data.output_frames_gen * sf_info.channels;
+ return src_data.output_frames_gen * source->channels();
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 560946d9da..85e849de2e 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -828,7 +828,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(processor)) != 0) {
pi->set_count (1);
-
+
if (pi->natural_input_streams() == ChanCount::ZERO) {
/* generator plugin */
_have_internal_generator = true;
@@ -1198,6 +1198,8 @@ Route::_reset_plugin_counts (ProcessorStreams* err)
ProcessorList::iterator r;
map<Placement,list<ProcessorCount> > processor_map;
ChanCount initial_streams;
+ ChanCount post_fader_input;
+ int ret = -1;
/* Process each placement in order, checking to see if we
can really do what has been requested.
@@ -1205,7 +1207,8 @@ Route::_reset_plugin_counts (ProcessorStreams* err)
/* divide processors up by placement so we get the signal flow
properly modelled. we need to do this because the _processors
- list is not sorted by placement
+ list is not sorted by placement, and because other reasons may
+ exist now or in the future for this separate treatment.
*/
/* ... but it should/will be... */
@@ -1219,19 +1222,18 @@ Route::_reset_plugin_counts (ProcessorStreams* err)
}
}
-
/* A: PreFader */
if ( ! check_some_plugin_counts (processor_map[PreFader], n_inputs (), err)) {
- return -1;
+ goto streamcount;
}
- ChanCount post_fader_input = (err ? err->count : n_inputs());
+ post_fader_input = (err ? err->count : n_inputs());
/* B: PostFader */
if ( ! check_some_plugin_counts (processor_map[PostFader], post_fader_input, err)) {
- return -1;
+ goto streamcount;
}
/* OK, everything can be set up correctly, so lets do it */
@@ -1241,15 +1243,15 @@ Route::_reset_plugin_counts (ProcessorStreams* err)
/* recompute max outs of any processor */
+ ret = 0;
+
+ streamcount:
processor_max_outs.reset();
- ProcessorList::iterator prev = _processors.end();
- for (r = _processors.begin(); r != _processors.end(); prev = r, ++r) {
+ for (r = _processors.begin(); r != _processors.end(); ++r) {
processor_max_outs = max ((*r)->output_streams (), processor_max_outs);
}
- /* we're done */
-
return 0;
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index ae41f3c0dc..71d7a07748 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -431,14 +431,13 @@ Session::destroy ()
tmp = i;
++tmp;
-
+
i->second->drop_references ();
-
+
i = tmp;
}
-
sources.clear ();
-
+
#ifdef TRACK_DESTRUCTION
cerr << "delete mix groups\n";
#endif /* TRACK_DESTRUCTION */
@@ -684,7 +683,7 @@ Session::when_engine_running ()
add_bundle (c);
}
- BootMessage (_("Connect ports"));
+ BootMessage (_("Setup signal flow and plugins"));
hookup_io ();
@@ -2835,6 +2834,8 @@ Session::remove_source (boost::weak_ptr<Source> src)
return;
}
+ cerr << "remove source for " << source->name() << endl;
+
{
Glib::Mutex::Lock lm (source_lock);
@@ -4165,7 +4166,7 @@ Session::get_silent_buffers (ChanCount count)
_silent_buffers->set_count(count);
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
- for (size_t i=0; i < count.get(*t); ++i) {
+ for (size_t i= 0; i < count.get(*t); ++i) {
_silent_buffers->get(*t, i).clear();
}
}
diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc
index ccbc08248d..872f97eab9 100644
--- a/libs/ardour/session_butler.cc
+++ b/libs/ardour/session_butler.cc
@@ -29,6 +29,7 @@
#include <pbd/error.h>
#include <pbd/pthread_utils.h>
+#include <pbd/stacktrace.h>
#include <ardour/configuration.h>
#include <ardour/audioengine.h>
@@ -130,6 +131,7 @@ Session::summon_butler ()
{
char c = ButlerRequest::Run;
::write (butler_request_pipe[1], &c, 1);
+ // PBD::stacktrace (cerr);
}
void
diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc
index f1355b331b..5fc8cd7535 100644
--- a/libs/ardour/session_events.cc
+++ b/libs/ardour/session_events.cc
@@ -355,7 +355,8 @@ Session::process_event (Event* ev)
case Event::LocateRollLocate:
// locate is handled by ::request_roll_at_and_return()
_requested_return_frame = ev->target_frame;
- set_transport_speed (ev->speed, true);
+ cerr << "Set RRF " << ev->target_frame << endl;
+ request_locate (ev->target2_frame, true);
break;
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index c4448640fd..70abd01a72 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -1741,7 +1741,8 @@ Session::XMLSourceFactory (const XMLNode& node)
}
try {
- return SourceFactory::create (*this, node);
+ /* note: do peak building in another thread when loading session state */
+ return SourceFactory::create (*this, node, true);
}
catch (failed_constructor& err) {
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index e6318f5503..8001b87204 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -415,6 +415,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
do_locate = true;
} else {
_transport_frame = last_stop_frame;
+ _requested_return_frame = -1;
}
if (synced_to_jack() && !play_loop) {
@@ -451,7 +452,18 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
}
#endif
- last_stop_frame = _transport_frame;
+ if (_requested_return_frame < 0) {
+ last_stop_frame = _transport_frame;
+ } else {
+ last_stop_frame = _requested_return_frame;
+ _requested_return_frame = -1;
+ }
+
+/* MISSING IN 3.0 ... move into realtime_stop() */
+// send_full_time_code ();
+// deliver_mmc (MIDI::MachineControl::cmdStop, 0);
+// deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
+/* END WHY */
if (did_record) {
@@ -1226,8 +1238,8 @@ Session::setup_auto_play ()
void
Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
{
- request_locate (start, false);
Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
+ ev->target2_frame = start;
queue_event (ev);
}
diff --git a/libs/ardour/sndfileimportable.cc b/libs/ardour/sndfileimportable.cc
new file mode 100644
index 0000000000..eb0e8a8afb
--- /dev/null
+++ b/libs/ardour/sndfileimportable.cc
@@ -0,0 +1,47 @@
+#include <ardour/sndfileimportable.h>
+#include <sndfile.h>
+
+using namespace ARDOUR;
+using namespace std;
+
+SndFileImportableSource::SndFileImportableSource (const string& path)
+ : in (sf_open (path.c_str(), SFM_READ, &sf_info), sf_close)
+{
+ if (!in) throw failed_constructor();
+}
+
+SndFileImportableSource::~SndFileImportableSource ()
+{
+}
+
+nframes_t
+SndFileImportableSource::read (Sample* buffer, nframes_t nframes)
+{
+ nframes_t per_channel = nframes / sf_info.channels;
+ per_channel = sf_readf_float (in.get(), buffer, per_channel);
+ return per_channel * sf_info.channels;
+}
+
+uint
+SndFileImportableSource::channels () const
+{
+ return sf_info.channels;
+}
+
+nframes_t
+SndFileImportableSource::length () const
+{
+ return sf_info.frames;
+}
+
+nframes_t
+SndFileImportableSource::samplerate() const
+{
+ return sf_info.samplerate;
+}
+
+void
+SndFileImportableSource::seek (nframes_t pos)
+{
+ sf_seek (in.get(), 0, SEEK_SET);
+}
diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc
index 7c4859aa55..e534964343 100644
--- a/libs/ardour/sndfilesource.cc
+++ b/libs/ardour/sndfilesource.cc
@@ -25,7 +25,6 @@
#include <sys/stat.h>
#include <glibmm/miscutils.h>
-#include <glibmm/thread.h>
#include <ardour/sndfilesource.h>
#include <ardour/sndfile_helpers.h>
#include <ardour/utils.h>
@@ -44,22 +43,6 @@ const AudioFileSource::Flag SndFileSource::default_writable_flags = AudioFileSou
AudioFileSource::Removable|
AudioFileSource::RemovableIfEmpty|
AudioFileSource::CanRename);
-
-struct SizedSampleBuffer {
- nframes_t size;
- Sample* buf;
-
- SizedSampleBuffer (nframes_t sz) : size (sz) {
- buf = new Sample[size];
- }
-
- ~SizedSampleBuffer() {
- delete [] buf;
- }
-};
-
-Glib::StaticPrivate<SizedSampleBuffer> thread_interleave_buffer = GLIBMM_STATIC_PRIVATE_INIT;
-
SndFileSource::SndFileSource (Session& s, const XMLNode& node)
: AudioFileSource (s, node)
{
@@ -95,7 +78,7 @@ SndFileSource::SndFileSource (Session& s, ustring path, SampleFormat sfmt, Heade
*/
file_is_new = true;
-
+
switch (hf) {
case CAF:
fmt = SF_FORMAT_CAF;
@@ -189,9 +172,8 @@ SndFileSource::SndFileSource (Session& s, ustring path, SampleFormat sfmt, Heade
_flags = Flag (_flags & ~Broadcast);
delete _broadcast_info;
_broadcast_info = 0;
- }
-
- }
+ }
+ }
}
void
@@ -234,13 +216,21 @@ SndFileSource::open ()
if ((sf = sf_open (_path.c_str(), (writable() ? SFM_RDWR : SFM_READ), &_info)) == 0) {
char errbuf[256];
sf_error_str (0, errbuf, sizeof (errbuf) - 1);
+#ifndef HAVE_COREAUDIO
+ /* if we have CoreAudio, we will be falling back to that if libsndfile fails,
+ so we don't want to see this message.
+ */
+
error << string_compose(_("SndFileSource: cannot open file \"%1\" for %2 (%3)"),
_path, (writable() ? "read+write" : "reading"), errbuf) << endmsg;
+#endif
return -1;
}
if (_channel >= _info.channels) {
+#ifndef HAVE_COREAUDIO
error << string_compose(_("SndFileSource: file only contains %1 channels; %2 is invalid as a channel number"), _info.channels, _channel) << endmsg;
+#endif
sf_close (sf);
sf = 0;
return -1;
@@ -255,7 +245,7 @@ SndFileSource::open ()
set_timeline_position (get_timecode_info (sf, _broadcast_info, timecode_info_exists));
- if (!timecode_info_exists) {
+ if (_length != 0 && !timecode_info_exists) {
delete _broadcast_info;
_broadcast_info = 0;
_flags = Flag (_flags & ~Broadcast);
@@ -327,6 +317,11 @@ SndFileSource::read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const
file_cnt = cnt;
}
+ if (file_cnt != cnt) {
+ nframes_t delta = cnt - file_cnt;
+ memset (dst+file_cnt, 0, sizeof (Sample) * delta);
+ }
+
if (file_cnt) {
if (sf_seek (sf, (sf_count_t) start, SEEK_SET|SFM_READ) != (sf_count_t) start) {
@@ -343,11 +338,6 @@ SndFileSource::read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const
}
}
- if (file_cnt != cnt) {
- nframes_t delta = cnt - file_cnt;
- memset (dst+file_cnt, 0, sizeof (Sample) * delta);
- }
-
real_cnt = cnt * _info.channels;
Sample* interleave_buf = get_interleave_buffer (real_cnt);
@@ -907,20 +897,3 @@ SndFileSource::one_of_several_channels () const
return _info.channels > 1;
}
-Sample*
-SndFileSource::get_interleave_buffer (nframes_t size)
-{
- SizedSampleBuffer* ssb;
-
- if ((ssb = thread_interleave_buffer.get()) == 0) {
- ssb = new SizedSampleBuffer (size);
- thread_interleave_buffer.set (ssb);
- }
-
- if (ssb->size < size) {
- ssb = new SizedSampleBuffer (size);
- thread_interleave_buffer.set (ssb);
- }
-
- return ssb->buf;
-}
diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc
index 804d4a4d47..5338997659 100644
--- a/libs/ardour/source_factory.cc
+++ b/libs/ardour/source_factory.cc
@@ -21,6 +21,7 @@
#include <pbd/error.h>
#include <pbd/convert.h>
#include <pbd/pthread_utils.h>
+#include <pbd/stacktrace.h>
#include <ardour/source_factory.h>
#include <ardour/sndfilesource.h>
@@ -28,10 +29,15 @@
#include <ardour/configuration.h>
#include <ardour/smf_source.h>
-#ifdef HAVE_COREAUDIO
+#ifdef HAVE_COREAUDIO
+#define USE_COREAUDIO_FOR_FILES
+#endif
+
+#ifdef USE_COREAUDIO_FOR_FILES
#include <ardour/coreaudiosource.h>
#endif
+
#include "i18n.h"
using namespace ARDOUR;
@@ -68,6 +74,7 @@ peak_thread_work ()
if (!as) {
continue;
}
+
as->setup_peakfile ();
}
}
@@ -128,48 +135,36 @@ SourceFactory::create (Session& s, const XMLNode& node, bool defer_peaks)
if (type == DataType::AUDIO) {
-#ifdef HAVE_COREAUDIO
-
try {
- boost::shared_ptr<Source> ret (new CoreAudioSource (s, node));
-
+
+ boost::shared_ptr<Source> ret (new SndFileSource (s, node));
if (setup_peakfile (ret, defer_peaks)) {
return boost::shared_ptr<Source>();
}
-
ret->check_for_analysis_data_on_disk ();
SourceCreated (ret);
return ret;
}
-
-
+
catch (failed_constructor& err) {
+#ifdef USE_COREAUDIO_FOR_FILES
+
/* this is allowed to throw */
-
- boost::shared_ptr<Source> ret (new SndFileSource (s, node));
-
+
+ boost::shared_ptr<Source> ret (new CoreAudioSource (s, node));
+
if (setup_peakfile (ret, defer_peaks)) {
return boost::shared_ptr<Source>();
}
-
+
ret->check_for_analysis_data_on_disk ();
SourceCreated (ret);
return ret;
- }
#else
- /* this is allowed to throw */
-
- boost::shared_ptr<Source> ret (new SndFileSource (s, node));
-
- if (setup_peakfile (ret, defer_peaks)) {
- return boost::shared_ptr<Source>();
- }
-
- ret->check_for_analysis_data_on_disk ();
- SourceCreated (ret);
- return ret;
+ throw; // rethrow
#endif
+ }
} else if (type == DataType::MIDI) {
boost::shared_ptr<Source> ret (new SMFSource (s, node));
@@ -185,59 +180,57 @@ boost::shared_ptr<Source>
SourceFactory::createReadable (DataType type, Session& s, string path, int chn, AudioFileSource::Flag flags, bool announce, bool defer_peaks)
{
if (type == DataType::AUDIO) {
-
-#ifdef HAVE_COREAUDIO
- try {
- boost::shared_ptr<Source> ret (new CoreAudioSource (s, path, chn, flags));
-
- if (setup_peakfile (ret, defer_peaks)) {
- return boost::shared_ptr<Source>();
- }
- ret->check_for_analysis_data_on_disk ();
- if (announce) {
- SourceCreated (ret);
- }
- return ret;
- }
-
- catch (failed_constructor& err) {
- boost::shared_ptr<Source> ret (new SndFileSource (s, path, chn, flags));
- if (setup_peakfile (ret, defer_peaks)) {
- return boost::shared_ptr<Source>();
+ if (!(flags & Destructive)) {
+
+ try {
+
+ boost::shared_ptr<Source> ret (new SndFileSource (s, path, chn, flags));
+
+ if (setup_peakfile (ret, defer_peaks)) {
+ return boost::shared_ptr<Source>();
+ }
+
+ ret->check_for_analysis_data_on_disk ();
+ if (announce) {
+ SourceCreated (ret);
+ }
+ return ret;
}
- ret->check_for_analysis_data_on_disk ();
- if (announce) {
- SourceCreated (ret);
- }
- return ret;
- }
+
+ catch (failed_constructor& err) {
+#ifdef USE_COREAUDIO_FOR_FILES
+
+ boost::shared_ptr<Source> ret (new CoreAudioSource (s, path, chn, flags));
+ if (setup_peakfile (ret, defer_peaks)) {
+ return boost::shared_ptr<Source>();
+ }
+ ret->check_for_analysis_data_on_disk ();
+ if (announce) {
+ SourceCreated (ret);
+ }
+ return ret;
+
#else
- boost::shared_ptr<Source> ret (new SndFileSource (s, path, chn, flags));
-
- if (setup_peakfile (ret, defer_peaks)) {
- return boost::shared_ptr<Source>();
- }
+ throw; // rethrow
+#endif
+ }
- ret->check_for_analysis_data_on_disk ();
- if (announce) {
- SourceCreated (ret);
+ } else {
+ // eh?
}
-
- return ret;
-#endif
-
+
} else if (type == DataType::MIDI) {
-
+
// FIXME: flags?
boost::shared_ptr<Source> ret (new SMFSource (s, path, SMFSource::Flag(0)));
-
- ret->check_for_analysis_data_on_disk ();
+
if (announce) {
SourceCreated (ret);
}
return ret;
+
}
return boost::shared_ptr<Source>();
diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc
index bcbb01d9c9..ab7b7c096e 100644
--- a/libs/ardour/tempo.cc
+++ b/libs/ardour/tempo.cc
@@ -1178,11 +1178,12 @@ TempoMap::round_to_type (nframes_t frame, int dir, BBTPointType type)
break;
}
-
+
+ /*
cerr << "for " << frame << " round to " << bbt << " using "
<< metric.start()
<< endl;
-
+ */
return metric.frame() + count_frames_between (metric.start(), bbt);
}