Remove unused per-port buffer offset
[ardour.git] / libs / ardour / audio_port.cc
1 /*
2     Copyright (C) 2006 Paul Davis
3
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.
8
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.
13
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.
17 */
18
19 #include <cassert>
20
21 #include "pbd/malign.h"
22 #include "pbd/stacktrace.h"
23
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"
29
30 using namespace ARDOUR;
31 using namespace std;
32
33 #define port_engine AudioEngine::instance()->port_engine()
34
35 AudioPort::AudioPort (const std::string& name, PortFlags flags)
36         : Port (name, DataType::AUDIO, flags)
37         , _buffer (new AudioBuffer (0))
38 {
39         assert (name.find_first_of (':') == string::npos);
40         cache_aligned_malloc ((void**) &_data, sizeof (Sample) * 8192);
41         _src.setup (_resampler_quality);
42         _src.set_rrfilt (10);
43 }
44
45 AudioPort::~AudioPort ()
46 {
47         cache_aligned_free (_data);
48         delete _buffer;
49 }
50
51 void
52 AudioPort::cycle_start (pframes_t nframes)
53 {
54         /* caller must hold process lock */
55         Port::cycle_start (nframes);
56
57         if (sends_output()) {
58                 _buffer->prepare ();
59         } else if (!externally_connected ()) {
60                 /* ardour internal port, just silence input, don't resample */
61                 // TODO reset resampler only once
62                 _src.reset ();
63                 memset (_data, 0, _cycle_nframes * sizeof (float));
64         } else {
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;
70                 _src.process ();
71 #ifndef NDEBUG
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);
74                 }
75 #endif
76                 while (_src.out_count > 0) {
77                         *_src.out_data =  _src.out_data[-1];
78                         ++_src.out_data;
79                         --_src.out_count;
80                 }
81         }
82 }
83
84 void
85 AudioPort::cycle_end (pframes_t nframes)
86 {
87         if (sends_output() && !_buffer->written() && _port_handle) {
88                 if (!_buffer->data (0)) {
89                         get_audio_buffer (nframes);
90                 }
91                 if (_buffer->capacity() >= nframes) {
92                         _buffer->silence (nframes);
93                 }
94         }
95
96         if (sends_output() && _port_handle) {
97
98                 if (!externally_connected ()) {
99                         /* ardour internal port, data goes nowhere, skip resampling */
100                         // TODO reset resampler only once
101                         _src.reset ();
102                         return;
103                 }
104
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);
110                 _src.process ();
111 #ifndef NDEBUG
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);
114                 }
115 #endif
116                 while (_src.out_count > 0) {
117                         *_src.out_data =  _src.out_data[-1];
118                         ++_src.out_data;
119                         --_src.out_count;
120                 }
121         }
122 }
123
124 void
125 AudioPort::cycle_split ()
126 {
127 }
128
129 AudioBuffer&
130 AudioPort::get_audio_buffer (pframes_t nframes)
131 {
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);
137         } else {
138                 _buffer->set_data (&_data[_global_port_buffer_offset], nframes);
139         }
140         return *_buffer;
141 }
142
143 Sample*
144 AudioPort::engine_get_whole_audio_buffer ()
145 {
146         /* caller must hold process lock */
147         assert (_port_handle);
148         return (Sample *) port_engine.get_buffer (_port_handle, _cycle_nframes);
149 }