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