1f6c2f63bf15411c59d1cf47580850e0fdd85b9f
[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(&src != this);
47                 assert(_capacity > 0);
48                 assert(src.type() == DataType::AUDIO);
49                 assert(offset + len <= _capacity);
50                 memcpy(_data + offset, ((AudioBuffer&)src).data(), sizeof(Sample) * len);
51                 _silent = src.silent();
52         }
53         
54         /** Accumulate (add)@a len frames FROM THE START OF @a src into self at @a offset */
55         void accumulate_from(const AudioBuffer& src, nframes_t len, nframes_t offset) {
56                 assert(_capacity > 0);
57                 assert(offset + len <= _capacity);
58
59                 Sample*       const dst_raw = _data + offset;
60                 const Sample* const src_raw = src.data();
61
62                 mix_buffers_no_gain(dst_raw, src_raw, len);
63
64                 _silent = (src.silent() && _silent);
65         }
66         
67         /** Accumulate (add) @a len frames FROM THE START OF @a src into self at @a offset
68          * scaling by @a gain_coeff */
69         void accumulate_with_gain_from(const AudioBuffer& src, nframes_t len, nframes_t offset, gain_t gain_coeff) {
70                 assert(_capacity > 0);
71                 assert(offset + len <= _capacity);
72
73                 Sample*       const dst_raw = _data + offset;
74                 const Sample* const src_raw = src.data();
75
76                 mix_buffers_with_gain (dst_raw, src_raw, len, gain_coeff);
77
78                 _silent = ( (src.silent() && _silent) || (_silent && gain_coeff == 0) );
79         }
80         
81         void apply_gain(gain_t gain, nframes_t len, nframes_t offset=0) {
82                 apply_gain_to_buffer (_data + offset, len, gain);
83         }
84
85         /** Set the data contained by this buffer manually (for setting directly to jack buffer).
86          * 
87          * Constructor MUST have been passed capacity=0 or this will die (to prevent mem leaks).
88          */
89         void set_data (Sample* data, size_t size) {
90                 assert(!_owns_data); // prevent leaks
91                 _capacity = size;
92                 _size = size;
93                 _data = data;
94                 _silent = false;
95         }
96
97         /** Reallocate the buffer used internally to handle at least @nframes of data
98          * 
99          * Constructor MUST have been passed capacity!=0 or this will die (to prevent mem leaks).
100          */
101         void resize (size_t nframes);
102
103         const Sample* data () const { return _data; }
104         Sample* data () { return _data; }
105
106         const Sample* data(nframes_t nframes, nframes_t offset) const
107                 { assert(offset + nframes <= _capacity); return _data + offset; }
108
109         Sample* data (nframes_t nframes, nframes_t offset)
110                 { assert(offset + nframes <= _capacity); return _data + offset; }
111
112 private:
113         bool    _owns_data;
114         Sample* _data; ///< Actual buffer contents
115 };
116
117
118 } // namespace ARDOUR
119
120 #endif // __ardour_audio_audio_buffer_h__