fix all manner of wrongness with port buffer offsets

git-svn-id: svn://localhost/ardour2/branches/3.0@9098 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2011-03-07 19:06:42 +00:00
parent 61cbf95f99
commit 665f3bea5a
17 changed files with 61 additions and 112 deletions

View File

@ -49,6 +49,9 @@ public:
assert(src.type() == DataType::AUDIO);
assert(len <= _capacity);
memcpy(_data + dst_offset, ((AudioBuffer&)src).data() + src_offset, sizeof(Sample) * len);
if (next_write_addr >= _data + _capacity) {
next_write_addr = _data;
}
if (dst_offset == 0 && src_offset == 0 && len == _capacity) {
_silent = src.silent();
} else {
@ -169,11 +172,12 @@ public:
void prepare () { _written = false; }
bool written() const { return _written; }
void set_marked_for_write (bool yn) { mfw = yn; }
private:
bool _owns_data;
bool _written;
Sample* _data; ///< Actual buffer contents
};

View File

@ -41,22 +41,12 @@ class AudioPort : public Port
size_t raw_buffer_size (pframes_t nframes) const;
Buffer& get_buffer (framecnt_t nframes, framecnt_t offset = 0) {
return get_audio_buffer (nframes, offset);
Buffer& get_buffer (framecnt_t nframes) {
return get_audio_buffer (nframes);
}
AudioBuffer& get_audio_buffer (framecnt_t nframes, framecnt_t offset = 0);
AudioBuffer& get_audio_buffer (framecnt_t nframes);
static framecnt_t port_offset() { return _port_offset; }
static void set_port_offset (framecnt_t off) {
_port_offset = off;
}
static void increment_port_offset (framecnt_t n) {
_port_offset += n;
}
protected:
friend class AudioEngine;
@ -64,8 +54,6 @@ class AudioPort : public Port
private:
AudioBuffer* _buffer;
static framecnt_t _port_offset;
};
} // namespace ARDOUR

View File

@ -67,7 +67,7 @@ public:
void clear();
void attach_buffers (PortSet& ports);
void get_jack_port_addresses (PortSet &, framecnt_t, framecnt_t);
void get_jack_port_addresses (PortSet &, framecnt_t);
/* the capacity here is a size_t and has a different interpretation depending
on the DataType of the buffers. for audio, its a frame count. for MIDI

View File

@ -41,16 +41,16 @@ class MidiPort : public Port {
void cycle_end (pframes_t nframes);
void cycle_split ();
void flush_buffers (pframes_t nframes, framepos_t time, framecnt_t offset = 0);
void flush_buffers (pframes_t nframes, framepos_t time);
void transport_stopped ();
size_t raw_buffer_size (pframes_t nframes) const;
Buffer& get_buffer (framecnt_t nframes, framecnt_t offset = 0) {
return get_midi_buffer (nframes, offset);
Buffer& get_buffer (framecnt_t nframes) {
return get_midi_buffer (nframes);
}
MidiBuffer& get_midi_buffer (framecnt_t nframes, framecnt_t offset = 0);
MidiBuffer& get_midi_buffer (framecnt_t nframes);
protected:
friend class AudioEngine;

View File

@ -113,10 +113,8 @@ public:
virtual void cycle_start (pframes_t) = 0;
virtual void cycle_end (pframes_t) = 0;
virtual void cycle_split () = 0;
virtual Buffer& get_buffer (framecnt_t nframes, framecnt_t offset = 0) = 0;
virtual void flush_buffers (pframes_t nframes, framepos_t /*time*/, framecnt_t offset = 0) {
assert (offset < nframes);
}
virtual Buffer& get_buffer (framecnt_t nframes) = 0;
virtual void flush_buffers (pframes_t nframes, framepos_t /*time*/) {}
virtual void transport_stopped () {}
bool physically_connected () const;
@ -125,6 +123,17 @@ public:
PBD::Signal1<void,bool> MonitorInputChanged;
static framecnt_t port_offset() { return _port_offset; }
static void set_port_offset (framecnt_t off) {
_port_offset = off;
}
static void increment_port_offset (framecnt_t n) {
_port_offset += n;
}
protected:
Port (std::string const &, DataType, Flags);
@ -133,6 +142,7 @@ protected:
static pframes_t _buffer_size;
static bool _connecting_blocked;
static framecnt_t _port_offset;
static AudioEngine* _engine; ///< the AudioEngine
@ -150,6 +160,7 @@ private:
/** ports that we are connected to, kept so that we can
reconnect to JACK when required */
std::set<std::string> _connections;
};
}

