X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Faudio_port.cc;h=a75f7d7a09163058b624bcaf6788763b687331ac;hb=535d60237486e2227d22e5febbcfbf868abb11e3;hp=0e48c2a69960200fb16f3b228f3dc63d17e7b892;hpb=70b939da4f9d4097160e32f2373a7a5ff8f4957f;p=ardour.git diff --git a/libs/ardour/audio_port.cc b/libs/ardour/audio_port.cc index 0e48c2a699..a75f7d7a09 100644 --- a/libs/ardour/audio_port.cc +++ b/libs/ardour/audio_port.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2006 Paul Davis + Copyright (C) 2006 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 @@ -17,168 +17,89 @@ */ #include -#include -#include -#include -#include +#include "ardour/audio_port.h" +#include "ardour/audioengine.h" +#include "ardour/data_type.h" +#include "ardour/audio_buffer.h" using namespace ARDOUR; using namespace std; -AudioPort::AudioPort (const std::string& name, Flags flags, bool ext, nframes_t capacity) - : Port (name, DataType::AUDIO, flags, ext) - , _has_been_mixed_down (false) - , _buffer (0) - , _internal_buffer (false) +AudioPort::AudioPort (const std::string& name, Flags flags) + : Port (name, DataType::AUDIO, flags) + , _buffer (new AudioBuffer (0)) { assert (name.find_first_of (':') == string::npos); - - if (external ()) { - - /* external ports use the external port buffer */ - _buffer = new AudioBuffer (0); - - } else { - - /* internal ports need their own buffers */ - _buffer = new AudioBuffer (capacity); - } - - check_buffer_status (); - } -AudioPort::~AudioPort() +AudioPort::~AudioPort () { delete _buffer; } void -AudioPort::cycle_start (nframes_t nframes, nframes_t offset) +AudioPort::cycle_start (nframes_t nframes) { /* caller must hold process lock */ - /* For external (JACK) ports, get_buffer() must only be run - on outputs here in cycle_start(). + /* 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 + 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 (!receives_input() && external ()) { - _buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes) + offset, nframes); - } - if (receives_input()) { - _has_been_mixed_down = false; - } else { - _buffer->silence (nframes, offset); - } -} + if (sends_output()) { -AudioBuffer & -AudioPort::get_audio_buffer (nframes_t nframes, nframes_t offset) -{ - /* caller must hold process lock */ + /* 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. + */ - if (receives_input () && !_has_been_mixed_down) { - - /* external ports use JACK's memory unless otherwise noted */ - - if (external()) { - if (!using_internal_data()) { - _buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes) + offset, nframes); - } else { - _buffer->silence (nframes, offset); - } - } - - mixdown (nframes, offset, !external ()); - } - - return *_buffer; + _buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes), nframes); + _buffer->prepare (); + } } void -AudioPort::cycle_end (nframes_t nframes, nframes_t offset) +AudioPort::cycle_end (nframes_t nframes) { - _has_been_mixed_down = false; + if (sends_output() && !_buffer->written()) { + _buffer->silence (nframes); + } } void -AudioPort::mixdown (nframes_t cnt, nframes_t offset, bool first_overwrite) +AudioPort::cycle_split () { - /* note: this is only called for input ports */ - - if (_connections.empty()) { - - /* no internal mixing to do, so for internal ports - just make sure the buffer is silent. - */ - - if (!external()) { - _buffer->silence (cnt, offset); - } - - } else { - - set::const_iterator p = _connections.begin(); - - /* mix in internally-connected ports. if this is an external port - then it may already have data present from JACK. in that case, we - do not want to overwrite that data, so we skip the initial ::read_from() - call and do everything with accumulate_from() - */ +} - if (!external()) { - _buffer->read_from (dynamic_cast(*p)->get_audio_buffer (cnt, offset), cnt, offset); - ++p; - - } +AudioBuffer& +AudioPort::get_audio_buffer (nframes_t nframes, nframes_t offset) +{ + /* caller must hold process lock */ - for (; p != _connections.end (); ++p) { - _buffer->accumulate_from (dynamic_cast(*p)->get_audio_buffer (cnt, offset), cnt, offset); + 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. - /* XXX horrible heuristic designed to check that we worked the whole buffer. - Needs fixing but its a hard problem. - */ + Note that offset is expected to be zero in almost all cases. + */ - if (cnt && offset == 0) { - _has_been_mixed_down = true; + _buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes) + offset + _port_offset, nframes); } -} -void -AudioPort::reset () -{ - Port::reset (); - - if (_buffer->capacity () != 0) { - _buffer->resize (_engine->frames_per_cycle ()); - _buffer->clear (); - } -} + /* output ports set their _buffer data information during ::cycle_start() + */ -bool -AudioPort::using_internal_data () const -{ - return _internal_buffer; + return *_buffer; } -void -AudioPort::use_internal_data () +size_t +AudioPort::raw_buffer_size(nframes_t nframes) const { - _buffer->replace_data (_buffer->capacity()); - _internal_buffer = true; + return nframes * sizeof(float); } -void -AudioPort::use_external_data () -{ - _internal_buffer = false; - _buffer->drop_data (); -}