Reduce overhead of multi-type-ness (last Summer's SoC):
[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
27 /** Buffer containing 32-bit floating point (audio) data. */
28 class AudioBuffer : public Buffer
29 {
30 public:
31         AudioBuffer(size_t capacity);
32         
33         ~AudioBuffer();
34
35         void silence(nframes_t len, nframes_t offset=0)
36         {
37                 if (!_silent) {
38                         assert(_capacity > 0);
39                         assert(offset + len <= _capacity);
40                         memset(_data + offset, 0, sizeof (Sample) * len);
41                         if (offset == 0 && len == _capacity) {
42                                 _silent = true;
43                         }
44                 }
45         }
46         
47         /** Read @a len frames FROM THE START OF @a src into self at @a offset */
48         void read_from(const Buffer& src, nframes_t len, nframes_t offset)
49         {
50                 assert(_capacity > 0);
51                 assert(src.type() == DataType::AUDIO);
52                 assert(offset + len <= _capacity);
53                 memcpy(_data + offset, ((AudioBuffer&)src).data(), sizeof(Sample) * len);
54                 _silent = src.silent();
55         }
56         
57         /** Accumulate (add)@a len frames FROM THE START OF @a src into self at @a offset */
58         void accumulate_from(const AudioBuffer& src, nframes_t len, nframes_t offset)
59         {
60                 assert(_capacity > 0);
61                 assert(offset + len <= _capacity);
62
63                 Sample*       const dst_raw = _data + offset;
64                 const Sample* const src_raw = src.data();
65
66                 for (nframes_t n = 0; n < len; ++n) {
67                         dst_raw[n] += src_raw[n];
68                 }
69
70                 _silent = (src.silent() && _silent);
71         }
72         
73         /** Accumulate (add) @a len frames FROM THE START OF @a src into self at @a offset
74          * scaling by @a gain_coeff */
75         void accumulate_with_gain_from(const AudioBuffer& src, nframes_t len, nframes_t offset, gain_t gain_coeff)
76         {
77                 assert(_capacity > 0);
78                 assert(offset + len <= _capacity);
79
80                 Sample*       const dst_raw = _data + offset;
81                 const Sample* const src_raw = src.data();
82
83                 mix_buffers_with_gain (dst_raw, src_raw, len, gain_coeff);
84
85                 _silent = ( (src.silent() && _silent) || (_silent && gain_coeff == 0) );
86         }
87         
88         void apply_gain(gain_t gain, nframes_t len, nframes_t offset=0) {
89                 apply_gain_to_buffer (_data + offset, len, gain);
90         }
91
92         /** Set the data contained by this buffer manually (for setting directly to jack buffer).
93          * 
94          * Constructor MUST have been passed capacity=0 or this will die (to prevent mem leaks).
95          */
96         void set_data(Sample* data, size_t size)
97         {
98                 assert(!_owns_data); // prevent leaks
99                 _capacity = size;
100                 _size = size;
101                 _data = data;
102                 _silent = false;
103         }
104
105         const Sample* data () const { return _data; }
106         Sample* data () { return _data; }
107
108         const Sample* data(nframes_t nframes, nframes_t offset) const
109                 { assert(offset + nframes <= _capacity); return _data + offset; }
110
111         Sample* data (nframes_t nframes, nframes_t offset)
112                 { assert(offset + nframes <= _capacity); return _data + offset; }
113
114 private:
115         bool    _owns_data;
116         Sample* _data; ///< Actual buffer contents
117 };
118
119
120 } // namespace ARDOUR
121
122 #endif // __ardour_audio_audio_buffer_h__