View File

@ -17,6 +17,9 @@
*/
#include <cassert>
#include "pbd/stacktrace.h"
#include "ardour/audio_port.h"
#include "ardour/audioengine.h"
#include "ardour/data_type.h"
@ -25,8 +28,6 @@
using namespace ARDOUR;
using namespace std;
framecnt_t AudioPort::_port_offset = 0;
AudioPort::AudioPort (const std::string& name, Flags flags)
: Port (name, DataType::AUDIO, flags)
, _buffer (new AudioBuffer (0))
@ -44,22 +45,7 @@ AudioPort::cycle_start (pframes_t nframes)
{
/* caller must hold process lock */
/* get_buffer() must only be run on outputs here in cycle_start().
Inputs must be done in the correct processing order, which
requires interleaving with route processing. that will
happen when Port::get_buffer() is called.
*/
if (sends_output()) {
/* Notice that cycle_start() is always run with the *entire* process cycle frame count,
so we do not bother to apply _port_offset here - we always want the address of the
entire JACK port buffer. We are not collecting data here - just noting the
address where we will write data later in the process cycle.
*/
_buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes), nframes);
_buffer->prepare ();
}
}
@ -67,7 +53,7 @@ AudioPort::cycle_start (pframes_t nframes)
void
AudioPort::cycle_end (pframes_t nframes)
{
if (sends_output() && !_buffer->written()) {
if (sends_output() && !_buffer->written()) {
_buffer->silence (nframes);
}
}
@ -78,24 +64,10 @@ AudioPort::cycle_split ()
}
AudioBuffer&
AudioPort::get_audio_buffer (framecnt_t nframes, framecnt_t offset)
AudioPort::get_audio_buffer (framecnt_t nframes)
{
/* caller must hold process lock */
if (receives_input ()) {
/* Get a pointer to the audio data @ offset + _port_offset within the JACK port buffer and store
it in our _buffer member.
Note that offset is expected to be zero in almost all cases.
*/
_buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes) + offset + _port_offset, nframes);
}
/* output ports set their _buffer data information during ::cycle_start()
*/
_buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes) + _port_offset, nframes);
return *_buffer;
}

View File

