4 * Copyright (C) 2007 Krzysztof Foltman
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
26 /// decrease by N if >= N (useful for circular buffers)
27 template<int N
> inline int wrap_around(int a
) {
28 return (a
>= N
) ? a
- N
: a
;
31 // provide fast specializations for powers of 2
32 template<> inline int wrap_around
<2>(int a
) { return a
& 1; }
33 template<> inline int wrap_around
<4>(int a
) { return a
& 3; }
34 template<> inline int wrap_around
<8>(int a
) { return a
& 7; }
35 template<> inline int wrap_around
<16>(int a
) { return a
& 15; }
36 template<> inline int wrap_around
<32>(int a
) { return a
& 31; }
37 template<> inline int wrap_around
<64>(int a
) { return a
& 63; }
38 template<> inline int wrap_around
<128>(int a
) { return a
& 127; }
39 template<> inline int wrap_around
<256>(int a
) { return a
& 255; }
40 template<> inline int wrap_around
<512>(int a
) { return a
& 511; }
41 template<> inline int wrap_around
<1024>(int a
) { return a
& 1023; }
42 template<> inline int wrap_around
<2048>(int a
) { return a
& 2047; }
43 template<> inline int wrap_around
<4096>(int a
) { return a
& 4095; }
44 template<> inline int wrap_around
<8192>(int a
) { return a
& 8191; }
45 template<> inline int wrap_around
<16384>(int a
) { return a
& 16383; }
46 template<> inline int wrap_around
<32768>(int a
) { return a
& 32767; }
47 template<> inline int wrap_around
<65536>(int a
) { return a
& 65535; }
49 template<class Buf
, class T
>
50 void fill(Buf
&buf
, T value
) {
52 int size
= buf
.size();
53 for (int i
=0; i
<size
; i
++)
58 void fill(T
*data
, int size
, T value
) {
59 for (int i
=0; i
<size
; i
++)
63 template<class T
, class U
>
64 void copy(T
*dest
, U
*src
, int size
, T scale
= 1, T add
= 0) {
65 for (int i
=0; i
<size
; i
++)
66 *dest
++ = (*src
++) * scale
+ add
;
70 struct sample_traits
{
78 struct sample_traits
<stereo_sample
<T
> > {
85 template<int N
, class T
= float>
86 class fixed_size_buffer
{
89 enum { buffer_size
= N
};
90 inline int size() { return N
; }
93 template<int N
, class T
= float>
94 class mem_fixed_size_buffer
: public fixed_size_buffer
<N
, T
> {
97 mem_fixed_size_buffer(T ubuf
[N
]) { buf
= ubuf
; }
98 void set_data(T buf
[N
]) { this->buf
= buf
; }
99 inline T
* data() { return buf
; }
100 inline const T
* data() const { return buf
; }
101 inline T
& operator[](int pos
) { return buf
[pos
]; }
102 inline const T
& operator[](int pos
) const { return buf
[pos
]; }
105 template<int N
, class T
= float>
106 class auto_buffer
: public fixed_size_buffer
<N
, T
> {
109 T
* data() const { return buf
; }
110 inline T
& operator[](int pos
) { return buf
[pos
]; }
111 inline const T
& operator[](int pos
) const { return buf
[pos
]; }
114 template<class T
= float>
115 class dynamic_buffer
{
120 dynamic_buffer() { owns
= false; }
121 dynamic_buffer(T
*_buf
, int _buf_size
, bool _own
)
122 : buf(_buf
), buf_size(_buf_size
), owns(_own
) {
124 dynamic_buffer(int _size
) {
129 inline T
* data() { return buf
; }
130 inline const T
* data() const { return buf
; }
131 inline int size() { return buf_size
; }
132 void resize(int new_size
, bool fill_with_zeros
= false) {
133 T
*new_buf
= new T
[new_size
];
134 memcpy(new_buf
, buf
, std::min(buf_size
, new_size
));
135 if (fill_with_zeros
&& buf_size
< new_size
)
136 dsp::zero(new_buf
+ buf_size
, new_size
- buf_size
);
143 inline T
& operator[](int pos
) { return buf
[pos
]; }
144 inline const T
& operator[](int pos
) const { return buf
[pos
]; }
151 template<class T
, class U
>
152 void copy_buf(T
&dest_buf
, const U
&src_buf
, T scale
= 1, T add
= 0) {
153 typedef typename
T::data_type data_type
;
154 data_type
*dest
= dest_buf
.data();
155 const data_type
*src
= src_buf
.data();
156 int size
= src
.size();
157 for (int i
=0; i
<size
; i
++)
158 *dest
++ = (*src
++) * scale
+ add
;
162 struct buffer_traits
{
165 /// this class template defines some basic position operations for fixed_size_buffers
166 template<int N
, class T
>
167 struct buffer_traits
<fixed_size_buffer
<N
, T
> > {
168 int inc_wrap(int pos
) const {
169 return wrap_around
<T::size
>(pos
+1);
172 int pos_diff(int pos1
, int pos2
) const {
173 int pos
= pos1
- pos2
;
174 if (pos
< 0) pos
+= T::size
;
179 /// this is useless for now (and untested too)
181 class circular_buffer
: public B
{
182 typedef typename
B::data_type data_type
;
183 typedef class buffer_traits
<B
> traits
;
193 inline void put(data_type data
) {
195 wpos
= traits::inc_wrap(wpos
);
197 inline bool empty() {
201 return rpos
== traits::inc_wrap(wpos
);
203 inline const data_type
& get() {
205 rpos
= traits::inc_wrap(rpos
);
206 return buffer
[oldrpos
];
208 inline int get_rbytes() {
209 return traits::pos_diff(wpos
, rpos
);
211 inline int get_wbytes() {
212 if (full()) return 0;
213 return traits::pos_diff(rpos
, wpos
);
217 /// this is useless for now
218 template<int N
, class T
= float>
219 class mono_auto_buffer
: public auto_buffer
<N
, T
> {
222 /// this is useless for now
223 template<int N
, class T
= float>
224 class stereo_auto_buffer
: public auto_buffer
<N
, stereo_sample
<T
> > {