tmp
[blender.git] / extern / audaspace / include / fx / ConvolverReader.h
1 /*******************************************************************************
2 * Copyright 2015-2016 Juan Francisco Crespo Gal├ín
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *   http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 ******************************************************************************/
16
17 #pragma once
18
19 /**
20 * @file ConvolverReader.h
21 * @ingroup fx
22 * The ConvolverReader class.
23 */
24
25 #include "IReader.h"
26 #include "ISound.h"
27 #include "Convolver.h"
28 #include "ImpulseResponse.h"
29 #include "util/FFTPlan.h"
30 #include "util/ThreadPool.h"
31
32 #include <memory>
33 #include <vector>
34 #include <future>
35
36 AUD_NAMESPACE_BEGIN
37
38 /**
39 * This class represents a reader for a sound that can be modified depending on a given impulse response.
40 */
41 class AUD_API ConvolverReader : public IReader
42 {
43 private:
44         /**
45         * The current position.
46         */
47         int m_position;
48
49         /**
50         * The reader of the input sound.
51         */
52         std::shared_ptr<IReader> m_reader;
53
54         /**
55         * The impulse response in the frequency domain.
56         */
57         std::shared_ptr<ImpulseResponse> m_ir;
58         
59         /**
60         * The FFT size, given by the FFTPlan.
61         */
62         int m_N;
63
64         /**
65         * The length of the impulse response fragments, m_N/2 will be used.
66         */
67         int m_M;
68
69         /**
70         * The max length of the input slices, m_N/2 will be used.
71         */
72         int m_L;
73
74         /**
75         * The array of convolvers that will be used, one per channel.
76         */
77         std::vector<std::unique_ptr<Convolver>> m_convolvers;
78
79         /**
80         * The output buffer in which the convolved data will be written and from which the reader will read.
81         */
82         sample_t* m_outBuffer;
83
84         /**
85         * A vector of buffers (one per channel) on which the audio signal will be separated per channel so it can be convolved.
86         */
87         std::vector<sample_t*> m_vecInOut;
88
89         /**
90         * Current position in which the m_outBuffer is being read.
91         */
92         int m_outBufferPos;
93         
94         /**
95         * Effective length of the m_outBuffer.
96         */
97         int m_eOutBufLen;
98
99         /**
100         * Real length of the m_outBuffer.
101         */
102         int m_outBufLen;
103
104         /**
105         * Flag indicating whether the end of the sound has been reached or not.
106         */
107         bool m_eosReader;
108
109         /**
110         * Flag indicating whether the end of the extra data generated in the convolution has been reached or not.
111         */
112         bool m_eosTail;
113
114         /**
115         * The number of channels of the sound to be convolved.
116         */
117         int m_inChannels;
118
119         /**
120         * The number of channels of the impulse response.
121         */
122         int m_irChannels;
123
124         /**
125         * The number of threads used for channels.
126         */
127         int m_nChannelThreads;
128
129         /**
130         * Length of the input data to be used by the channel threads.
131         */
132         int m_lastLengthIn;
133
134         /**
135         * A shared ptr to a thread pool.
136         */
137         std::shared_ptr<ThreadPool> m_threadPool;
138
139         /** 
140         * A vector of futures to sync tasks.
141         */
142         std::vector<std::future<int>> m_futures;
143
144         // delete copy constructor and operator=
145         ConvolverReader(const ConvolverReader&) = delete;
146         ConvolverReader& operator=(const ConvolverReader&) = delete;
147
148 public:
149         /**
150         * Creates a new convolver reader.
151         * \param reader A reader of the input sound to be assigned to this reader.
152         * \param ir A shared pointer to an impulseResponse object that will be used to convolve the sound.
153         * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
154         * \param plan A shared pointer to and FFT plan that will be used for convolution.
155         * \exception Exception thrown if impulse response doesn't match the specs (number fo channels and rate) of the input reader.
156         */
157         ConvolverReader(std::shared_ptr<IReader> reader, std::shared_ptr<ImpulseResponse> ir, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan);
158         virtual ~ConvolverReader();
159
160         virtual bool isSeekable() const;
161         virtual void seek(int position);
162         virtual int getLength() const;
163         virtual int getPosition() const;
164         virtual Specs getSpecs() const;
165         virtual void read(int& length, bool& eos, sample_t* buffer);
166
167 private:
168         /**
169         * Divides a sound buffer in several buffers, one per channel.
170         * \param buffer The buffer that will be divided.
171         * \param len The length of the buffer.
172         */
173         void divideByChannel(const sample_t* buffer, int len);
174
175         /**
176         * Joins several buffers (one per channel) into the m_outBuffer.
177         * \param start The starting position from which the m_outBuffer will be written.
178         * \param len The amout of samples that will be joined.
179         */
180         void joinByChannel(int start, int len);
181
182         /**
183         * Loads the m_outBuffer with data.
184         */
185         void loadBuffer();
186
187         /**
188         * The function that the threads will run. It will process a subset of channels.
189         * \param id An id number that will determine which subset of channels will be processed.
190         * \param input A flag that will indicate if thare is input data.
191         *               -If true there is new input data.
192         *               -If false there isn't new input data.
193         * \return The number of samples obtained.
194         */
195         int threadFunction(int id, bool input);
196 };
197
198 AUD_NAMESPACE_END