set_block_size (_session.get_block_size());
allocate_temporary_buffers ();
-
- add_channel (1);
- assert(_n_channels == ChanCount(DataType::AUDIO, 1));
}
AudioDiskstream::~AudioDiskstream ()
transvec.buf[0]->type = CaptureStart;
transvec.buf[0]->capture_val = capture_start_frame;
(*chan)->capture_transition_buf->increment_write_ptr(1);
- }
- else {
+ } else {
// bad!
fatal << X_("programming error: capture_transition_buf is full on rec start! inconceivable!")
<< endmsg;
}
int
-AudioDiskstream::process (framepos_t transport_frame, nframes_t nframes, bool can_record, bool rec_monitors_input, bool& need_butler)
+AudioDiskstream::process (framepos_t transport_frame, pframes_t nframes, bool can_record, bool rec_monitors_input, bool& need_butler)
{
uint32_t n;
boost::shared_ptr<ChannelList> c = channels.reader();
ChannelList::iterator chan;
int ret = -1;
- nframes_t rec_offset = 0;
- nframes_t rec_nframes = 0;
+ framecnt_t rec_offset = 0;
+ framecnt_t rec_nframes = 0;
bool collect_playback = false;
playback_distance = 0;
chaninfo->capture_buf->get_write_vector (&chaninfo->capture_vector);
- if (rec_nframes <= chaninfo->capture_vector.len[0]) {
+ if (rec_nframes <= (framecnt_t) chaninfo->capture_vector.len[0]) {
chaninfo->current_capture_buffer = chaninfo->capture_vector.buf[0];
AudioPort* const ap = _io->audio (n);
assert(ap);
- assert(rec_nframes <= ap->get_audio_buffer(nframes).capacity());
+ assert(rec_nframes <= (framecnt_t) ap->get_audio_buffer(nframes).capacity());
memcpy (chaninfo->current_capture_buffer, ap->get_audio_buffer (nframes).data(rec_offset), sizeof (Sample) * rec_nframes);
} else {
- nframes_t total = chaninfo->capture_vector.len[0] + chaninfo->capture_vector.len[1];
+ framecnt_t total = chaninfo->capture_vector.len[0] + chaninfo->capture_vector.len[1];
if (rec_nframes > total) {
DiskOverrun ();
assert(ap);
Sample* buf = ap->get_audio_buffer(nframes).data();
- nframes_t first = chaninfo->capture_vector.len[0];
+ framecnt_t first = chaninfo->capture_vector.len[0];
memcpy (chaninfo->capture_wrap_buffer, buf, sizeof (Sample) * first);
memcpy (chaninfo->capture_vector.buf[0], buf, sizeof (Sample) * first);
/* we're doing playback */
- nframes_t necessary_samples;
+ framecnt_t necessary_samples;
/* no varispeed playback if we're recording, because the output .... TBD */
if (rec_nframes == 0 && _actual_speed != 1.0f) {
- necessary_samples = (nframes_t) floor ((nframes * fabs (_actual_speed))) + 1;
+ necessary_samples = (framecnt_t) floor ((nframes * fabs (_actual_speed))) + 1;
} else {
necessary_samples = nframes;
}
ChannelInfo* chaninfo (*chan);
- if (necessary_samples <= chaninfo->playback_vector.len[0]) {
+ if (necessary_samples <= (framecnt_t) chaninfo->playback_vector.len[0]) {
chaninfo->current_playback_buffer = chaninfo->playback_vector.buf[0];
} else {
- nframes_t total = chaninfo->playback_vector.len[0] + chaninfo->playback_vector.len[1];
+ framecnt_t total = chaninfo->playback_vector.len[0] + chaninfo->playback_vector.len[1];
if (necessary_samples > total) {
cerr << _name << " Need " << necessary_samples << " total = " << total << endl;
}
void
-AudioDiskstream::process_varispeed_playback(nframes_t nframes, boost::shared_ptr<ChannelList> c)
+AudioDiskstream::process_varispeed_playback (pframes_t nframes, boost::shared_ptr<ChannelList> c)
{
ChannelList::iterator chan;
}
bool
-AudioDiskstream::commit (nframes_t /* nframes */)
+AudioDiskstream::commit (framecnt_t /* nframes */)
{
bool need_butler = false;
capture_captured += adjust_capture_position;
adjust_capture_position = 0;
}
-
+
+ if (c->empty()) {
+ return false;
+ }
+
if (_slaved) {
if (_io && _io->active()) {
need_butler = c->front()->playback_buf->write_space() >= c->front()->playback_buf->bufsize() / 2;
}
} else {
if (_io && _io->active()) {
- need_butler = c->front()->playback_buf->write_space() >= disk_io_chunk_frames
- || c->front()->capture_buf->read_space() >= disk_io_chunk_frames;
+ need_butler = ((framecnt_t) c->front()->playback_buf->write_space() >= disk_io_chunk_frames)
+ || ((framecnt_t) c->front()->capture_buf->read_space() >= disk_io_chunk_frames);
} else {
- need_butler = c->front()->capture_buf->read_space() >= disk_io_chunk_frames;
+ need_butler = ((framecnt_t) c->front()->capture_buf->read_space() >= disk_io_chunk_frames);
}
}
_pending_overwrite = yn;
overwrite_frame = playback_sample;
- overwrite_offset = channels.reader()->front()->playback_buf->get_read_ptr();
+
+ boost::shared_ptr<ChannelList> c = channels.reader ();
+ if (!c->empty ()) {
+ overwrite_offset = c->front()->playback_buf->get_read_ptr();
+ }
}
int
AudioDiskstream::overwrite_existing_buffers ()
{
boost::shared_ptr<ChannelList> c = channels.reader();
+ if (c->empty ()) {
+ _pending_overwrite = false;
+ return 0;
+ }
+
Sample* mixdown_buffer;
float* gain_buffer;
int ret = -1;
overwrite_queued = false;
/* assume all are the same size */
- nframes_t size = c->front()->playback_buf->bufsize();
+ framecnt_t size = c->front()->playback_buf->bufsize();
mixdown_buffer = new Sample[size];
gain_buffer = new float[size];
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan, ++n) {
start = overwrite_frame;
- nframes_t cnt = size;
+ framecnt_t cnt = size;
/* to fill the buffer without resetting the playback sample, we need to
do it one or two chunks (normally two).
*/
- nframes_t to_read = size - overwrite_offset;
+ framecnt_t to_read = size - overwrite_offset;
if (read ((*chan)->playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer, start, to_read, *chan, n, reversed)) {
error << string_compose(_("AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"),
(*chan)->playback_buf->increment_read_ptr (distance);
}
- first_recordable_frame += distance;
+ if (first_recordable_frame < max_framepos) {
+ first_recordable_frame += distance;
+ }
playback_sample += distance;
return 0;
int
AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
- framepos_t& start, nframes_t cnt,
+ framepos_t& start, framecnt_t cnt,
ChannelInfo* /*channel_info*/, int channel, bool reversed)
{
- nframes_t this_read = 0;
+ framecnt_t this_read = 0;
bool reloop = false;
framepos_t loop_end = 0;
framepos_t loop_start = 0;
- nframes_t offset = 0;
+ framecnt_t offset = 0;
Location *loc = 0;
/* XXX we don't currently play loops in reverse. not sure why */
//cerr << "start is " << start << " loopstart: " << loop_start << " loopend: " << loop_end << endl;
}
+ if (reversed) {
+ start -= cnt;
+ }
+
while (cnt) {
- if (reversed) {
- start -= cnt;
- }
-
/* take any loop into account. we can't read past the end of the loop. */
if (loc && (loop_end - start < cnt)) {
AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer)
{
int32_t ret = 0;
- nframes_t to_read;
+ framecnt_t to_read;
RingBufferNPT<Sample>::rw_vector vector;
bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
- nframes_t total_space;
- nframes_t zero_fill;
+ framecnt_t total_space;
+ framecnt_t zero_fill;
uint32_t chan_n;
ChannelList::iterator i;
boost::shared_ptr<ChannelList> c = channels.reader();
- nframes_t ts;
+ framecnt_t ts;
if (c->empty()) {
return 0;
work with.
*/
- if (_slaved && total_space < (c->front()->playback_buf->bufsize() / 2)) {
+ if (_slaved && total_space < (framecnt_t) (c->front()->playback_buf->bufsize() / 2)) {
return 0;
}
zero_fill = total_space - file_frame;
total_space = file_frame;
- file_frame = 0;
} else {
ChannelInfo* chan (*i);
Sample* buf1;
Sample* buf2;
- nframes_t len1, len2;
+ framecnt_t len1, len2;
chan->playback_buf->get_write_vector (&vector);
- if (vector.len[0] > disk_io_chunk_frames) {
+ if ((framecnt_t) vector.len[0] > disk_io_chunk_frames) {
/* we're not going to fill the first chunk, so certainly do not bother with the
other part. it won't be connected with the part we do fill, as in:
to_read = min (ts, len1);
to_read = min (to_read, disk_io_chunk_frames);
+ assert (to_read >= 0);
+
if (to_read) {
if (read (buf1, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) {
}
file_frame = file_frame_tmp;
-
+ assert (file_frame >= 0);
+
out:
return ret;
int32_t ret = 0;
RingBufferNPT<Sample>::rw_vector vector;
RingBufferNPT<CaptureTransition>::rw_vector transvec;
- nframes_t total;
+ framecnt_t total;
_write_data_count = 0;
ret = 1;
}
- to_write = min (disk_io_chunk_frames, (nframes_t) vector.len[0]);
+ to_write = min (disk_io_chunk_frames, (framecnt_t) vector.len[0]);
// check the transition buffer when recording destructive
// important that we get this after the capture buf
of vector.len[1] to be flushed to disk as well.
*/
- to_write = min ((nframes_t)(disk_io_chunk_frames - to_write), (nframes_t) vector.len[1]);
+ to_write = min ((framecnt_t)(disk_io_chunk_frames - to_write), (framecnt_t) vector.len[1]);
if ((*chan)->write_source->write (vector.buf[1], to_write) != to_write) {
error << string_compose(_("AudioDiskstream %1: cannot write to disk"), _id) << endmsg;
bool more_work = true;
int err = 0;
boost::shared_ptr<AudioRegion> region;
- nframes_t total_capture;
+ framecnt_t total_capture;
SourceList srcs;
SourceList::iterator src;
ChannelList::iterator chan;
(*chan)->write_source->mark_for_remove ();
(*chan)->write_source->drop_references ();
- _session.remove_source ((*chan)->write_source);
(*chan)->write_source.reset ();
}
}
i_am_the_modifier++;
+
+ if (_playlist->explicit_relayering()) {
+ /* We are in `explicit relayering' mode, so we must specify which layer this new region
+ should end up on. Put it at the top.
+ */
+ region->set_layer (_playlist->top_layer() + 1);
+ region->set_pending_explicit_relayer (true);
+ }
+
_playlist->add_region (region, (*ci)->start, 1, non_layered());
i_am_the_modifier--;
if ((*chan)->write_source->removable()) {
(*chan)->write_source->mark_for_remove ();
(*chan)->write_source->drop_references ();
- _session.remove_source ((*chan)->write_source);
}
(*chan)->write_source.reset ();
}
void
-AudioDiskstream::set_block_size (nframes_t /*nframes*/)
+AudioDiskstream::set_block_size (pframes_t /*nframes*/)
{
if (_session.get_block_size() > speed_buffer_size) {
speed_buffer_size = _session.get_block_size();
*/
double const sp = max (fabsf (_actual_speed), 1.2f);
- nframes_t required_wrap_size = (nframes_t) floor (_session.get_block_size() * sp) + 1;
+ framecnt_t required_wrap_size = (framecnt_t) floor (_session.get_block_size() * sp) + 1;
if (required_wrap_size > wrap_buffer_size) {
{
boost::shared_ptr<ChannelList> c = channels.reader();
+ if (c->empty ()) {
+ return 0;
+ }
+
return (float) ((double) c->front()->playback_buf->read_space()/
(double) c->front()->playback_buf->bufsize());
}
{
boost::shared_ptr<ChannelList> c = channels.reader();
+ if (c->empty ()) {
+ return 0;
+ }
+
return (float) ((double) c->front()->capture_buf->write_space()/
(double) c->front()->capture_buf->bufsize());
}
try {
fs = boost::dynamic_pointer_cast<AudioFileSource> (
SourceFactory::createWritable (DataType::AUDIO, _session,
- prop->value(), false, _session.frame_rate()));
+ prop->value(), string(), false, _session.frame_rate()));
}
catch (failed_constructor& err) {
}
}
-AudioDiskstream::ChannelInfo::ChannelInfo (nframes_t playback_bufsize, nframes_t capture_bufsize, nframes_t speed_size, nframes_t wrap_size)
+AudioDiskstream::ChannelInfo::ChannelInfo (framecnt_t playback_bufsize, framecnt_t capture_bufsize, framecnt_t speed_size, framecnt_t wrap_size)
{
peak_power = 0.0f;
source = 0;
}
void
-AudioDiskstream::ChannelInfo::resize_playback (nframes_t playback_bufsize)
+AudioDiskstream::ChannelInfo::resize_playback (framecnt_t playback_bufsize)
{
delete playback_buf;
playback_buf = new RingBufferNPT<Sample> (playback_bufsize);
}
void
-AudioDiskstream::ChannelInfo::resize_capture (nframes_t capture_bufsize)
+AudioDiskstream::ChannelInfo::resize_capture (framecnt_t capture_bufsize)
{
delete capture_buf;