1 /*
2  * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert
3  * Copyright (C) 2011 Pete Shorthose
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  * --------------------------------------------------------------------------
19  */
20 
21 /* ------- This is the guitarix convolution Engine  ------- */
22 
23 #pragma once
24 
25 #ifndef SRC_HEADERS_GX_CONVOLVER_H_
26 #define SRC_HEADERS_GX_CONVOLVER_H_
27 
28 #include <zita-convolver.h>
29 #include <gxwmm/gainline.h>
30 
31 #include <sndfile.hh>
32 
33 namespace gx_engine {
34 
35 /* GxConvolver */
36 
37 class Audiofile {
38 public:
39 
40     enum {
41         TYPE_OTHER,
42         TYPE_CAF,
43         TYPE_WAV,
44         TYPE_AIFF,
45         TYPE_AMB
46     };
47 
48     enum {
49         FORM_OTHER,
50         FORM_16BIT,
51         FORM_24BIT,
52         FORM_32BIT,
53         FORM_FLOAT
54     };
55 
56     enum {
57         ERR_NONE    = 0,
58         ERR_MODE    = -1,
59         ERR_TYPE    = -2,
60         ERR_FORM    = -3,
61         ERR_OPEN    = -4,
62         ERR_SEEK    = -5,
63         ERR_DATA    = -6,
64         ERR_READ    = -7,
65         ERR_WRITE   = -8
66     };
67 
68     Audiofile(void);
69     ~Audiofile(void);
70 
type(void)71     int type(void) const      { return _type; }
form(void)72     int form(void) const      { return _form; }
rate(void)73     int rate(void) const      { return _rate; }
chan(void)74     int chan(void) const      { return _chan; }
size(void)75     unsigned int size(void) const { return _size; }
76 
77     int open_read(string name);
78     int close(void);
79 
80     int seek(unsigned int posit);
81     int read(float *data, unsigned int frames);
82 
83 private:
84 
85     void reset(void);
86 
87     SNDFILE     *_sndfile;
88     int          _type;
89     int          _form;
90     int          _rate;
91     int          _chan;
92     unsigned int _size;
93 };
94 
95 bool read_audio(const std::string& filename, unsigned int *audio_size, int *audio_chan,
96 		int *audio_type, int *audio_form, int *audio_rate, float **buffer);
97 
98 class GxConvolverBase: protected Convproc {
99 protected:
100     volatile bool ready;
101     bool sync;
102     void adjust_values(unsigned int audio_size, unsigned int& count, unsigned int& offset,
103                        unsigned int& delay, unsigned int& ldelay, unsigned int& length,
104                        unsigned int& size, unsigned int& bufsize);
105     unsigned int buffersize;
106     unsigned int samplerate;
GxConvolverBase()107     GxConvolverBase(): ready(false), sync(false), buffersize(), samplerate() {}
108     ~GxConvolverBase();
109 public:
set_buffersize(unsigned int sz)110     inline void set_buffersize(unsigned int sz) { buffersize = sz; }
get_buffersize()111     inline unsigned int get_buffersize() { return buffersize; }
set_samplerate(unsigned int sr)112     inline void set_samplerate(unsigned int sr) { samplerate = sr; }
get_samplerate()113     inline unsigned int get_samplerate() { return samplerate; }
114     bool checkstate();
115     using Convproc::state;
set_not_runnable()116     inline void set_not_runnable()   { ready = false; }
is_runnable()117     inline bool is_runnable()        { return ready; }
118     bool start(int policy, int priority);
119     using Convproc::stop_process;
set_sync(bool val)120     inline void set_sync(bool val)   { sync = val; }
121 };
122 
123 class GxConvolver: public GxConvolverBase {
124 private:
125     gx_resample::StreamingResampler resamp;
126     bool read_sndfile(Audiofile& audio, int nchan, int samplerate, const float *gain,
127 		      unsigned int *delay, unsigned int offset, unsigned int length,
128 		      const Gainline& points);
129 public:
GxConvolver()130     GxConvolver(): GxConvolverBase(), resamp() {}
131     bool configure(
132         string fname, float gain, float lgain,
133         unsigned int delay, unsigned int ldelay, unsigned int offset,
134         unsigned int length, unsigned int size, unsigned int bufsize,
135         const Gainline& gainline);
136     bool compute(int count, float* input1, float *input2, float *output1, float *output2);
137     bool configure(string fname, float gain, unsigned int delay, unsigned int offset,
138 		   unsigned int length, unsigned int size, unsigned int bufsize,
139 		   const Gainline& gainline);
140     bool compute(int count, float* input, float *output);
141     static void compute_interpolation(double& fct, double& gp, unsigned int& idx,
142 				      const Gainline& points, int offset);
143 };
144 
compute_interpolation(double & fct,double & gp,unsigned int & idx,const Gainline & points,int offset)145 inline void GxConvolver::compute_interpolation(
146     double& fct, double& gp, unsigned int& idx, const Gainline& points, int offset) {
147     fct = (points[idx+1].g-points[idx].g)/(20*(points[idx+1].i-points[idx].i));
148     gp = points[idx].g/20 + fct * (offset-points[idx].i);
149     idx++;
150 }
151 
152 
153 class GxSimpleConvolver: public GxConvolverBase {
154 private:
155     gx_resample::BufferResampler& resamp;
156 public:
GxSimpleConvolver(gx_resample::BufferResampler & resamp_)157     GxSimpleConvolver(gx_resample::BufferResampler& resamp_)
158 	: GxConvolverBase(), resamp(resamp_) {}
159     bool configure(int count, float *impresp, unsigned int imprate);
160     bool update(int count, float *impresp, unsigned int imprate);
161     bool compute(int count, float* input, float *output);
compute(int count,float * buffer)162     bool compute(int count, float* buffer) {
163         return is_runnable() ? compute(count, buffer, buffer) : true;
164     }
165 
166     bool configure_stereo(int count, float *impresp, unsigned int imprate);
167     bool update_stereo(int count, float *impresp, unsigned int imprate);
168     bool compute_stereo(int count, float* input, float* input1, float *output, float *output1);
compute_stereo(int count,float * buffer,float * buffer1)169     bool compute_stereo(int count, float* buffer, float* buffer1)
170     {
171       return is_runnable() ? compute_stereo(count, buffer, buffer1, buffer, buffer1) : true;
172     }
173 };
174 
175 } /* end of gx_engine namespace */
176 #endif  // SRC_HEADERS_GX_CONVOLVER_H_
177