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.
21 #include "pbd/malign.h"
22 #include "pbd/stacktrace.h"
24 #include "ardour/audio_buffer.h"
25 #include "ardour/audioengine.h"
26 #include "ardour/audio_port.h"
27 #include "ardour/data_type.h"
28 #include "ardour/port_engine.h"
30 using namespace ARDOUR;
33 #define port_engine AudioEngine::instance()->port_engine()
35 AudioPort::AudioPort (const std::string& name, PortFlags flags)
36 : Port (name, DataType::AUDIO, flags)
37 , _buffer (new AudioBuffer (0))
39 assert (name.find_first_of (':') == string::npos);
40 cache_aligned_malloc ((void**) &_data, sizeof (Sample) * 8192);
41 _src.setup (_resampler_quality);
45 AudioPort::~AudioPort ()
47 cache_aligned_free (_data);
52 AudioPort::cycle_start (pframes_t nframes)
54 /* caller must hold process lock */
55 Port::cycle_start (nframes);
59 } else if (!externally_connected ()) {
60 /* ardour internal port, just silence input, don't resample */
61 // TODO reset resampler only once
63 memset (_data, 0, _cycle_nframes * sizeof (float));
65 _src.inp_data = (float*)port_engine.get_buffer (_port_handle, nframes);
66 _src.inp_count = nframes;
67 _src.out_count = _cycle_nframes;
68 _src.set_rratio (_cycle_nframes / (double)nframes);
69 _src.out_data = _data;
72 if (_src.inp_count != 0 || _src.out_count != 0) {
73 printf ("AudioPort::cycle_start x-flow: %d/%d\n", _src.inp_count, _src.out_count);
76 while (_src.out_count > 0) {
77 *_src.out_data = _src.out_data[-1];
85 AudioPort::cycle_end (pframes_t nframes)
87 if (sends_output() && !_buffer->written() && _port_handle) {
88 if (!_buffer->data (0)) {
89 get_audio_buffer (nframes);
91 if (_buffer->capacity() >= nframes) {
92 _buffer->silence (nframes);
96 if (sends_output() && _port_handle) {
98 if (!externally_connected ()) {
99 /* ardour internal port, data goes nowhere, skip resampling */
100 // TODO reset resampler only once
105 _src.inp_count = _cycle_nframes;
106 _src.out_count = nframes;
107 _src.set_rratio (nframes / (double)_cycle_nframes);
108 _src.inp_data = _data;
109 _src.out_data = (float*)port_engine.get_buffer (_port_handle, nframes);
112 if (_src.inp_count != 0 || _src.out_count != 0) {
113 printf ("AudioPort::cycle_end x-flow: %d/%d\n", _src.inp_count, _src.out_count);
116 while (_src.out_count > 0) {
117 *_src.out_data = _src.out_data[-1];
125 AudioPort::cycle_split ()
130 AudioPort::get_audio_buffer (pframes_t nframes)
132 /* caller must hold process lock */
133 assert (_port_handle);
134 if (!externally_connected ()) {
135 _buffer->set_data ((Sample *) port_engine.get_buffer (_port_handle, _cycle_nframes) +
136 _global_port_buffer_offset, nframes);
138 _buffer->set_data (&_data[_global_port_buffer_offset], nframes);
144 AudioPort::engine_get_whole_audio_buffer ()
146 /* caller must hold process lock */
147 assert (_port_handle);
148 return (Sample *) port_engine.get_buffer (_port_handle, _cycle_nframes);