@ -113,7 +113,7 @@ BufferSet::attach_buffers (PortSet& ports)
* Does not allocate, so RT-safe.
*/
void
BufferSet::get_jack_port_addresses (PortSet& ports, framecnt_t nframes, framecnt_t offset)
BufferSet::get_jack_port_addresses (PortSet& ports, framecnt_t nframes)
{
assert (_count == ports.count ());
assert (_available == ports.count ());
@ -128,7 +128,7 @@ BufferSet::get_jack_port_addresses (PortSet& ports, framecnt_t nframes, framecnt
int i = 0;
for (PortSet::iterator p = ports.begin(*t); p != ports.end(*t); ++p) {
v[i] = &p->get_buffer (nframes, offset);
v[i] = &p->get_buffer (nframes);
++i;
}
}

View File

@ -27,6 +27,7 @@
#include "ardour/debug.h"
#include "ardour/delivery.h"
#include "ardour/audio_buffer.h"
#include "ardour/audio_port.h"
#include "ardour/amp.h"
#include "ardour/buffer_set.h"
#include "ardour/configuration.h"
@ -253,7 +254,7 @@ Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pf
processing pathway that wants to use this->output_buffers() for some reason.
*/
output_buffers().get_jack_port_addresses (ports, nframes, _output_offset);
output_buffers().get_jack_port_addresses (ports, nframes);
// this Delivery processor is not a derived type, and thus we assume
// we really can modify the buffers passed in (it is almost certainly
@ -289,7 +290,7 @@ Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pf
panner = _panshell->panner();
if (panner && !panner->bypassed()) {
// Use the panner to distribute audio to output port buffers
_panshell->run (bufs, output_buffers(), start_frame, end_frame, nframes);
@ -300,11 +301,11 @@ Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pf
// Do a 1:1 copy of data to output ports
if (bufs.count().n_audio() > 0 && ports.count().n_audio () > 0) {
_output->copy_to_outputs (bufs, DataType::AUDIO, nframes, _output_offset);
_output->copy_to_outputs (bufs, DataType::AUDIO, nframes, 0);
}
if (bufs.count().n_midi() > 0 && ports.count().n_midi () > 0) {
_output->copy_to_outputs (bufs, DataType::MIDI, nframes, _output_offset);
_output->copy_to_outputs (bufs, DataType::MIDI, nframes, 0);
}
}
@ -451,7 +452,7 @@ Delivery::flush_buffers (framecnt_t nframes, framepos_t time)
PortSet& ports (_output->ports());
for (PortSet::iterator i = ports.begin(); i != ports.end(); ++i) {
(*i).flush_buffers (nframes, time, _output_offset);
(*i).flush_buffers (nframes, time);
}
}

View File

