Merge pull request #110 from tesselode/fixes
[wdl/wdl-ol.git] / WDL / convoengine.h
blob53fbb33c83a70da40015fe546946eeb34e4ff67d
1 /*
2 WDL - convoengine.h
3 Copyright (C) 2006 and later Cockos Incorporated
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
22 This file provides an interface to the WDL fast convolution engine. This engine can convolve audio streams using
23 either brute force (for small impulses), or a partitioned FFT scheme (for larger impulses).
25 Note that this library needs to have lookahead ability in order to process samples. Calling Add(somevalue) may produce Avail() < somevalue.
30 #ifndef _WDL_CONVOENGINE_H_
31 #define _WDL_CONVOENGINE_H_
33 #include "queue.h"
34 #include "fastqueue.h"
35 #include "fft.h"
37 #ifndef WDL_CONVO_MAX_IMPULSE_NCH
38 #define WDL_CONVO_MAX_IMPULSE_NCH 2
39 #endif
41 #ifndef WDL_CONVO_MAX_PROC_NCH
42 #define WDL_CONVO_MAX_PROC_NCH 2
43 #endif
45 //#define WDL_CONVO_WANT_FULLPRECISION_IMPULSE_STORAGE // define this for slowerness with -138dB error difference in resulting output (+-1 LSB at 24 bit)
47 #ifdef WDL_CONVO_WANT_FULLPRECISION_IMPULSE_STORAGE
49 typedef WDL_FFT_REAL WDL_CONVO_IMPULSEBUFf;
50 typedef WDL_FFT_COMPLEX WDL_CONVO_IMPULSEBUFCPLXf;
52 #else
53 typedef float WDL_CONVO_IMPULSEBUFf;
54 typedef struct
56 WDL_CONVO_IMPULSEBUFf re, im;
58 WDL_CONVO_IMPULSEBUFCPLXf;
59 #endif
61 class WDL_ImpulseBuffer
63 public:
64 WDL_ImpulseBuffer() { samplerate=44100.0; m_nch=1; }
65 ~WDL_ImpulseBuffer() { }
67 int GetLength() { return impulses[0].GetSize(); }
68 int SetLength(int samples); // resizes/clears all channels accordingly, returns actual size set (can be 0 if error)
69 void SetNumChannels(int usench); // handles allocating/converting/etc
70 int GetNumChannels() { return m_nch; }
73 double samplerate;
74 WDL_TypedBuf<WDL_FFT_REAL> impulses[WDL_CONVO_MAX_IMPULSE_NCH];
76 private:
77 int m_nch;
81 class WDL_ConvolutionEngine
83 public:
84 WDL_ConvolutionEngine();
85 ~WDL_ConvolutionEngine();
87 int SetImpulse(WDL_ImpulseBuffer *impulse, int fft_size=-1, int impulse_sample_offset=0, int max_imp_size=0, bool forceBrute=false);
89 int GetFFTSize() { return m_fft_size; }
90 int GetLatency() { return m_fft_size/2; }
92 void Reset(); // clears out any latent samples
94 void Add(WDL_FFT_REAL **bufs, int len, int nch);
96 int Avail(int wantSamples);
97 WDL_FFT_REAL **Get(); // returns length valid
98 void Advance(int len);
100 private:
101 WDL_TypedBuf<WDL_CONVO_IMPULSEBUFf> m_impulse[WDL_CONVO_MAX_IMPULSE_NCH]; // FFT'd data blocks per channel
102 WDL_TypedBuf<char> m_impulse_zflag[WDL_CONVO_MAX_IMPULSE_NCH]; // FFT'd data blocks per channel
104 int m_impulse_nch;
105 int m_fft_size;
106 int m_impulse_len;
107 int m_proc_nch;
109 WDL_Queue m_samplesout[WDL_CONVO_MAX_PROC_NCH];
110 WDL_Queue m_samplesin2[WDL_CONVO_MAX_PROC_NCH];
111 WDL_FastQueue m_samplesin[WDL_CONVO_MAX_PROC_NCH];
113 int m_hist_pos[WDL_CONVO_MAX_PROC_NCH];
115 WDL_TypedBuf<WDL_FFT_REAL> m_samplehist[WDL_CONVO_MAX_PROC_NCH]; // FFT'd sample blocks per channel
116 WDL_TypedBuf<char> m_samplehist_zflag[WDL_CONVO_MAX_IMPULSE_NCH];
117 WDL_TypedBuf<WDL_FFT_REAL> m_overlaphist[WDL_CONVO_MAX_PROC_NCH];
118 WDL_TypedBuf<WDL_FFT_REAL> m_combinebuf;
120 WDL_FFT_REAL *m_get_tmpptrs[WDL_CONVO_MAX_PROC_NCH];
122 public:
124 // _div stuff
125 int m_zl_delaypos;
126 int m_zl_dumpage;
128 //#define WDLCONVO_ZL_ACCOUNTING
129 #ifdef WDLCONVO_ZL_ACCOUNTING
130 int m_zl_fftcnt;//removeme (testing of benchmarks)
131 #endif
132 void AddSilenceToOutput(int len, int nch);
134 } WDL_FIXALIGN;
136 // low latency version
137 class WDL_ConvolutionEngine_Div
139 public:
140 WDL_ConvolutionEngine_Div();
141 ~WDL_ConvolutionEngine_Div();
143 int SetImpulse(WDL_ImpulseBuffer *impulse, int maxfft_size=0, int known_blocksize=0, int max_imp_size=0, int impulse_offset=0, int latency_allowed=0);
145 int GetLatency();
146 void Reset();
148 void Add(WDL_FFT_REAL **bufs, int len, int nch);
150 int Avail(int wantSamples);
151 WDL_FFT_REAL **Get(); // returns length valid
152 void Advance(int len);
154 private:
155 WDL_PtrList<WDL_ConvolutionEngine> m_engines;
157 WDL_Queue m_samplesout[WDL_CONVO_MAX_PROC_NCH];
158 WDL_FFT_REAL *m_get_tmpptrs[WDL_CONVO_MAX_PROC_NCH];
160 int m_proc_nch;
161 bool m_need_feedsilence;
163 } WDL_FIXALIGN;
166 #endif