summaryrefslogtreecommitdiff
path: root/libs/ardour/audio_port.cc
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2009-01-21 02:27:21 +0000
committerCarl Hetherington <carl@carlh.net>2009-01-21 02:27:21 +0000
commitd6637dad5a239d74038fdf9e5800e5108ba0c44f (patch)
tree8371648bdc73dc98407c6924fefa00934e344902 /libs/ardour/audio_port.cc
parent4476461443061703e9ef268ade72511dff3e3ae5 (diff)
Rework Port class hierarchy a bit. Hopefully now simpler, and should
support connection of JACK ports with internal ones. git-svn-id: svn://localhost/ardour2/branches/3.0@4417 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/audio_port.cc')
-rw-r--r--libs/ardour/audio_port.cc153
1 files changed, 77 insertions, 76 deletions
diff --git a/libs/ardour/audio_port.cc b/libs/ardour/audio_port.cc
index 7e57a734b8..55d65d850d 100644
--- a/libs/ardour/audio_port.cc
+++ b/libs/ardour/audio_port.cc
@@ -18,118 +18,86 @@
#include <cassert>
#include <ardour/audio_port.h>
-#include <ardour/jack_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 external, nframes_t capacity)
- : Port (name, flags)
- , BaseAudioPort (name, flags)
- , PortFacade (name, flags)
- , _has_been_mixed_down( false )
+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)
{
- if (!external || receives_input()) {
+ assert (name.find_first_of (':') == string::npos);
+
+ if (external ()) {
+
+ /* external ports use the external port buffer */
+ _buffer = new AudioBuffer (0);
- /* internal-only and input ports need their own buffers.
- external output ports use the external port buffer.
- */
+ } else {
+ /* internal ports need their own buffers */
_buffer = new AudioBuffer (capacity);
- _own_buffer = true;
- }
-
- if (!external) {
-
- _ext_port = 0;
- set_name (name);
-
- } else {
- /* make the JackAudioPort create its own buffer. For input,
- we will copy from it during cycle_start(). For output,
- we will set up our buffer to point to its buffer, which
- will in turn be using the JACK port buffer for data.
- */
-
- _ext_port = new JackAudioPort (name, flags, 0);
-
- //if (sends_output()) {
- // _buffer = &dynamic_cast<JackAudioPort*>(_ext_port)->get_audio_buffer( nframes, offset );
- //}
-
- Port::set_name (_ext_port->name());
}
-
- reset ();
+
}
AudioPort::~AudioPort()
{
- delete _ext_port;
- _ext_port = 0;
+ delete _buffer;
}
void
-AudioPort::reset()
-{
- BaseAudioPort::reset();
-
- if (_ext_port) {
- _ext_port->reset ();
- }
-}
-
-
-void
AudioPort::cycle_start (nframes_t nframes, nframes_t offset)
{
/* caller must hold process lock */
- if (_ext_port) {
- _ext_port->cycle_start (nframes, offset);
- }
_has_been_mixed_down = false;
+
+ if (external ()) {
+ /* external ports use JACK's memory */
+ _buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes), nframes + offset);
+ }
}
AudioBuffer &
-AudioPort::get_audio_buffer( nframes_t nframes, nframes_t offset ) {
+AudioPort::get_audio_buffer (nframes_t nframes, nframes_t offset)
+{
+ /* caller must hold process lock */
- if (_has_been_mixed_down)
+ if (_has_been_mixed_down) {
return *_buffer;
+ }
- if (_flags & IsInput) {
-
- if (_ext_port) {
- _buffer->read_from (dynamic_cast<BaseAudioPort*>(_ext_port)->get_audio_buffer (nframes, offset), nframes, offset);
+ if (receives_input ()) {
- if (!_connections.empty()) {
- (*_mixdown) (_connections, _buffer, nframes, offset, false);
- }
+ /* INPUT */
- } else {
+ /* If we're external (), we have some data in our buffer set up by JACK;
+ otherwise, we have an undefined buffer. In either case we mix down
+ our non-JACK inputs; either accumulating into the JACK data or
+ overwriting the undefined data */
+
+ mixdown (nframes, offset, !external ());
- if (_connections.empty()) {
- _buffer->silence (nframes, offset);
- } else {
- (*_mixdown) (_connections, _buffer, nframes, offset, true);
- }
- }
-
} else {
-
- // XXX if we could get the output stage to not purely mix into, but also
- // to initially overwrite the buffer, we could avoid this silence step.
- if (_ext_port) {
- _buffer = & (dynamic_cast<BaseAudioPort*>(_ext_port)->get_audio_buffer( nframes, offset ));
- }
- if (nframes)
+
+ /* OUTPUT */
+
+ if (!external ()) {
+ /* start internal output buffers with silence */
_buffer->silence (nframes, offset);
+ }
+
}
- if (nframes)
+
+ if (nframes) {
_has_been_mixed_down = true;
+ }
return *_buffer;
}
@@ -137,5 +105,38 @@ AudioPort::get_audio_buffer( nframes_t nframes, nframes_t offset ) {
void
AudioPort::cycle_end (nframes_t nframes, nframes_t offset)
{
- _has_been_mixed_down=false;
+ _has_been_mixed_down = false;
+}
+
+void
+AudioPort::mixdown (nframes_t cnt, nframes_t offset, bool first_overwrite)
+{
+ if (_connections.empty()) {
+ if (first_overwrite) {
+ _buffer->silence (cnt, offset);
+ }
+ return;
+ }
+
+ set<Port*>::const_iterator p = _connections.begin();
+
+ if (first_overwrite) {
+ _buffer->read_from (dynamic_cast<AudioPort*>(*p)->get_audio_buffer (cnt, offset), cnt, offset);
+ ++p;
+ }
+
+ for (; p != _connections.end (); ++p) {
+ _buffer->accumulate_from (dynamic_cast<AudioPort*>(*p)->get_audio_buffer (cnt, offset), cnt, offset);
+ }
+}
+
+void
+AudioPort::reset ()
+{
+ Port::reset ();
+
+ if (_buffer->capacity () != 0) {
+ _buffer->resize (_engine->frames_per_cycle ());
+ _buffer->clear ();
+ }
}