@ -41,6 +41,7 @@ using namespace std;
#ifdef DEBUG_RT_ALLOC
static Graph* graph = 0;
extern "C" {
int alloc_allowed ()

View File

@ -1525,7 +1525,7 @@ IO::process_input (boost::shared_ptr<Processor> proc, framepos_t start_frame, fr
{
/* don't read the data into new buffers - just use the port buffers directly */
_buffers.get_jack_port_addresses (_ports, nframes, 0);
_buffers.get_jack_port_addresses (_ports, nframes);
proc->run (_buffers, start_frame, end_frame, nframes, true);
}

View File

@ -50,7 +50,7 @@ MidiPort::cycle_start (pframes_t nframes)
}
MidiBuffer &
MidiPort::get_midi_buffer (framecnt_t nframes, framecnt_t offset)
MidiPort::get_midi_buffer (framecnt_t nframes)
{
if (_has_been_mixed_down) {
return *_buffer;
@ -78,10 +78,10 @@ MidiPort::get_midi_buffer (framecnt_t nframes, framecnt_t offset)
continue;
}
if (ev.time >= offset && ev.time < (offset + nframes)) {
if (ev.time >= _port_offset && ev.time < (_port_offset + nframes)) {
_buffer->push_back (ev);
} else {
cerr << "Dropping incoming MIDI at time " << ev.time << "; offset=" << offset << " limit=" << (offset + nframes) << "\n";
cerr << "Dropping incoming MIDI at time " << ev.time << "; offset=" << _port_offset << " limit=" << (_port_offset + nframes) << "\n";
}
}
@ -114,7 +114,7 @@ MidiPort::cycle_split ()
}
void
MidiPort::flush_buffers (pframes_t nframes, framepos_t time, framecnt_t offset)
MidiPort::flush_buffers (pframes_t nframes, framepos_t time)
{
if (sends_output ()) {
@ -137,14 +137,14 @@ MidiPort::flush_buffers (pframes_t nframes, framepos_t time, framecnt_t offset)
// event times are in frames, relative to cycle start
assert (ev.time() < (nframes + offset));
assert (ev.time() < (nframes + _port_offset));
if (ev.time() >= offset) {
if (ev.time() >= _port_offset) {
if (jack_midi_event_write (jack_buffer, (jack_nframes_t) ev.time(), ev.buffer(), ev.size()) != 0) {
cerr << "write failed, drop flushed note off on the floor, time " << ev.time() << " > " << offset << endl;
cerr << "write failed, drop flushed note off on the floor, time " << ev.time() << " > " << _port_offset << endl;
}
} else {
cerr << "drop flushed event on the floor, time " << ev.time() << " < " << offset << endl;
cerr << "drop flushed event on the floor, time " << ev.time() << " < " << _port_offset << endl;
}
}
}

View File

@ -42,6 +42,7 @@ using namespace PBD;
AudioEngine* Port::_engine = 0;
pframes_t Port::_buffer_size = 0;
bool Port::_connecting_blocked = false;
framecnt_t Port::_port_offset = 0;
/** @param n Port short name */
Port::Port (std::string const & n, DataType t, Flags f)

View File

@ -418,10 +418,8 @@ Route::process_output_buffers (BufferSet& bufs,
GLOBAL DECLICK (for transport changes etc.)
----------------------------------------------------------------------------------------- */
if (declick > 0) {
Amp::declick (bufs, nframes, 1);
} else if (declick < 0) {
Amp::declick (bufs, nframes, -1);
if (declick != 0) {
Amp::declick (bufs, nframes, declick);
}
_pending_declick = 0;
@ -503,7 +501,7 @@ Route::process_output_buffers (BufferSet& bufs,
do we catch route != active somewhere higher?
*/
(*i)->run (bufs, start_frame, end_frame, nframes, *i != _processors.back());
(*i)->run (bufs, start_frame, end_frame, nframes, *i != _processors.back());
bufs.set_count ((*i)->output_streams());
}
}
@ -2695,7 +2693,7 @@ Route::nonrealtime_handle_transport_stopped (bool /*abort_ignored*/, bool did_lo
if (Config->get_plugins_stop_with_transport() && can_flush_processors) {
(*i)->flush ();
}
(*i)->transport_stopped (now);
}
}
@ -2819,6 +2817,7 @@ Route::check_initial_delay (framecnt_t nframes, framecnt_t& transport_frame)
output ports, so make a note of that for
future reference.
*/
_main_outs->increment_output_offset (_roll_delay);
transport_frame += _roll_delay;

View File

@ -3745,45 +3745,18 @@ BufferSet&
Session::get_silent_buffers (ChanCount count)
{
return ProcessThread::get_silent_buffers (count);
#if 0
assert(_silent_buffers->available() >= 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) {
_silent_buffers->get(*t, i).clear();
}
}
return *_silent_buffers;
#endif
}
BufferSet&
Session::get_scratch_buffers (ChanCount count)
{
return ProcessThread::get_scratch_buffers (count);
#if 0
if (count != ChanCount::ZERO) {
assert(_scratch_buffers->available() >= count);
_scratch_buffers->set_count(count);
} else {
_scratch_buffers->set_count (_scratch_buffers->available());
}
return *_scratch_buffers;
#endif
}
BufferSet&
Session::get_mix_buffers (ChanCount count)
{
return ProcessThread::get_mix_buffers (count);
#if 0
assert(_mix_buffers->available() >= count);
_mix_buffers->set_count(count);
return *_mix_buffers;
#endif
}
uint32_t

View File

@ -51,6 +51,7 @@ using namespace std;
/** Called by the audio engine when there is work to be done with JACK.
* @param nframes Number of frames to process.
*/
void
Session::process (pframes_t nframes)
{
@ -397,7 +398,7 @@ Session::process_with_events (pframes_t nframes)
fail_roll (nframes);
return;
}
get_track_statistics ();
nframes -= this_nframes;

View File

@ -819,7 +819,7 @@ Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool
return;
}
if (_transport_speed && (!with_loop || loop_changing)) {
if (_transport_speed) {
/* schedule a declick. we'll be called again when its done */
if (!(transport_sub_state & PendingDeclickOut)) {

View File

@ -133,8 +133,6 @@ GenericMidiControlProtocol::reload_maps ()
return;
}
cerr << "Found " << midi_maps->size() << " MIDI maps along " << spath.to_string() << endl;
for (vector<string*>::iterator i = midi_maps->begin(); i != midi_maps->end(); ++i) {
string fullpath = *(*i);