mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-11 14:41:06 +02:00
... whenever they really describe the size of a buffer that fits in memory, or of a block file (which is never now more than a megabyte and so could be fit in memory all at once), or a part thereof.
169 lines
4.7 KiB
C++
169 lines
4.7 KiB
C++
/**********************************************************************
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
Equalization48x.h
|
|
|
|
Intrinsics (SSE/AVX) and Threaded Equalization
|
|
|
|
***********************************************************************/
|
|
|
|
#ifndef __AUDACITY_EFFECT_EQUALIZATION48X__
|
|
#define __AUDACITY_EFFECT_EQUALIZATION48X__
|
|
|
|
#include "../Experimental.h"
|
|
#ifdef EXPERIMENTAL_EQ_SSE_THREADED
|
|
|
|
#ifdef __AVX_ENABLED
|
|
#define __MAXBUFFERCOUNT 8
|
|
#else
|
|
#define __MAXBUFFERCOUNT 4
|
|
#endif
|
|
|
|
// bitwise function selection
|
|
// options are
|
|
#define MATH_FUNCTION_ORIGINAL 0 // 0 original path
|
|
#define MATH_FUNCTION_BITREVERSE_TABLE 1 // 1 SSE BitReverse Table
|
|
#define MATH_FUNCTION_SIN_COS_TABLE 2 // 2 SSE SinCos Table
|
|
#define MATH_FUNCTION_THREADED 4 // 4 SSE threaded no SinCos and no BitReverse buffer
|
|
#define MATH_FUNCTION_SSE 8 // 8 SSE no SinCos and no BitReverse buffer
|
|
#define MATH_FUNCTION_AVX 16
|
|
#define MATH_FUNCTION_SEGMENTED_CODE 32
|
|
|
|
// added by Andrew Hallendorff intrinsics processing
|
|
enum EQBufferStatus
|
|
{
|
|
BufferEmpty=0,
|
|
BufferReady,
|
|
BufferBusy,
|
|
BufferDone
|
|
};
|
|
|
|
class BufferInfo {
|
|
public:
|
|
BufferInfo() { mBufferLength=0; mBufferStatus=BufferEmpty; mContiguousBufferSize=0; };
|
|
float* mBufferSouce[__MAXBUFFERCOUNT];
|
|
float* mBufferDest[__MAXBUFFERCOUNT];
|
|
int mBufferLength;
|
|
size_t mFftWindowSize;
|
|
size_t mFftFilterSize;
|
|
float* mScratchBuffer;
|
|
int mContiguousBufferSize;
|
|
EQBufferStatus mBufferStatus;
|
|
};
|
|
|
|
typedef struct {
|
|
int x64;
|
|
int MMX;
|
|
int SSE;
|
|
int SSE2;
|
|
int SSE3;
|
|
int SSSE3;
|
|
int SSE41;
|
|
int SSE42;
|
|
int SSE4a;
|
|
int AVX;
|
|
int XOP;
|
|
int FMA3;
|
|
int FMA4;
|
|
} MathCaps;
|
|
|
|
class EffectEqualization;
|
|
|
|
class EffectEqualization48x;
|
|
|
|
static int EQWorkerCounter=0;
|
|
|
|
class EQWorker : public wxThread {
|
|
public:
|
|
EQWorker():wxThread(wxTHREAD_JOINABLE) {
|
|
mBufferInfoList=NULL;
|
|
mBufferInfoCount=0;
|
|
mMutex=NULL;
|
|
mEffectEqualization48x=NULL;
|
|
mExitLoop=false;
|
|
mThreadID=EQWorkerCounter++;
|
|
mProcessingType=4;
|
|
}
|
|
void SetData( BufferInfo* bufferInfoList, int bufferInfoCount, wxMutex *mutex, EffectEqualization48x *effectEqualization48x) {
|
|
mBufferInfoList=bufferInfoList;
|
|
mBufferInfoCount=bufferInfoCount;
|
|
mMutex=mutex;
|
|
mEffectEqualization48x=effectEqualization48x;
|
|
}
|
|
void ExitLoop() { // this will cause the thread to drop from the loops
|
|
mExitLoop=true;
|
|
}
|
|
void* Entry() override;
|
|
BufferInfo* mBufferInfoList;
|
|
int mBufferInfoCount, mThreadID;
|
|
wxMutex *mMutex;
|
|
EffectEqualization48x *mEffectEqualization48x;
|
|
bool mExitLoop;
|
|
int mProcessingType;
|
|
};
|
|
|
|
class EffectEqualization48x {
|
|
|
|
public:
|
|
|
|
EffectEqualization48x();
|
|
virtual ~EffectEqualization48x();
|
|
|
|
static MathCaps *GetMathCaps();
|
|
static void SetMathPath(int mathPath);
|
|
static int GetMathPath();
|
|
static void AddMathPathOption(int mathPath);
|
|
static void RemoveMathPathOption(int mathPath);
|
|
|
|
bool Process(EffectEqualization* effectEqualization);
|
|
bool Benchmark(EffectEqualization* effectEqualization);
|
|
private:
|
|
bool RunFunctionSelect(int flags, int count, WaveTrack * t, sampleCount start, sampleCount len);
|
|
bool TrackCompare();
|
|
bool DeltaTrack(WaveTrack * t, WaveTrack * t2, sampleCount start, sampleCount len);
|
|
bool AllocateBuffersWorkers(int nThreads);
|
|
bool FreeBuffersWorkers();
|
|
|
|
bool ProcessTail(WaveTrack * t, WaveTrack * output, sampleCount start, sampleCount len);
|
|
|
|
bool ProcessBuffer(fft_type *sourceBuffer, fft_type *destBuffer, sampleCount bufferLength);
|
|
bool ProcessBuffer1x(BufferInfo *bufferInfo);
|
|
bool ProcessOne1x(int count, WaveTrack * t, sampleCount start, sampleCount len);
|
|
void Filter1x(size_t len, float *buffer, float *scratchBuffer);
|
|
|
|
bool ProcessBuffer4x(BufferInfo *bufferInfo);
|
|
bool ProcessOne4x(int count, WaveTrack * t, sampleCount start, sampleCount len);
|
|
bool ProcessOne1x4xThreaded(int count, WaveTrack * t, sampleCount start, sampleCount len, int processingType=4);
|
|
void Filter4x(size_t len, float *buffer, float *scratchBuffer);
|
|
|
|
#ifdef __AVX_ENABLED
|
|
bool ProcessBuffer8x(BufferInfo *bufferInfo);
|
|
bool ProcessOne8x(int count, WaveTrack * t, sampleCount start, sampleCount len);
|
|
bool ProcessOne8xThreaded(int count, WaveTrack * t, sampleCount start, sampleCount len);
|
|
void Filter8x(size_t len, float *buffer, float *scratchBuffer);
|
|
#endif
|
|
|
|
EffectEqualization* mEffectEqualization;
|
|
int mThreadCount;
|
|
size_t mFilterSize;
|
|
size_t mBlockSize;
|
|
size_t mWindowSize;
|
|
int mBufferCount;
|
|
int mWorkerDataCount;
|
|
int mBlocksPerBuffer;
|
|
int mScratchBufferSize;
|
|
int mSubBufferSize;
|
|
float *mBigBuffer;
|
|
BufferInfo* mBufferInfo;
|
|
wxMutex mDataMutex;
|
|
EQWorker* mEQWorkers;
|
|
bool mThreaded;
|
|
bool mBenching;
|
|
friend EQWorker;
|
|
friend EffectEqualization;
|
|
};
|
|
|
|
#endif
|
|
|
|
#endif |