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:
parent
61cbf95f99
commit
665f3bea5a
@ -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
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ using namespace std;
|
||||
|
||||
#ifdef DEBUG_RT_ALLOC
|
||||
static Graph* graph = 0;
|
||||
|
||||
extern "C" {
|
||||
|
||||
int alloc_allowed ()
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user