2 Copyright (C) 2006 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <ardour/audio_port.h>
21 #include <ardour/audioengine.h>
22 #include <ardour/data_type.h>
23 #include <ardour/audio_buffer.h>
25 using namespace ARDOUR;
28 AudioPort::AudioPort (const std::string& name, Flags flags, bool ext, nframes_t capacity)
29 : Port (name, DataType::AUDIO, flags, ext)
30 , _has_been_mixed_down (false)
32 , _internal_buffer (false)
34 assert (name.find_first_of (':') == string::npos);
38 /* external ports use the external port buffer */
39 _buffer = new AudioBuffer (0);
43 /* internal ports need their own buffers */
44 _buffer = new AudioBuffer (capacity);
47 check_buffer_status ();
51 AudioPort::~AudioPort()
57 AudioPort::cycle_start (nframes_t nframes, nframes_t offset)
59 /* caller must hold process lock */
61 /* For external (JACK) ports, get_buffer() must only be run
62 on outputs here in cycle_start().
64 Inputs must be done in the correct processing order, which
65 requires interleaving with route processing. that will
66 happen when Port::get_buffer() is called.
69 if (!receives_input() && external ()) {
70 _buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes) + offset, nframes);
73 if (receives_input()) {
74 _has_been_mixed_down = false;
76 _buffer->silence (nframes, offset);
81 AudioPort::get_audio_buffer (nframes_t nframes, nframes_t offset)
83 /* caller must hold process lock */
85 if (receives_input () && !_has_been_mixed_down) {
87 /* external ports use JACK's memory unless otherwise noted */
90 if (!using_internal_data()) {
91 _buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes) + offset, nframes);
93 _buffer->silence (nframes, offset);
97 mixdown (nframes, offset, !external ());
104 AudioPort::cycle_end (nframes_t nframes, nframes_t offset)
106 _has_been_mixed_down = false;
110 AudioPort::mixdown (nframes_t cnt, nframes_t offset, bool first_overwrite)
112 /* note: this is only called for input ports */
114 if (_connections.empty()) {
116 /* no internal mixing to do, so for internal ports
117 just make sure the buffer is silent.
121 _buffer->silence (cnt, offset);
126 set<Port*>::const_iterator p = _connections.begin();
128 /* mix in internally-connected ports. if this is an external port
129 then it may already have data present from JACK. in that case, we
130 do not want to overwrite that data, so we skip the initial ::read_from()
131 call and do everything with accumulate_from()
135 _buffer->read_from (dynamic_cast<AudioPort*>(*p)->get_audio_buffer (cnt, offset), cnt, offset);
140 for (; p != _connections.end (); ++p) {
141 _buffer->accumulate_from (dynamic_cast<AudioPort*>(*p)->get_audio_buffer (cnt, offset), cnt, offset);
146 /* XXX horrible heuristic designed to check that we worked the whole buffer.
147 Needs fixing but its a hard problem.
150 if (cnt && offset == 0) {
151 _has_been_mixed_down = true;
160 if (_buffer->capacity () != 0) {
161 _buffer->resize (_engine->frames_per_cycle ());
167 AudioPort::using_internal_data () const
169 return _internal_buffer;
173 AudioPort::use_internal_data ()
175 _buffer->replace_data (_buffer->capacity());
176 _internal_buffer = true;
180 AudioPort::use_external_data ()
182 _internal_buffer = false;
183 _buffer->drop_data ();