Mercurial > hg > x
view QuickSpec.h @ 1:6422640a802f
first upload
author | Wen X <xue.wen@elec.qmul.ac.uk> |
---|---|
date | Tue, 05 Oct 2010 10:45:57 +0100 |
parents | |
children |
line wrap: on
line source
#ifndef QuickSpecH #define QuickSpecH /* QuickSpec.cpp - TQuickSpectrogram class TQuickSpectrogram implements a compute-on-request spectrogram class. Every time one frame of the spectrogram is read from this class, it checks if the single-frame spectrogram has been computed already, computes it if not, and return the pointer to the spectrum. Further reading: "A buffering technique for real-time spectrogram displaying.pdf" */ #include <cstddef> #include <stdlib.h> #include "xcomplex.h" #include "windowfunctions.h" #include "fft.h" //--------------------------------------------------------------------------- #define QSPEC_FORMAT float //default spectral data format #define QSpec_BufferSize 1024 //default initial buffer size, in frames, of TQuickSpectrogram /* __int24 is a 24bit signed integer type and __pint24 is its pointer type. Although __int24* will also return a pointer to an __int24 structure, operations based on __int24* may have unspecified results, depending on structure alignments imposed by compiler. It is therefore necessary to have an explicit pointer type __pint24 to enforce 24-bit data alighment. Using __int24: When storage format is not a concern, __int24 can be used the same way as __int16 or __int32. However, a default 32-bit compiler may fail to implement compact 24-bit alignment to entries of an __int24[] array. If 24-bit alignment is desired, then always create the array dynamically with new[], which returns a __pint24 type pointer. Assigning a __pint24 type pointer to __int24* type variable should be avoided. */ #ifndef INT24 #define INT24 struct __int24; struct __pint24 { char* p; __fastcall __pint24(){} __fastcall __pint24(const void* ap){p=(char*)ap;} __pint24& __fastcall operator=(const void* ap){p=(char*)ap; return *this;} __int24& __fastcall operator*(){return *(__int24*)p;} __int24& __fastcall operator[](int index){return *(__int24*)&p[3*index];} __pint24 __fastcall operator++(int){__pint24 result=*this; p+=3; return result;} __pint24& __fastcall operator++(){p+=3; return *this;} __pint24 __fastcall operator--(int){__pint24 result=*this; p-=3; return result;} __pint24& __fastcall operator--(){p-=3; return *this;} __pint24& __fastcall operator+=(int a){p+=3*a; return *this;} __pint24& __fastcall operator-=(int a){p-=3*a; return *this;} __fastcall operator void*() const{return p;} }; struct __int24 { __int16 loword; __int8 hibyte; __fastcall __int24(){} __fastcall __int24(const __int32 a){loword=*(__int16*)&a; hibyte=((__int16*)&a)[1];} __fastcall __int24(const double f){__int32 a=f; loword=*(__int16*)&a; hibyte=((__int16*)&a)[1];} __int24& __fastcall operator=(const __int32 a){loword=*(__int16*)&a; hibyte=((__int16*)&a)[1]; return *this;} __int24& __fastcall operator=(const double f){__int32 a=f; loword=*(__int16*)&a; hibyte=((__int16*)&a)[1]; return *this;} __fastcall operator __int32() const{__int32 result; *(__int16*)&result=loword; ((__int16*)&result)[1]=hibyte; return result;} __pint24 operator &(){return (__pint24)this;} void* operator new[](size_t count){void* result=malloc(3*count); return result;} void operator delete[](void* p){free(p);} }; #endif /* TQuickSpectrogram is a spectrogram class the handles the computation and storage of a spectrogram. Using TQuickSpectrogram: TQuickSpectrogram provides read-only access to the spectrogram of a given waveform. The spectrogram contains a sequence of windowed Fourier transforms, computed from uniformly placed frames. The 0th frame starts at 0 (inclusive) and finishes at Wid (exclusive). Each spectrum has Wid/2+1 entries. Follow these steps: 1. create a QuickSpectrogram, specifying usex and useph, and optionally, external buffer provide G and its arguments Id and Parent; 2. set Data, DataLength and BytesPerSample; 3. set frame size and hop size Wid and Offst; 4. if G is not specified, set window type (optional extra parameter) for computing spectra; 5. access the spectrogram via A(fr), Spec(fr) (optional) and Ph(fr) (optional). Steps 2~4 do not have to follow the given order. Call Invalidate() to notify the object of changes of waveform content. Call FreeBuffers() to return the object to the initial state before step 2. */ typedef void (*GetBuf)(int Id, cdouble* &w, cdouble* &x, double* &win, int* &hbi, void* Parent); class TQuickSpectrogram { int BufferCount; //number of buffers in use int BufferSize; //number of frames each additional buffer holds int FrCount; //number of allocated frames //internal storage of spectrogram QSPEC_FORMAT** fPh; //phase spectrogram, optional QSPEC_FORMAT** fA; //amplitude spectrogram, compulsory cmplx<QSPEC_FORMAT>** fSpec; //complete complex spectrogram, optional //internal buffers (optional) for FFT WindowType fwt; //type of window int fWid; //size of window int* fhbi; //half-size bit-inversed integer table double fwdp; //additional parameter specifying window type double* fwin; //internal window cdouble* fw; //FFT twiddle factors cdouble* fx; //FFT data buffer //x and ph create-time switch bool usex; //set at create time if complex spectrogram is required bool useph; //set at create time if phase spectrogram is required //internal methods void AddBuffer(); void AddBuffer(int AddFrCount); void __fastcall CalculateSpectrum(int fr); void SetFrCapacity(int AnFrCapacity); public: //if specified, Parent is responsible to supply FFT buffers through GetFFTBuffers (optional) int Id; //an identifier given at create time, used as argument for calling GetFFTBuffers() void* Parent; //a pointer used as argument for calling GetFFTBuffers() GetBuf GetFFTBuffers; //if specified, this supplies FFT buffers //index and validity arrays associated with internal storage int Capacity; //size of $Frame[] and &Valid[], usually set to the total number of frames of the data int* Frame; //indices to individual frames in internal storage int* Valid; //validity tags to individual frames in internal storage WindowType WinType; //window type for computing spectrogram double WinParam; //additional parameter specifying certain window types (Gaussian, Kaiser, etc.) void* Data; //pointer to waveform audio int DataLength; //length of waveform audio, in samples int BytesPerSample; //bytes per sample of waveform audio int Offst; //frame offset int Wid; //frame size, the same as window size __fastcall TQuickSpectrogram(void* AParent, int AnId, bool Ausex, bool Auseph, GetBuf G); __fastcall ~TQuickSpectrogram(); QSPEC_FORMAT* __fastcall A(int fr); //accesses amplitude spectrogram at frame fr void FreeBuffers(); //discards all computed frames and free memory int Invalidate(int From, int To); //discards computed frames QSPEC_FORMAT* __fastcall Ph(int fr); //accesses phase spectrogram at frame fr cmplx<QSPEC_FORMAT>* __fastcall Spec(int fr); //accesses complex spectrogram at frame fr }; #endif