1 /*
2  * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
3  *           (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
4  *
5  * This file is part of lsp-plugins
6  * Created on: 21 авг. 2018 г.
7  *
8  * lsp-plugins is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * any later version.
12  *
13  * lsp-plugins is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef TEST_FLOATBUFFER_H_
23 #define TEST_FLOATBUFFER_H_
24 
25 #include <common/types.h>
26 #include <test/helpers.h>
27 
28 namespace test
29 {
30     class FloatBuffer
31     {
32         private:
33             float      *pBuffer;
34             uint8_t    *pData;
35             size_t      nLength;
36             size_t      nAlign;
37             bool        bAligned;
38             mutable ssize_t  nLastDiff;
39 
40         private:
41             void allocate(size_t samples, size_t align, bool aligned);
42 
43         public:
44             explicit FloatBuffer(size_t samples, size_t align = DEFAULT_ALIGN, bool aligned = true);
45             explicit FloatBuffer(const FloatBuffer &src);
46             ~FloatBuffer();
47 
48         public:
randomize_positive()49             inline void randomize_positive()            { test::randomize_positive(pBuffer, nLength); };
randomize_negative()50             inline void randomize_negative()            { test::randomize_negative(pBuffer, nLength); };
randomize_sign()51             inline void randomize_sign()                { test::randomize_sign(pBuffer, nLength); };
randomize_0to1()52             inline void randomize_0to1()                { test::randomize_0to1(pBuffer, nLength); };
randomize(float min,float max)53             inline void randomize(float min, float max) { test::randomize(pBuffer, nLength, min, max); }
randomize()54             void randomize()                            { test::randomize_positive(pBuffer, nLength); };
55             void fill_zero();
56             void fill(float v);
57             void copy(const FloatBuffer &buf);
58             void copy(const float *buf, size_t count);
59             void replace(const float *buf, size_t count);
60             void vfill(size_t off, size_t n, ...);
61 
62             bool validate() const;
valid()63             inline bool valid() const { return validate(); };
corrupted()64             inline bool corrupted() const { return !validate(); };
65             bool equals_relative(const FloatBuffer &src, float tolerance = 1e-5f) const;
66             bool equals_absolute(const FloatBuffer &src, float tolerance = 1e-5f) const;
67             bool equals_adaptive(const FloatBuffer &src, float tolerance = 1e-5f) const;
68             void dump(const char *text) const;
69             void dump(const char *text, size_t from, size_t count) const;
70             void dump_hex(const char *text) const;
71             void dump_hex(const char *text, size_t from, size_t count) const;
aligned()72             inline bool aligned() const { return bAligned; }
size()73             inline size_t size() const { return nLength; }
last_diff()74             inline ssize_t last_diff() const { return nLastDiff; }
get_diff()75             inline float get_diff() const { return (nLastDiff >= 0) ? pBuffer[nLastDiff] : 0.0f; }
76 
77         public:
78             inline float &operator [] (size_t index) {
79                 return pBuffer[index];
80             }
81 
82             inline float operator [] (size_t index) const {
83                 return pBuffer[index];
84             }
85 
get(size_t index)86             inline float get(size_t index) const {
87                 return pBuffer[index];
88             }
89 
90             template <typename T>
data()91                 inline T *data()
92                 {
93                     return reinterpret_cast<T *>(pBuffer);
94                 }
95 
data()96             inline float *data()
97             {
98                 return pBuffer;
99             }
100 
data(size_t offset)101             inline float *data(size_t offset)
102             {
103                 return &pBuffer[offset];
104             }
105 
106             inline operator float *()
107             {
108                 return pBuffer;
109             }
110 
111             inline operator const float *() const
112             {
113                 return pBuffer;
114             }
115 
116     };
117 }
118 
119 #endif /* TEST_FLOATBUFFER_H_ */
120