new port design, probably about 90% done (i.e it mostly works and this commit is...
[ardour.git] / libs / ardour / ardour / audio_buffer.h
1 /*
2     Copyright (C) 2006 Paul Davis 
3     
4     This program is free software; you can redistribute it and/or modify it
5     under the terms of the GNU General Public License as published by the Free
6     Software Foundation; either version 2 of the License, or (at your option)
7     any later version.
8     
9     This program is distributed in the hope that it will be useful, but WITHOUT
10     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12     for more details.
13     
14     You should have received a copy of the GNU General Public License along
15     with this program; if not, write to the Free Software Foundation, Inc.,
16     675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #ifndef __ardour_audio_buffer_h__
20 #define __ardour_audio_buffer_h__
21
22 #include <ardour/buffer.h>
23
24 namespace ARDOUR {
25
26 class AudioBuffer : public Buffer
27 {
28 public:
29         AudioBuffer(size_t capacity);
30         
31         ~AudioBuffer();
32
33         void silence(nframes_t len, nframes_t offset = 0) {
34                 if (!_silent) {
35                         assert(_capacity > 0);
36                         assert(offset + len <= _capacity);
37                         memset(_data + offset, 0, sizeof (Sample) * len);
38                         if (offset == 0 && len == _capacity) {
39                                 _silent = true;
40                         }
41                 }
42         }
43         
44         /** Read @a len frames FROM THE START OF @a src into self at @a offset */
45         void read_from(const Buffer& src, nframes_t len, nframes_t offset) {
46                 assert(_capacity > 0);
47                 assert(src.type() == DataType::AUDIO);
48                 assert(offset + len <= _capacity);
49                 memcpy(_data + offset, ((AudioBuffer&)src).data(), sizeof(Sample) * len);
50                 _silent = src.silent();
51         }
52         
53         /** Accumulate (add)@a len frames FROM THE START OF @a src into self at @a offset */
54         void accumulate_from(const AudioBuffer& src, nframes_t len, nframes_t offset) {
55                 assert(_capacity > 0);
56                 assert(offset + len <= _capacity);
57
58                 Sample*       const dst_raw = _data + offset;
59                 const Sample* const src_raw = src.data();
60
61                 mix_buffers_no_gain(dst_raw, src_raw, len);
62
63                 _silent = (src.silent() && _silent);
64         }
65         
66         /** Accumulate (add) @a len frames FROM THE START OF @a src into self at @a offset
67          * scaling by @a gain_coeff */
68         void accumulate_with_gain_from(const AudioBuffer& src, nframes_t len, nframes_t offset, gain_t gain_coeff) {
69                 assert(_capacity > 0);
70                 assert(offset + len <= _capacity);
71
72                 Sample*       const dst_raw = _data + offset;
73                 const Sample* const src_raw = src.data();
74
75                 mix_buffers_with_gain (dst_raw, src_raw, len, gain_coeff);
76
77                 _silent = ( (src.silent() && _silent) || (_silent && gain_coeff == 0) );
78         }
79         
80         void apply_gain(gain_t gain, nframes_t len, nframes_t offset=0) {
81                 apply_gain_to_buffer (_data + offset, len, gain);
82         }
83
84         /** Set the data contained by this buffer manually (for setting directly to jack buffer).
85          * 
86          * Constructor MUST have been passed capacity=0 or this will die (to prevent mem leaks).
87          */
88         void set_data (Sample* data, size_t size) {
89                 assert(!_owns_data); // prevent leaks
90                 _capacity = size;
91                 _size = size;
92                 _data = data;
93                 _silent = false;
94         }
95
96         /** Reallocate the buffer used internally to handle at least @nframes of data
97          * 
98          * Constructor MUST have been passed capacity!=0 or this will die (to prevent mem leaks).
99          */
100         void resize (size_t nframes);
101
102         const Sample* data () const { return _data; }
103         Sample* data () { return _data; }
104
105         const Sample* data(nframes_t nframes, nframes_t offset) const
106                 { assert(offset + nframes <= _capacity); return _data + offset; }
107
108         Sample* data (nframes_t nframes, nframes_t offset)
109                 { assert(offset + nframes <= _capacity); return _data + offset; }
110
111 private:
112         bool    _owns_data;
113         Sample* _data; ///< Actual buffer contents
114 };
115
116
117 } // namespace ARDOUR
118
119 #endif // __ardour_audio_audio_buffer_h__