Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <fstream>
#include <cstdio>
#include <unistd.h>
#include <cmath>
#include <cstdlib>
#include <ctime>
+#include "pbd/gstdio_compat.h"
#include "pbd/error.h"
#include "pbd/xml++.h"
#include "pbd/memento_command.h"
#include "ardour/types.h"
#include "ardour/utils.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
#include <locale.h>
using namespace std;
need_write_sources = true;
}
- if (input_change_pending.type == IOChange::ConfigurationChanged) {
+ if (input_change_pending.type & IOChange::ConfigurationChanged) {
RCUWriter<ChannelList> writer (channels);
boost::shared_ptr<ChannelList> c = writer.get_copy();
/* now refill channel buffers */
if (speed() != 1.0f || speed() != -1.0f) {
- seek ((framepos_t) (location * (double) speed()));
+ seek ((framepos_t) (location * (double) speed()), true);
} else {
- seek (location);
+ seek (location, true);
}
}
boost::shared_ptr<Region> rp;
{
- const RegionList& rl (_playlist->region_list().rlist());
+ const RegionList& rl (_playlist->region_list_property().rlist());
if (rl.size() > 0) {
assert((rl.size() == 1));
rp = rl.front();
throw failed_constructor();
}
- /* be sure to stretch the region out to the maximum length */
+ /* be sure to stretch the region out to the maximum length (non-musical)*/
- region->set_length (max_framepos - region->position());
+ region->set_length (max_framepos - region->position(), 0);
uint32_t n;
ChannelList::iterator chan;
Sample *buf = bufs.get_audio (n).data(rec_offset);
memcpy (chaninfo->current_capture_buffer, buf, sizeof (Sample) * rec_nframes);
-
+
} else {
framecnt_t total = chaninfo->capture_vector.len[0] + chaninfo->capture_vector.len[1];
}
if ((_track->monitoring_state () & MonitoringDisk) || collect_playback) {
-
+
/* we're doing playback */
framecnt_t necessary_samples;
/* no varispeed playback if we're recording, because the output .... TBD */
- if (rec_nframes == 0 && _actual_speed != 1.0f) {
+ if (rec_nframes == 0 && _actual_speed != 1.0) {
necessary_samples = (framecnt_t) ceil ((nframes * fabs (_actual_speed))) + 2;
} else {
necessary_samples = nframes;
memcpy ((char *) chaninfo->playback_wrap_buffer,
chaninfo->playback_vector.buf[0],
chaninfo->playback_vector.len[0] * sizeof (Sample));
-
+
/* Copy buf[1] from playback_buf */
memcpy (chaninfo->playback_wrap_buffer + chaninfo->playback_vector.len[0],
chaninfo->playback_vector.buf[1],
int channel = 0;
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan, ++channel) {
ChannelInfo* chaninfo (*chan);
-
+
playback_distance = interpolation.interpolate (
channel, nframes, chaninfo->current_playback_buffer, chaninfo->speed_buffer);
-
+
chaninfo->current_playback_buffer = chaninfo->speed_buffer;
}
-
+
} else {
playback_distance = nframes;
}
if (need_disk_signal) {
/* copy data over to buffer set */
-
+
size_t n_buffers = bufs.count().n_audio();
size_t n_chans = c->size();
gain_t scaling = 1.0f;
-
+
if (n_chans > n_buffers) {
scaling = ((float) n_buffers)/n_chans;
}
for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
-
+
AudioBuffer& buf (bufs.get_audio (n%n_buffers));
ChannelInfo* chaninfo (*chan);
-
+
if (n < n_chans) {
if (scaling != 1.0f) {
buf.read_from_with_gain (chaninfo->current_playback_buffer, nframes, scaling);
ChanCount cnt (DataType::AUDIO, n_chans);
cnt.set (DataType::MIDI, bufs.count().n_midi());
bufs.set_count (cnt);
-
+
/* extra buffers will already be silent, so leave them alone */
}
if (adjust_capture_position != 0) {
capture_captured += adjust_capture_position;
+ DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 now captured %2 (by %3)\n", name(), capture_captured, adjust_capture_position));
adjust_capture_position = 0;
}
boost::shared_ptr<ChannelList> c = channels.reader();
for (chan = c->begin(); chan != c->end(); ++chan) {
- (*chan)->playback_buf->increment_read_ptr (llabs(distance));
+ (*chan)->playback_buf->increment_read_ptr (::llabs(distance));
}
if (first_recordable_frame < max_framepos) {
/* do not read from disk while session is marked as Loading, to avoid
useless redundant I/O.
*/
-
+
if (_session.state_of_the_state() & Session::Loading) {
return 0;
}
-
+
if (c->empty()) {
return 0;
}
/* now back to samples */
framecnt_t samples_to_read = byte_size_for_read / (bits_per_sample / 8);
-
+
//cerr << name() << " will read " << byte_size_for_read << " out of total bytes " << total_bytes << " in buffer of "
// << c->front()->playback_buf->bufsize() * bits_per_sample / 8 << " bps = " << bits_per_sample << endl;
// cerr << name () << " read samples = " << samples_to_read << " out of total space " << total_space << " in buffer of " << c->front()->playback_buf->bufsize() << " samples\n";
// uint64_t before = g_get_monotonic_time ();
// uint64_t elapsed;
-
+
for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) {
ChannelInfo* chan (*i);
// elapsed = g_get_monotonic_time () - before;
// cerr << "\tbandwidth = " << (byte_size_for_read / 1048576.0) / (elapsed/1000000.0) << "MB/sec\n";
-
+
file_frame = file_frame_tmp;
assert (file_frame >= 0);
ret = ((total_space - samples_to_read) > disk_read_chunk_frames);
-
+
c->front()->playback_buf->get_write_vector (&vector);
-
+
out:
return ret;
}
error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
return -1;
}
-
+
(*chan)->capture_buf->increment_read_ptr (to_write);
(*chan)->curr_capture_cnt += to_write;
if (Config->get_auto_analyse_audio()) {
Analyser::queue_source_for_analysis (s, true);
}
+
+ DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("newly captured source %1 length %2\n", s->path(), s->length (0)));
}
}
}
_last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
-
+
_playlist->clear_changes ();
_playlist->set_capture_insertion_in_progress (true);
_playlist->freeze ();
RegionFactory::region_name (region_name, whole_file_region_name, false);
- DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
- _name, (*ci)->start, (*ci)->frames, region_name));
+ DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture bufpos %5 start @ %2 length %3 add new region %4\n",
+ _name, (*ci)->start, (*ci)->frames, region_name, buffer_position));
try {
// all we need to do is finish this capture, with modified capture length
boost::shared_ptr<ChannelList> c = channels.reader();
- // adjust the capture length knowing that the data will be recorded to disk
- // only necessary after the first loop where we're recording
- if (capture_info.size() == 0) {
- capture_captured += _capture_offset;
-
- if (_alignment_style == ExistingMaterial) {
- capture_captured += _session.worst_output_latency();
- } else {
- capture_captured += _roll_delay;
- }
- }
-
finish_capture (c);
// the next region will start recording via the normal mechanism
*/
DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("Finish capture, add new CI, %1 + %2\n", ci->start, ci->frames));
-
+
capture_info.push_back (ci);
capture_captured = 0;
if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_audio() == 0) {
return;
}
-
- /* can't rec-safe in destructive mode if transport is before start ????
+
+ /* can't rec-safe in destructive mode if transport is before start ????
REQUIRES REVIEW */
-
+
if (destructive() && yn && _session.transport_frame() < _session.current_start_frame()) {
return;
}
-
+
/* yes, i know that this not proof against race conditions, but its
good enough. i think.
*/
-
+
if (record_safe () != yn) {
if (yn) {
engage_record_safe ();
} else {
disengage_record_safe ();
}
-
+
RecordSafeChanged (); /* EMIT SIGNAL */
}
}
{
XMLNode& node (Diskstream::get_state());
char buf[64] = "";
- LocaleGuard lg (X_("C"));
+ LocaleGuard lg;
boost::shared_ptr<ChannelList> c = channels.reader();
snprintf (buf, sizeof(buf), "%u", (unsigned int) c->size());
int
AudioDiskstream::set_state (const XMLNode& node, int version)
{
- const XMLProperty* prop;
+ XMLProperty const * prop;
XMLNodeList nlist = node.children();
XMLNodeIterator niter;
uint32_t nchans = 1;
XMLNode* capture_pending_node = 0;
- LocaleGuard lg (X_("C"));
+ LocaleGuard lg;
/* prevent write sources from being created */
when slaving to MTC, Timecode etc.
*/
- double const sp = max (fabsf (_actual_speed), 1.2f);
+ double const sp = max (fabs (_actual_speed), 1.2);
framecnt_t required_wrap_size = (framecnt_t) ceil (_session.get_block_size() * sp) + 2;
if (required_wrap_size > wrap_buffer_size) {
boost::shared_ptr<ChannelList> c = channels.reader();
if (c->empty ()) {
- return 0;
+ return 1.0;
}
return (float) ((double) c->front()->playback_buf->read_space()/
- (double) c->front()->playback_buf->bufsize());
+ (double) c->front()->playback_buf->bufsize());
}
float
boost::shared_ptr<ChannelList> c = channels.reader();
if (c->empty ()) {
- return 0;
+ return 1.0;
}
return (float) ((double) c->front()->capture_buf->write_space()/
int
AudioDiskstream::use_pending_capture_data (XMLNode& node)
{
- const XMLProperty* prop;
+ XMLProperty const * prop;
XMLNodeList nlist = node.children();
XMLNodeIterator niter;
boost::shared_ptr<AudioFileSource> fs;
}
// This protects sessions from errant CapturingSources in stored sessions
- struct stat sbuf;
- if (stat (prop->value().c_str(), &sbuf)) {
+ GStatBuf sbuf;
+ if (g_stat (prop->value().c_str(), &sbuf)) {
continue;
}
boost::shared_ptr<AudioRegion> wf_region;
boost::shared_ptr<AudioRegion> region;
-
+
/* First create the whole file region */
PropertyList plist;
-
+
plist.add (Properties::start, 0);
plist.add (Properties::length, first_fs->length (first_fs->timeline_position()));
plist.add (Properties::name, region_name_from_path (first_fs->name(), true));
* the playlist */
region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, plist));
-
+
_playlist->add_region (region, position);
}
if (Profile->get_trx()) {
return false;
}
-
+
if (!_playlist) {
requires_bounce = false;
return false;
boost::shared_ptr<Region> first;
{
- const RegionList& rl (_playlist->region_list().rlist());
+ const RegionList& rl (_playlist->region_list_property().rlist());
assert((rl.size() == 1));
first = rl.front();
continue to exist. If we do not do this, then the
Session retains a reference to it, it is not
deleted, and later attempts to create a new source
- file will use wierd naming because it already
+ file will use wierd naming because it already
exists.
XXX longer term TO-DO: do not add to session source