15 #include "arm_cmplx_mult_cmplx_f32.c"
56 for (
unsigned i = 0; i <
mNumBufs; i++) {
82 for (
unsigned i = 0; i < newNumBufs; i++) {
95 unsigned frames = inFile->
duration();
103 data = inFile->
buffer(chan);
114 unsigned newNumBufs = (nTaps / fftl2) + 1;
119 for (
unsigned i = 0; i <
mNumBufs; i++) {
122 unsigned offs = i * fftl2;
123 for (
unsigned j = 0; j < fftl2; j++) {
124 unsigned k = j + offs;
125 if (k >= nTaps) *sPtr++ = 0.0;
126 else *sPtr++ = data[k];
137 unsigned numFrames = outputBuffer.mNumFrames;
138 unsigned numBufs = mNumBufs;
139 unsigned windowCount = mWindowCount;
140 unsigned fftlen = mFFTSize;
141 unsigned wInp = windowCount % numBufs;
142 unsigned rbufsize = numFrames *
sizeof(
sample);
143 unsigned cbufsize = fftlen *
sizeof(
sample);
145 float norm = 1.0f / (float) fftlen;
147 if (numFrames != fftlen / 2) {
149 "Convolver2::nextBuffer # frames %d wrong for FFT size %d (use a block resizer).",
150 numFrames, mFFTSize);
155 bzero(mInputFFT[wInp], cxbufsize);
156 memcpy(mInputFFT[wInp], inp, rbufsize);
161 mFFTBuffer.setBuffer(0, (
SampleBuffer) mInputFFT[wInp]);
163 mFFTAnalyzer.nextBuffer(mFFTBuffer, mFFTBuffer);
165 bzero(mSpectrumBuffer, cxbufsize);
166 for (
unsigned i = 0; i < numBufs; i++) {
167 wInp = (numBufs + windowCount - i) % numBufs;
168 complex_multiply_accumulate(
179 mFFTBuffer.setBuffer(0, (
SampleBuffer) mSpectrumBuffer);
181 mFFTSynthesizer.nextBuffer(mFFTBuffer, mFFTBuffer);
188 for (
unsigned i = 0; i < numFrames; i++) {
189 *outP++ = (*res++ + *prev++) * norm;
192 for (
unsigned i = 0; i < numFrames; i++)
193 *outP++ = (*res++ + *prev++);
195 memcpy(mLastOutput, ((
SampleBuffer) mSpectrumBuffer) + numFrames, rbufsize);
213 #ifdef ARM // use NEON code for this
214 arm_cmplx_mult_cmplx_f32((
const float32_t *) left, (
const float32_t *) right,
215 (float32_t *) output, (uint32_t)
mFFTSize);
221 float leftRe, rightRe, leftIm, rightIm;
225 leftRe = (*loleft)[0];
226 rightRe = (*loright)[0];
227 leftIm = (*loleft)[1];
228 rightIm = (*loright)[1];
229 re = (leftRe * rightRe) - (leftIm * rightIm);
230 im = (leftRe * rightIm) + (leftIm * rightRe);
231 (*looutput)[0] += re;
232 (*looutput)[1] += im;
sample * SampleBuffer
1-channel buffer data type, vector of (sample)
void logMsg(const char *format,...)
These are the public logging messages.
SampleComplex * SampleComplexVector
complex vector
void pullInput(Buffer &outputBuffer)
virtual void setBuffer(unsigned bufNum, SampleBuffer sPtr)
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Effect – mix-in for classes that have unit generators as inputs (like filters).
Convolver2(UnitGenerator &in, char *inFName, unsigned chan=0, unsigned len=512, bool norm=false)
Constructors.
unsigned duration() const
number of frames in the sound file
void nextBuffer(Buffer &outputBuffer)
main nextBuffer call does the fft/ifft
SampleComplexMatrix mInputFFT
A list of past input spectra.
virtual unsigned numChannels()
float sample
(could be changed to int, or double)
SampleComplexVector mSpectrumBuffer
temp summing complex vector
FFT_Wrapper mFFTAnalyzer
FFT analysis/synthesis wrappers.
virtual SampleBuffer buffer(unsigned bufNum)
SampleComplexMatrix mFilterFFT
list of IR ffts
void setIRFile(char *inFName, unsigned chan=0)
SampleBuffer mLastOutput
most-recent output (1/2 window)
void checkBuffers(unsigned newNumBufs)
alloc buffers
void setIRData(float *irData, unsigned nTaps)
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
~Convolver2()
set the IR file name; runs the analysis ffts
void complex_multiply_accumulate(SampleComplexVector left, SampleComplexVector right, SampleComplexVector output)
fast complex MAC using non-interleaved complex arrays
Buffer mFFTBuffer
buffer used for FFTs, no storage
static JSoundFile * openSndfile(string path, int start=-1, int stop=-1, bool doRead=true)
Factory methods.
sample SampleComplex[2]
array-of-2 complex # type (like FFTW)
#define SAFE_MALLOC(ptr, type, len)
Useful Macros.
Base class of CSL exceptions (written upper-case). Has a string message.