drc-3.2.2/ 0000755 0000764 0000145 00000000000 13163367152 011260 5 ustar denis itadm drc-3.2.2/source/ 0000755 0000764 0000145 00000000000 13165107362 012555 5 ustar denis itadm drc-3.2.2/source/drc.workspace 0000644 0000764 0000145 00000000416 12033305710 015234 0 ustar denis itadm
drc-3.2.2/source/fftsg.h 0000644 0000764 0000145 00000001727 11320611736 014042 0 ustar denis itadm /*
Fast Fourier/Cosine/Sine Transform
Copyright Takuya OOURA, 1996-2001
(Email: ooura@kurims.kyoto-u.ac.jp or ooura@mmm.t.u-tokyo.ac.jp)
You may use, copy, modify and distribute this code for any
purpose (include commercial use) and without fee.
http://momonga.t.u-tokyo.ac.jp/~ooura/fft.html
*/
#ifndef fftsg_h
#define fftsg_h
#include "drc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define OouraForward (-1)
#define OouraBackward (1)
#define OouraRForward (1)
#define OouraRBackward (-1)
void cdft(int nx2, int dir, DRCFloat * data, int * ip, DRCFloat * w);
void rdft(int n, int dir, DRCFloat * data, int * ip, DRCFloat * w);
void ddct(int n, int dir, DRCFloat * data, int * ip, DRCFloat * w);
void ddst(int n, int dir, DRCFloat * data, int * ip, DRCFloat * w);
void dfct(int n, DRCFloat *a, DRCFloat *t, int *ip, DRCFloat *w);
void dfst(int n, DRCFloat *a, DRCFloat *t, int *ip, DRCFloat *w);
#ifdef __cplusplus
}
#endif
#endif
drc-3.2.2/source/baselib.h 0000644 0000764 0000145 00000007055 13162156312 014332 0 ustar denis itadm /****************************************************************************
DRC: Digital Room Correction
Copyright (C) 2002, 2003 Denis Sbragion
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
You can contact the author on Internet at the following address:
d.sbragion@neomerica.it
****************************************************************************/
/* Funzioni di libreria base */
#ifndef BaseLib_h
#define BaseLib_h
/* Inclusioni */
#include "dsplib.h"
#include "boolean.h"
#include "drc.h"
#include
/* Output stringhe con sync output e parametro */
int sputsp(const char * s, const char * p);
/* Output stringhe con sync output */
int sputs(const char * s);
/* Determina la lunghezza di un file */
size_t FSize(FILE * F);
/* Tipo file da leggere */
typedef enum { PcmInt16Bit = 'I', PcmFloat32Bit = 'F', PcmFloat64Bit = 'D' } IFileType;
/* Tipo ampiezza target function */
typedef enum { MAGLinear = 'L', MAGdB = 'D' } TFMagType;
/*
Legge parte di un file di ingresso e lo pone nell'array indicato
di dimensione InitWindow.
Ritorna true se l'operazione ha successo.
*/
Boolean ReadSignal(const char * FName,DRCFloat * Dst,const int InitWindow,
const int ImpulseCenter,const IFileType FType,
int * PreSpikeStart, int * PostSpikeEnd);
/* Scrive il segnale indicato su disco */
Boolean WriteSignal(const char * FName,const DRCFloat * Src,const int SSize,
const IFileType FType);
/* Sovrascrive il segnale indicato su disco */
Boolean OverwriteSignal(const char * FName,const DRCFloat * Src,const int SSize, const int Skip,
const IFileType FType);
/* Calcola l'autocorrelazione del sgnale S */
Boolean AutoCorrelation(DLReal * S, int N);
/* Calcola la cross correlazione tra S1 e S2 */
/* XC deve avere lunghezza 2N - 1 */
Boolean CrossCorrelation(DLReal * S1, DLReal * S2, int N, DLReal * XC);
/* Calcola il ritardo di gruppo del segnale S */
Boolean GroupDelay(const DLReal * S, const int N, DLReal * GD);
/* I/O Delay computation, reliable only for simple impulse responses */
DLReal LinearDelay(DLReal * Hn,unsigned int N,unsigned int Np,DLReal MZE);
/* Conta il numero di righe in un file */
int FLineCount(const char * FName);
/* Legge i punti di generazione filtro FIR dal file indicato */
Boolean ReadPoints(char * CorrFile,const TFMagType MagType,
DLReal * FilterFreqs,DLReal * FilterM,DLReal * FilterP,const int NPoints,
int SampleRate);
/* Integra due funzioni di trsferimento definite per punti, usando
una interpolazione lineare, ritorna il numero di punti generati,
che non sono mai pi di NPoints1 + NPoints2 */
int LITFMerge(DLReal * FilterFreqs1,DLComplex * FilterPoints1,const int NPoints1,
DLReal * FilterFreqs2,DLComplex * FilterPoints2,const int NPoints2,
DLReal * FilterFreqsOut,DLComplex * FilterPointsOut);
/* Trova il valore massimo all'interno di un file. */
int FindMaxPcm(const char * FName,const IFileType FType);
#endif
drc-3.2.2/source/drc.workspace.layout 0000644 0000764 0000145 00000000353 13165107243 016560 0 ustar denis itadm
drc-3.2.2/source/dsplib.h 0000644 0000764 0000145 00000003557 13162156312 014211 0 ustar denis itadm /****************************************************************************
DRC: Digital Room Correction
Copyright (C) 2002, 2003 Denis Sbragion
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
You can contact the author on Internet at the following address:
d.sbragion@neomerica.it
****************************************************************************/
/****************************************************************************
Progetto : DSP Library.
File : DspLib.h
Autore : Sbragion Denis
Descrizione : Definizioni base
Revisioni :
16/10/93 : Prima stesura.
****************************************************************************/
#ifndef DspLib_h
#define DspLib_h
#include
#include
#include "boolean.h"
#include "drc.h"
typedef DRCFloat DLReal;
/* Imposta la funzioni trigonometriche ridotte */
#define DLSin DRCSin
#define DLCos DRCCos
#ifndef M_PI
#define M_PI ((DLReal) 3.14159265358979323846264338327950288)
#endif
#ifndef M_2PI
#define M_2PI ((DLReal) 6.28318530717958647692528676655900576)
#endif
typedef std::complex DLComplex;
#endif
/***************************************************************************/
drc-3.2.2/source/hd.cpp 0000644 0000764 0000145 00000024216 13162156312 013655 0 ustar denis itadm /****************************************************************************
DRC: Digital Room Correction
Copyright (C) 2002, 2003 Denis Sbragion
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
You can contact the author on Internet at the following address:
d.sbragion@neomerica.it
****************************************************************************/
/* Deconvoluzione omomorfa */
/* Inclusioni */
#include "hd.h"
#include "fft.h"
#include "baselib.h"
#include "level.h"
#include
/* Memory leaks debugger */
#ifdef DebugMLeaks
#include "debug_new.h"
#endif
/* Effettua la deconvoluzione omomorfa del segnale In */
/* Versione basata sul calcolo del Cepstrum */
Boolean CepstrumHD(const DLReal * In, DLReal * MPOut, DLReal * EPOut,
const int N, const int MExp)
{
DLComplex * FFTArray1;
DLComplex * FFTArray2;
int FS;
int I;
Boolean LogLimit;
DLReal CV;
/* Controlla se si deve adottare una potenza di due */
if (MExp >= 0)
{
/* Calcola la potenza di due superiore a N */
for (FS = 1;FS <= N;FS <<= 1);
FS *= 1 << MExp;
}
else
FS = N;
/* Alloca gli array per l'FFT */
if ((FFTArray1 = new DLComplex[FS]) == NULL)
return False;
if ((FFTArray2 = new DLComplex[FS]) == NULL)
return False;
/* Copia l'array sorgente in quello temporaneo */
for (I = 0;I < N;I++)
FFTArray1[I] = In[I];
/* Azzera la parte rimanente */
for (I = N;I < FS;I++)
FFTArray1[I] = 0;
/* Trasforma l'array risultante */
Fft(FFTArray1,FS);
/* Calcola i valori per il cepstrum */
LogLimit = False;
for (I = 0;I < FS;I++)
{
CV = std::abs(FFTArray1[I]);
if (CV <= 0)
{
LogLimit = True;
FFTArray2[I] = (DLReal) log(DRCMinFloat);
}
else
FFTArray2[I] = std::log(CV);
}
/* Verifica se si raggiunto il limite */
if (LogLimit == True)
sputs("Notice: log limit reached in cepstrum computation.");
/* Calcola il cepstrum */
IFft(FFTArray2,FS);
/* Finestra il cepstrum */
for (I = 1; I < FS/2;I++)
FFTArray2[I] *= 2;
for (I = FS/2 + 1; I < FS;I++)
FFTArray2[I] = 0;
/* Calcola la trsformata del cepstrum finestrato */
Fft(FFTArray2,FS);
/* Effettua il calcolo dell'esponenziale */
for (I = 0;I < FS;I++)
FFTArray2[I] = std::exp(FFTArray2[I]);
/* Verifica se deve estrarre la componente EP */
if (EPOut != NULL)
{
/* Determina la trasformata della parte excess phase */
for (I = 0;I < FS;I++)
FFTArray1[I] = std::polar((DLReal) 1.0,
std::arg(FFTArray1[I]) - std::arg(FFTArray2[I]));
/* Determina la risposta del sistema excess phase */
IFft(FFTArray1,FS);
/* Copia il risultato nell'array destinazione */
for (I = 0;I < N;I++)
EPOut[I] = std::real(FFTArray1[I]);
}
/* Verifica se deve estrarre la componente MP */
if (MPOut != NULL)
{
/* Determina la risposta del sistema a fase minima */
IFft(FFTArray2,FS);
/* Copia il risultato nell'array destinazione */
for (I = 0;I < N;I++)
MPOut[I] = std::real(FFTArray2[I]);
}
/* Dealloca gli array */
delete[] FFTArray1;
delete[] FFTArray2;
/* Operazione completata */
return True;
}
/* Effettua la deconvoluzione omomorfa del segnale In */
/* Versione basata sulla trasformata di Hilbert */
Boolean HilbertHD(const DLReal * In, DLReal * MPOut, DLReal * EPOut,
const int N,const int MExp)
{
DLComplex * FFTArray1;
DLComplex * FFTArray2;
DLReal * FFTArray3;
int FS;
int I;
Boolean LogLimit;
DLReal CV;
/* Controlla se si deve adottare una potenza di due */
if (MExp >= 0)
{
/* Calcola la potenza di due superiore a N */
for (FS = 1;FS <= N;FS <<= 1);
FS *= 1 << MExp;
}
else
FS = N;
/* Alloca gli array per l'FFT */
if ((FFTArray1 = new DLComplex[FS]) == NULL)
return False;
if ((FFTArray2 = new DLComplex[FS]) == NULL)
return False;
if ((FFTArray3 = new DLReal[FS]) == NULL)
return False;
/* Copia l'array sorgente in quello temporaneo */
for (I = 0;I < N;I++)
FFTArray1[I] = In[I];
/* Azzera la parte rimanente */
for (I = N;I < FS;I++)
FFTArray1[I] = 0;
/* Trasforma l'array risultante */
Fft(FFTArray1,FS);
/* Calcola i valori per la trasformata di Hilbert */
LogLimit = False;
for (I = 0;I < FS;I++)
{
CV = std::abs(FFTArray1[I]);
if (CV <= DRCMinFloat)
{
LogLimit = True;
FFTArray2[I] = (DLReal) log(DRCMinFloat);
FFTArray3[I] = DRCMinFloat;
}
else
{
FFTArray2[I] = std::log(CV);
FFTArray3[I] = CV;
}
}
/* Verifica se si raggiunto il limite */
if (LogLimit == True)
sputs("Notice: log limit reached in Hilbert computation.");
/* Calcola la fase per la componente a fase minima */
IFft(FFTArray2,FS);
for (I = 1 + FS / 2; I < FS;I++)
FFTArray2[I] = -FFTArray2[I];
FFTArray2[0] = 0;
FFTArray2[FS / 2] = 0;
Fft(FFTArray2,FS);
/* Effettua la convoluzione per l'estrazione del sistema
a fase minima */
for (I = 0; I < FS;I++)
FFTArray2[I] = FFTArray3[I] * std::exp(FFTArray2[I]);
/* Dealloca gli array */
delete[] FFTArray3;
/* Verifica se deve estrarre la componente EP */
if (EPOut != NULL)
{
/* Determina la trasformata della parte excess phase */
for (I = 0;I < FS;I++)
FFTArray1[I] = std::polar((DLReal) 1.0,
std::arg(FFTArray1[I]) - std::arg(FFTArray2[I]));
/* Determina la risposta del sistema excess phase */
IFft(FFTArray1,FS);
/* Copia il risultato nell'array destinazione */
for (I = 0;I < N;I++)
EPOut[I] = std::real(FFTArray1[I]);
}
/* Verifica se deve estrarre la componente MP */
if (MPOut != NULL)
{
/* Determina la risposta del sistema a fase minima */
IFft(FFTArray2,FS);
/* Copia il risultato nell'array destinazione */
for (I = 0;I < N;I++)
MPOut[I] = std::real(FFTArray2[I]);
}
/* Dealloca gli array */
delete[] FFTArray1;
delete[] FFTArray2;
/* Operazione completata */
return True;
}
/* Experimental nonsense, ignore */
/* Effettua la decomposizione del segnale In nelle somponenti allmag/allphase */
Boolean AMAPDecomposition(const DLReal * In, DLReal * AMOut, DLReal * APOut,
const int N, const int PFactor)
{
DLComplex * FFTArray1;
DLComplex * FFTArray2;
int FS;
int I,J;
DLReal PA[2];
/* Calcola la potenza di due superiore a N */
for(FS = 1;FS <= N;FS <<= 1);
FS *= 1 << PFactor;
/* Alloca gli array per l'FFT */
if ((FFTArray1 = new DLComplex[FS]) == NULL)
return False;
if ((FFTArray2 = new DLComplex[FS]) == NULL)
return False;
/* Azzera l'array conversione */
for (I = 0;I < FS;I++)
FFTArray1[I] = 0;
/* Copia l'array sorgente in quello temporaneo */
for (I = 0,J = (FS - N) / 2;I < N;I++,J++)
FFTArray1[J] = In[I];
/* Trasforma l'array risultante */
Radix2Fft(FFTArray1,FS);
/* Trasforma nella componente allmag */
PA[0] = 1;
PA[1] = -1;
for (I = 0;I < FS;I++)
FFTArray2[I] = FFTArray1[I] = PA[I % 2] * std::abs(FFTArray1[I]);
/* Calcola la componente allmag */
Radix2IFft(FFTArray1,FS);
/* Copia il risultato nell'array destinazione */
for (I = 0,J = (FS - N) / 2;I < N;I++,J++)
AMOut[I] = std::real(FFTArray1[J]);
/* Azzera l'array conversione */
for (I = 0;I < FS;I++)
FFTArray1[I] = 0;
/* Copia l'array sorgente in quello temporaneo */
for (I = 0,J = (FS - N) / 2;I < N;I++,J++)
FFTArray1[J] = In[I];
/* Trasforma l'array risultante */
Radix2Fft(FFTArray1,FS);
/* Trasforma nella componente allphase */
for (I = 0;I < FS;I++)
FFTArray1[I] = FFTArray1[I] / FFTArray2[I];
/* Calcola la componente allphase */
Radix2IFft(FFTArray1,FS);
/* Copia il risultato nell'array destinazione */
for (I = 0;I < N / 2;I++)
APOut[I] = std::real(FFTArray1[FS - I]);
for (I = N / 2;I < N;I++)
APOut[I] = std::real(FFTArray1[I]);
/* Rinormalizza il risultato */
// NormFlat(APOut,N,1,PFactor);
/* Dealloca gli array temporanei */
delete[] FFTArray1;
delete[] FFTArray2;
/* Operazione completata */
return True;
}
/* Effettua la decomposizione del segnale In nelle somponenti no phase/no mag */
Boolean NPNMDecomposition(const DLReal * In, DLReal * NPOut, DLReal * NMOut,
const int N, const int PFactor)
{
DLComplex * FFTArray1;
DLComplex * FFTArray2;
int FS;
int I;
/* Calcola la potenza di due superiore a N */
for(FS = 1;FS <= N;FS <<= 1);
FS *= 1 << PFactor;
/* Alloca gli array per l'FFT */
if ((FFTArray1 = new DLComplex[FS]) == NULL)
return False;
if ((FFTArray2 = new DLComplex[FS]) == NULL)
return False;
/* Copia l'array sorgente in quello temporaneo */
for (I = 0;I < N;I++)
FFTArray1[I] = In[I];
/* Azzera la parte rimanente */
for (I = N;I < FS;I++)
FFTArray1[I] = 0;
/* Trasforma l'array risultante */
Radix2Fft(FFTArray1,FS);
/* Trasforma nella componente no phase */
for (I = 0;I < FS;I++)
FFTArray2[I] = std::abs(FFTArray1[I]);
/* Calcola la componente allmag */
Radix2IFft(FFTArray2,FS);
/* Copia il risultato nell'array destinazione */
for (I = 0;I < N;I++)
NPOut[I] = std::real(FFTArray2[I]);
/* Trasforma nella componente allphase */
for (I = 0;I < FS;I++)
FFTArray2[I] = FFTArray1[I] / std::abs(FFTArray1[I]);
/* Calcola la componente allphase */
Radix2IFft(FFTArray2,FS);
/* Copia il risultato nell'array destinazione */
for (I = 0;I < N;I++)
NMOut[I] = std::real(FFTArray2[I]);
/* Dealloca gli array temporanei */
delete[] FFTArray1;
delete[] FFTArray2;
/* Operazione completata */
return True;
}
drc-3.2.2/source/lsconv.layout 0000644 0000764 0000145 00000000552 13165107243 015320 0 ustar denis itadm
drc-3.2.2/source/glsweep.cbp 0000644 0000764 0000145 00000004562 13165106030 014707 0 ustar denis itadm
drc-3.2.2/source/slprefilt.cpp 0000644 0000764 0000145 00000055253 13165105213 015270 0 ustar denis itadm /****************************************************************************
DRC: Digital Room Correction
Copyright (C) 2002, 2003 Denis Sbragion
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
You can contact the author on Internet at the following address:
d.sbragion@neomerica.it
****************************************************************************/
/* Prefiltratura a bande tramite sliding lowpass di un segnale */
#include
#include "slprefilt.h"
#include "level.h"
#include "baselib.h"
/* Memory leaks debugger */
#ifdef DebugMLeaks
#include "debug_new.h"
#endif
/* Calcolo filtro passa basso finestrato Blackman */
/* Il calcolo viene effettuato usando una ricorsione trigonometrica
per migliorare le prestazioni di generazione */
/* La finestratura viene generata solo per met */
void FastLowPassFir(DLReal * Filter,const unsigned int Order,const DLReal Freq,
DLReal * Window,const unsigned int WSize)
{
/* Variabili per le ricorsioni trigonometriche */
DLReal SR1,SS1,SV1;
DLReal CR1,CS1,CV1;
DLReal CR2,CS2,CV2;
/* Indici creazione filtro e finestra */
unsigned int I,J,K;
unsigned int HalfOrder = Order / 2;
/* Periodo filtro */
DLReal C = (DLReal) (((DLReal) M_PI) * Freq);
/* Valore attuale finestra */
DLReal WV;
/* Periodo finestratura */
DLReal C1;
DLReal C2;
/* Verifica che non si tratti del filtro banale */
if (Order == 1)
{
Filter[0] = (DLReal) 1.0;
return;
}
/* Verifica se deve essere calcolata la finestratura */
if (WSize > 0)
{
/* Finestratura gi presente, procede con la creazione del filtro */
/* Verifica l'ordine del filtro */
if (Order%2 == 0)
{
/* Inizializza le variabili per il calcolo della ricorsione
per il filtro */
/* R = sin(sd/2); */
SR1 = (DLReal) DLSin(((DLReal) 0.5) * C);
/* S = sin(sv); */
/* S = sin(sd) * cos(sv) + (S * (1 - cos(sd))); */
SS1 = ((DLReal) DLSin(C)) * ((DLReal) DLCos(((DLReal) 0.5) * C)) +
(SR1 * (((DLReal) 1.0) - ((DLReal) DLCos(C))));
/* V = sin(sv); */
SV1 = SR1;
/* R = -4 * R * R; */
SR1 = ((DLReal) -4.0) * SR1 * SR1;
/* Ciclo creazione filtro */
for(I = 1,J = HalfOrder - 1,K = HalfOrder; I <= HalfOrder;I++,J--,K++)
{
/* Calcola e assegna il valore per il filtro */
Filter[J] = Filter[K] = (DLReal) (Window[J] * SV1 /
((I - ((DLReal) 0.5)) * ((DLReal) M_PI)));
/* Calcola il valore successivo filtro per ricorsione */
SS1 += SR1 * SV1;
SV1 += SS1;
}
}
else
{
/* Inizializza le variabili per il calcolo della ricorsione
per il filtro */
/* S = sin(sv); */
SS1 = ((DLReal) DLSin(C));
/* V = sin(sv); */
SV1 = SS1;
/* S = sin(sd) * cos(sv) + (S * (1 - cos(sd))); */
SR1 = ((DLReal) DLCos(C));
SS1 = SS1 * SR1 + (SS1 * (((DLReal) 1.0) - SR1));
/* R = sin(sd/2); */
/* R = -4 * R * R; */
SR1 = (DLReal) DLSin(((DLReal) 0.5) * C);
SR1 = ((DLReal) -4.0) * SR1 * SR1;
/* Ciclo creazione filtro */
for(I = 1,J = HalfOrder - 1,K = HalfOrder + 1; I <= HalfOrder;I++,J--,K++)
{
/* Calcola e assegna il valore per il filtro */
Filter[J] = Filter[K] = (DLReal) (Window[J] * SV1 / (I * ((DLReal) M_PI)));
/* Calcola il valore successivo filtro per ricorsione */
SS1 += SR1 * SV1;
SV1 += SS1;
}
/* Assegna il valore centrale */
Filter[HalfOrder] = Freq;
}
}
else
{
/* Finestratura da calcolare, inizializza il periodo */
C1 = (DLReal) (2 * ((DLReal) M_PI) / (Order - 1));
C2 = (DLReal) (4 * ((DLReal) M_PI) / (Order - 1));
/* Verifica l'ordine del filtro */
if (Order%2 == 0)
{
/* Inizializza le variabili per il calcolo della ricorsione
per la finestratura */
/* R = sin(cd/2); */
/* R = -4 * R * R; */
CR1 = (DLReal) DLSin(((DLReal) 0.5) * C1);
CR1 = ((DLReal) -4.0) * CR1 * CR1;
/* S = cos(cv); */
CS1 = (DLReal) DLCos(HalfOrder * C1);
/* S = (S * (1 - cos(cd))) - sin(cv) * sin(cd); */
CS1 = (CS1 * (((DLReal) 1.0) - ((DLReal) DLCos(C1)))) -
((DLReal) DLSin(HalfOrder * C1)) * ((DLReal) DLSin(C1));
/* V = cos(cv); */
CV1 = (DLReal) DLCos(HalfOrder * C1);
/* R = sin(cd/2); */
/* R = -4 * R * R; */
CR2 = (DLReal) DLSin(((DLReal) 0.5) * C2);
CR2 = ((DLReal) -4.0) * CR2 * CR2;
/* S = cos(cv); */
CS2 = (DLReal) DLCos(HalfOrder * C2);
/* S = (S * (1 - cos(cd))) - sin(cv) * sin(cd); */
CS2 = (CS2 * (((DLReal) 1.0) - ((DLReal) DLCos(C2)))) -
((DLReal) DLSin(HalfOrder * C2)) * ((DLReal) DLSin(C2));
/* V = cos(cv); */
CV2 = (DLReal) DLCos(HalfOrder * C2);
/* Inizializza le variabili per il calcolo della ricorsione
per il filtro */
/* R = sin(sd/2); */
SR1 = (DLReal) DLSin(((DLReal) 0.5) * C);
/* S = sin(sv); */
/* S = sin(sd) * cos(sv) + (S * (1 - cos(sd))); */
SS1 = ((DLReal) DLSin(C)) * ((DLReal) DLCos(((DLReal) 0.5) * C)) +
(SR1 * (((DLReal) 1.0) - ((DLReal) DLCos(C))));
/* V = sin(sv); */
SV1 = SR1;
/* R = -4 * R * R; */
SR1 = ((DLReal) -4.0) * SR1 * SR1;
/* Ciclo creazione filtro */
for(I = 1,J = HalfOrder - 1,K = HalfOrder; I <= HalfOrder;I++,J--,K++)
{
/* Calcola e assegna il valore della finestra */
Window[J] = WV = (DLReal) (((DLReal) 0.42) - ((DLReal) 0.5) * CV1 +
((DLReal) 0.08) * CV2);
/* Calcola e assegna il valore per il filtro */
Filter[J] = Filter[K] = (DLReal) (WV * SV1 / ((I - ((DLReal) 0.5)) * ((DLReal) M_PI)));
/* Calcola il valore successivo filtro per ricorsione */
SS1 += SR1 * SV1;
SV1 += SS1;
/* Calcola il valore successivo finestra per ricorsione */
CS1 += CR1 * CV1;
CV1 += CS1;
CS2 += CR2 * CV2;
CV2 += CS2;
}
}
else
{
/* Inizializza le variabili per il calcolo della ricorsione
per la finestratura */
/* R = sin(cd/2); */
/* R = -4 * R * R; */
CR1 = (DLReal) DLSin(((DLReal) 0.5) * C1);
CR1 = ((DLReal) -4.0) * CR1 * CR1;
/* S = cos(cv); */
CS1 = (DLReal) DLCos((HalfOrder + 1) * C1);
/* S = (S * (1 - cos(cd))) - sin(cv) * sin(cd); */
CS1 = (CS1 * (((DLReal) 1.0) - ((DLReal) DLCos(C1)))) -
((DLReal) DLSin((HalfOrder + 1) * C1)) * ((DLReal) DLSin(C1));
/* V = cos(cv); */
CV1 = (DLReal) DLCos((HalfOrder + 1) * C1);
/* R = sin(cd/2); */
/* R = -4 * R * R; */
CR2 = (DLReal) DLSin(((DLReal) 0.5) * C2);
CR2 = ((DLReal) -4.0) * CR2 * CR2;
/* S = cos(cv); */
CS2 = (DLReal) DLCos((HalfOrder + 1) * C2);
/* S = (S * (1 - cos(cd))) - sin(cv) * sin(cd); */
CS2 = (CS2 * (((DLReal) 1.0) - ((DLReal) DLCos(C2)))) -
((DLReal) DLSin((HalfOrder + 1) * C2)) * ((DLReal) DLSin(C2));
/* V = cos(cv); */
CV2 = (DLReal) DLCos((HalfOrder + 1) * C2);
/* Inizializza le variabili per il calcolo della ricorsione
per il filtro */
/* S = sin(sv); */
SS1 = ((DLReal) DLSin(C));
/* V = sin(sv); */
SV1 = SS1;
/* S = sin(sd) * cos(sv) + (S * (1 - cos(sd))); */
SR1 = ((DLReal) DLCos(C));
SS1 = SS1 * SR1 + (SS1 * (((DLReal) 1.0) - SR1));
/* R = sin(sd/2); */
/* R = -4 * R * R; */
SR1 = (DLReal) DLSin(((DLReal) 0.5) * C);
SR1 = ((DLReal) -4.0) * SR1 * SR1;
/* Ciclo creazione filtro */
for(I = 1,J = HalfOrder - 1,K = HalfOrder + 1; I <= HalfOrder;I++,J--,K++)
{
/* Calcola e assegna il valore della finestra */
Window[J] = WV = (DLReal) (((DLReal) 0.42) - ((DLReal) 0.5) * CV1 +
((DLReal) 0.08) * CV2);
/* Calcola e assegna il valore per il filtro */
Filter[J] = Filter[K] = (DLReal) (WV * SV1 / (I * ((DLReal) M_PI)));
/* Calcola il valore successivo filtro per ricorsione */
SS1 += SR1 * SV1;
SV1 += SS1;
/* Calcola il valore successivo finestra per ricorsione */
CS1 += CR1 * CV1;
CV1 += CS1;
CS2 += CR2 * CV2;
CV2 += CS2;
}
/* Assegna il valore centrale del filtro */
Filter[HalfOrder] = Freq;
}
}
}
/* Prefiltratura a bande tramite sliding lowpass di un segnale */
void SLPreFilt(DLReal * InImp, const int IBS, const int FBS,
const int FilterLen, const int BandSplit, const DLReal WindowExponent,
const int SampleFreq, const DLReal StartFreq, const DLReal EndFreq,
int WindowGap, DLReal FSharpness, DLReal * OutImp,
const WindowType WType, const SLPPrefilteringType SLPType)
{
/* Array filtro FIR */
DLReal * FIRFilter;
/* Array finestratura filtro */
DLReal * FWin;
/* Dimensione effettiva filtro FIR */
int EFL, HEFL;
/* Dimensione corrente filtro FIR */
int CFL;
int CHFL;
int CFLM;
/* Dimensione attuale finestra */
int CWL;
/* Dimensione effettiva finestra */
int EWL;
/* Indici convoluzione */
int I,J,IS,FS,EI;
/* Dimensioni blocco in uscita */
int NR,HNR;
/* Posizione semiblocchi destro e sinistro */
int OCP;
/* Numero banda corrente */
int Band;
/* Frequenza di taglio. */
DLReal BCut = 0;
/* Larghezza banda */
DLReal BWidth;
/* Inizio e fine filtratura */
DLReal FilterBegin;
DLReal FilterEnd;
/* Coefficienti calcolo frequenza di taglio su finestra */
DLReal A = 0;
DLReal Q = 0;
DLReal B = 0;
int HFBS;
int HIBS;
/* Sommatoria filtratura */
DLReal Sum;
/* Variabili per il Kahan summation algorithm */
DLReal SC;
DLReal SY;
DLReal ST;
/* Calcola inizio e fine della prefiltratura */
FilterBegin = (2 * StartFreq) / SampleFreq;
FilterEnd = (2 * EndFreq) / SampleFreq;
/* Calcola la dimensione effettiva filtro FIR */
if (FilterLen % 2 == 0)
{
EFL = FilterLen - 1;
/* Azzera l'ultimo campione del blocco in uscita in quanto non utilizzato */
OutImp[(IBS + FilterLen - 1) - 1] = 0;
}
else
EFL = FilterLen;
HEFL = EFL / 2;
/* Calcola la dimensione del blocco in uscita */
NR = IBS + EFL - 1;
/* Calcola il centro dei semiblocchi */
HNR = NR / 2;
/* Alloca gli array temporanei */
FIRFilter = new DLReal[EFL];
FWin = new DLReal[HEFL];
/* Imposta i parametri iniziali per la visualizzazione */
BWidth = (DLReal) pow(2,1.0/BandSplit);
Band = 0;
/* Calcola le dimensioni finestratura effettive */
HFBS = FBS / 2;
HIBS = IBS / 2;
/* Effettua la finestratura iniziale del segnale in ingresso */
sputs("Input signal prewindowing.");
SpacedBlackmanWindow(InImp,IBS,WindowGap,WType);
/* Verifica il tipo di curva di prefiltratura */
switch (SLPType)
{
/* Proporzionale */
case SLPProportional:
/* Calcola i coefficienti per il calcolo finestratura */
B = (DLReal) exp(log(FilterBegin / FilterEnd) / WindowExponent);
Q = (DLReal) ((B * HIBS - HFBS) / (1.0 - B));
A = (DLReal) (1.0 / (FilterEnd * pow(HFBS + Q,WindowExponent)));
break;
/* Bilineare */
case SLPBilinear:
A = (DLReal) (HIBS - HFBS);
B = (FilterEnd - FilterBegin);
Q = (DLReal) ((pow(WindowExponent,4.0) * (FilterBegin / FilterEnd)) - 1.0);
break;
}
/* Finestratura sinistra */
if ((WType == WLeft) || (WType == WFull))
{
/* Prepara gli indici per la convoluzione */
EWL = (int) floor(FSharpness * HNR);
CHFL = HEFL;
/* Verifica che il filtro stia all'interno della finestratura corrente */
if (CHFL >= EWL)
{
/* Ricalcola la dimensione del filtro */
if (EWL > 1)
CHFL = EWL - 1;
else
CHFL = 1;
CFL = 1 + (CHFL * 2);
}
else
/* Usa la dimensione base */
CFL = EFL;
/* Ricalcola il filtro e la finestra */
FastLowPassFir(FIRFilter,CFL,FilterBegin,FWin,0);
/* Segnala lo stato */
sputs("L - Initial lowpass convolution...");
/* Ciclo di convoluzione lowpass iniziale */
for(I = 0,CWL = HNR,OCP = 0;I < (HNR - HIBS);I++,CWL--,OCP++)
{
/* Calcola la finestratura effettiva corrente */
EWL = (int) floor(FSharpness * CWL);
/* Verifica che il filtro stia all'interno della finestratura corrente */
if (CHFL >= EWL)
{
/* Ricalcola la dimensione del filtro */
if (EWL > 1)
CHFL = EWL - 1;
else
CHFL = 1;
CFL = 1 + (CHFL * 2);
/* Ricalcola il filtro e la finestra */
FastLowPassFir(FIRFilter,CFL,FilterBegin,FWin,0);
}
/* Verifica se si pu utilizzare il filtro completo */
if (OCP - CHFL >= HEFL)
{
/* Imposta gli indici per il filtro completo */
CFLM = CFL;
IS = OCP - (CHFL + HEFL);
FS = 0;
}
else
{
/* Imposta gli indici per il filtro parziale */
CFLM = CFL;
IS = 0;
FS = (CHFL + HEFL) - OCP;
}
/* Esegue la convoluzione, Kahan summation algorithm */
Sum = (DLReal) 0.0;
SC = (DLReal) 0.0;
for (J = FS,EI = IS;J < CFLM;J++,EI++)
{
SY = (InImp[EI] * FIRFilter[J]) - SC;
ST = Sum + SY;
SC = (ST - Sum) - SY;
Sum = ST;
}
OutImp[OCP] = Sum;
}
/* Imposta i parametri iniziali per la visualizzazione */
Band = 0;
/* Ciclo di convoluzione sliding lowpass */
for(I = HNR - HIBS,CWL = HIBS,OCP = HNR - HIBS;I < (HNR - HFBS);I++,CWL--,OCP++)
{
/* Calcola la finestratura effettiva corrente */
EWL = (int) floor(FSharpness * CWL);
/* Verifica il tipo di curva di prefiltratura */
switch (SLPType)
{
/* Proporzionale */
case SLPProportional:
/* Calcola la frequenza di taglio */
BCut = (DLReal) 1.0 / (A * pow(CWL + Q,WindowExponent));
break;
/* Bilineare */
case SLPBilinear:
/* Calcola la frequenza di taglio */
BCut = (DLReal) FilterBegin + (B * (((HIBS - CWL) / A) * (1 + Q)) /
(1 + ((HIBS - CWL) / A) * Q));
break;
}
/* Verifica che il filtro stia all'interno della finestratura corrente */
if (CHFL >= EWL)
{
/* Ricalcola la dimensione del filtro */
if (EWL > 1)
CHFL = EWL - 1;
else
CHFL = 1;
CFL = 1 + (CHFL * 2);
/* Ricalcola il filtro e la finestra */
FastLowPassFir(FIRFilter,CFL,BCut,FWin,0);
}
else
/* Ricalcola il filtro usando la finestra corrente */
FastLowPassFir(FIRFilter,CFL,BCut,FWin,CFL);
/* Verifica visualizzazione stato prefiltratura */
if (BCut >= (DLReal) (FilterBegin * pow(BWidth,Band)))
{
/* Segnala lo stato */
printf("L - Band: %3d, %7.1f Hz, width: %6d, FIR, ", (int) Band,
(double) (BCut * SampleFreq) / 2, CWL);
/* Passa alla banda successiva */
Band++;
/* Inizio convoluzione */
sputs("convolution...");
}
/* Verifica se si pu utilizzare il filtro completo */
if (OCP - CHFL >= HEFL)
{
/* Imposta gli indici per il filtro completo */
CFLM = CFL;
IS = OCP - (CHFL + HEFL);
FS = 0;
}
else
{
/* Imposta gli indici per il filtro parziale */
CFLM = CFL;
IS = 0;
FS = (CHFL + HEFL) - OCP;
}
/* Esegue la convoluzione, Kahan summation algorithm */
Sum = (DLReal) 0.0;
SC = (DLReal) 0.0;
for (J = FS,EI = IS;J < CFLM;J++,EI++)
{
SY = (InImp[EI] * FIRFilter[J]) - SC;
ST = Sum + SY;
SC = (ST - Sum) - SY;
Sum = ST;
}
OutImp[OCP] = Sum;
}
/* Verifica il tipo di curva di prefiltratura */
switch (SLPType)
{
/* Proporzionale */
case SLPProportional:
/* Calcola la frequenza di taglio */
BCut = (DLReal) 1.0 / (A * pow(CWL + Q,WindowExponent));
break;
/* Bilineare */
case SLPBilinear:
/* Calcola la frequenza di taglio */
BCut = (DLReal) FilterBegin + (B * (((HIBS - CWL) / A) * (1 + Q)) /
(1 + ((HIBS - CWL) / A) * Q));
break;
}
/* Segnala lo stato finale */
printf("F - Band: %3d, %7.1f Hz, width: %6d, FIR, ", (int) Band,
(double) (BCut * SampleFreq) / 2, CWL);
sputs("completed.");
}
/* Effettua la convoluzione, lato destro */
if ((WType == WRight) || (WType == WFull))
{
/* Prepara gli indici per la convoluzione */
EWL = (int) floor(FSharpness * HNR);
CHFL = HEFL;
/* Verifica che il filtro stia all'interno della finestratura corrente */
if (CHFL >= EWL)
{
/* Ricalcola la dimensione del filtro */
if (EWL > 1)
CHFL = EWL - 1;
else
CHFL = 1;
CFL = 1 + (CHFL * 2);
}
else
/* Usa la dimensione base */
CFL = EFL;
/* Ricalcola il filtro e la finestra */
FastLowPassFir(FIRFilter,CFL,FilterBegin,FWin,0);
/* Segnala lo stato */
sputs("R - Initial lowpass convolution...");
/* Ciclo di convoluzione lowpass iniziale */
for(I = 0,CWL = HNR,OCP = NR - 1;I < (HNR - HIBS);I++,CWL--,OCP--)
{
/* Calcola la finestratura effettiva corrente */
EWL = (int) floor(FSharpness * CWL);
/* Verifica che il filtro stia all'interno della finestratura corrente */
if (CHFL >= EWL)
{
/* Ricalcola la dimensione del filtro */
if (EWL > 1)
CHFL = EWL - 1;
else
CHFL = 1;
CFL = 1 + (CHFL * 2);
/* Ricalcola il filtro e la finestra */
FastLowPassFir(FIRFilter,CFL,FilterBegin,FWin,0);
}
/* Verifica se si pu utilizzare il filtro completo */
if (OCP + CHFL < HEFL + IBS)
{
/* Imposta gli indici per il filtro completo */
CFLM = CFL;
IS = OCP - (CHFL + HEFL);
FS = 0;
}
else
{
/* Imposta gli indici per il filtro parziale */
CFLM = HEFL + IBS + CHFL - OCP;
IS = OCP - (CHFL + HEFL);
FS = 0;
}
/* Esegue la convoluzione, Kahan summation algorithm */
Sum = (DLReal) 0.0;
SC = (DLReal) 0.0;
for (J = FS,EI = IS;J < CFLM;J++,EI++)
{
SY = (InImp[EI] * FIRFilter[J]) - SC;
ST = Sum + SY;
SC = (ST - Sum) - SY;
Sum = ST;
}
OutImp[OCP] = Sum;
}
/* Imposta i parametri iniziali per la visualizzazione */
Band = 0;
/* Ciclo di convoluzione sliding lowpass */
for(I = HNR - HIBS,CWL = HIBS,OCP = NR - 1 - (HNR - HIBS);I < (HNR - HFBS);I++,CWL--,OCP--)
{
/* Calcola la finestratura effettiva corrente */
EWL = (int) floor(FSharpness * CWL);
/* Verifica il tipo di curva di prefiltratura */
switch (SLPType)
{
/* Proporzionale */
case SLPProportional:
/* Calcola la frequenza di taglio */
BCut = (DLReal) 1.0 / (A * pow(CWL + Q,WindowExponent));
break;
/* Bilineare */
case SLPBilinear:
/* Calcola la frequenza di taglio */
BCut = (DLReal) FilterBegin + (B * (((HIBS - CWL) / A) * (1 + Q)) /
(1 + ((HIBS - CWL) / A) * Q));
break;
}
/* Verifica che il filtro stia all'interno della finestratura corrente */
if (CHFL >= EWL)
{
/* Ricalcola la dimensione del filtro */
if (EWL > 1)
CHFL = EWL - 1;
else
CHFL = 1;
CFL = 1 + (CHFL * 2);
/* Ricalcola il filtro e la finestra */
FastLowPassFir(FIRFilter,CFL,BCut,FWin,0);
}
else
/* Ricalcola il filtro usando la finestra corrente */
FastLowPassFir(FIRFilter,CFL,BCut,FWin,CFL);
/* Verifica visualizzazione stato prefiltratura */
if (BCut >= (DLReal) (FilterBegin * pow(BWidth,Band)))
{
/* Segnala lo stato */
printf("R - Band: %3d, %7.1f Hz, width: %6d, FIR, ", (int) Band,
(double) (BCut * SampleFreq) / 2, CWL);
/* Passa alla banda successiva */
Band++;
/* Inizio convoluzione */
sputs("convolution...");
}
/* Verifica se si pu utilizzare il filtro completo */
if (OCP + CHFL < HEFL + IBS)
{
/* Imposta gli indici per il filtro completo */
CFLM = CFL;
IS = OCP - (CHFL + HEFL);
FS = 0;
}
else
{
/* Imposta gli indici per il filtro parziale */
CFLM = HEFL + IBS + CHFL - OCP;
IS = OCP - (CHFL + HEFL);
FS = 0;
}
/* Esegue la convoluzione, Kahan summation algorithm */
Sum = (DLReal) 0.0;
SC = (DLReal) 0.0;
for (J = FS,EI = IS;J < CFLM;J++,EI++)
{
SY = (InImp[EI] * FIRFilter[J]) - SC;
ST = Sum + SY;
SC = (ST - Sum) - SY;
Sum = ST;
}
OutImp[OCP] = Sum;
}
/* Verifica il tipo di curva di prefiltratura */
switch (SLPType)
{
/* Proporzionale */
case SLPProportional:
/* Calcola la frequenza di taglio */
BCut = (DLReal) 1.0 / (A * pow(CWL + Q,WindowExponent));
break;
/* Bilineare */
case SLPBilinear:
/* Calcola la frequenza di taglio */
BCut = (DLReal) FilterBegin + (B * (((HIBS - CWL) / A) * (1 + Q)) /
(1 + ((HIBS - CWL) / A) * Q));
break;
}
/* Segnala lo stato finale */
printf("F - Band: %3d, %7.1f Hz, width: %6d, FIR, ", (int) Band,
(double) (BCut * SampleFreq) / 2, CWL);
sputs("completed.");
}
/* Segnala lo stato finale */
sputs("Final allpass convolution...");
/* Copia la parte rimanente della risposta */
switch (WType)
{
case WLeft:
for (I = HNR - HFBS,J = HIBS - HFBS;J < IBS;I++,J++)
OutImp[I] = InImp[J];
for (I = NR - HEFL;I < NR;I++)
OutImp[I] = (DLReal) 0.0;
break;
case WRight:
for (I = 0;I < HEFL;I++)
OutImp[I] = (DLReal) 0.0;
FS = HFBS + (IBS % 2);
for (I = HEFL,J = 0;I < (HNR + FS);I++,J++)
OutImp[I] = InImp[J];
break;
case WFull:
FS = HFBS + (IBS % 2);
for (I = HNR - HFBS,J = HIBS - HFBS;I < (HNR + FS);I++,J++)
OutImp[I] = InImp[J];
break;
}
/* Dealloca gli array intermedi */
delete[] FIRFilter;
delete[] FWin;
}
drc-3.2.2/source/fir.h 0000644 0000764 0000145 00000007645 13162156311 013515 0 ustar denis itadm /****************************************************************************
DRC: Digital Room Correction
Copyright (C) 2002, 2003 Denis Sbragion
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
You can contact the author on Internet at the following address:
d.sbragion@neomerica.it
****************************************************************************/
/****************************************************************************
Progetto : DSP Library.
File : Fir.h
Autore : Sbragion Denis
Descrizione : Funzioni per il calcolo di filtri fir.
Revisioni :
16/10/93 : Prima stesura.
****************************************************************************/
#ifndef Fir_h
#define Fir_h
#include "boolean.h"
#include "dsplib.h"
// Definizione tipo interpolazione
typedef enum
{
Linear,
Logarithmic,
SplineLinear,
SplineLogarithmic,
PCHIPLinear,
PCHIPLogarithmic
}
InterpolationType;
// Ritornano i filtri fir a fase lineare di ordine Order corrispondenti
// al nome della funzione. Tutti i filtri sono ricavati con la sola
// finestra rettangolare.
// Per i filtri HighPass e BandStop Order deve essere dispari.
// Se non lo e` viene calcolato un filtro con Order-1 coefficienti
// trascurando l' ultimo che viene posto a 0.
// Order deve comunque essere maggiore o uguale a 2.
void LowPassFir(DLReal * Filter,unsigned int Order,DLReal Freq);
void HighPassFir(DLReal * Filter,unsigned int Order,DLReal Freq);
void BandPassFir(DLReal * Filter,unsigned int Order,DLReal Low,
DLReal High);
void BandStopFir(DLReal * Filter,unsigned int Order,DLReal Low,
DLReal High);
// Ritorna il trasformatore di Hilbert di ordine Order ricavato con la
// sola finestra rettangolare.
// Order deve essere dispari altrimenti l' ultimo coefficiente viene
// ignorato e posto uguale a 0. Inoltre Order deve essere maggiore di 2.
void HilbertFir(DLReal * Filter,unsigned int Order);
// Genera un filtro Fir con risposta generica tramite IFft e
// finestratura. L' ordine Order deve essere maggiore o uguale a 2.
// Il filtro e` ricavato con la sola finestra rettangolare. Si ricordi
// che i filtri di ordine dispari presentano generalmente un
// comportamento piu` regolare.
// F rappresenta l' array delle frequenze su cui costruire la risposta
// del filtro. Deve essere in ordine crescente con il primo
// coefficiente 0 e l' ultimo, corrispondente a meta` della frequenza
// di campionamento, uguale a 1. M[I] e P[I] rappresentano
// guadagno e fase desiderati nei corrispondenti punti F[I].
// Ritorna False in caso di errori.
// Se Is e` 0 l' array per l' interpolazione intermedia viene preso
// con dimensione pari alla piu` piccola potenza di 2 che supera Order,
// altrimenti viene preso con dimensione Is. Is non deve comunque essere
// inferiore a Order. Per avere una elevata precisione nella
// ricostruzione della risposta utilizzare un elevato valore di Is.
// Se Is e` una potenza di 2 il calcolo risulta molto piu` rapido.
Boolean GenericFir(DLReal * Filter,unsigned int Order,DLReal * F,
DLReal * M, DLReal * P,unsigned int Np,unsigned int Is = 0,
InterpolationType It = Linear);
#endif
/***************************************************************************/
drc-3.2.2/source/spline.h 0000644 0000764 0000145 00000012160 13164710040 014210 0 ustar denis itadm /****************************************************************************
DRC: Digital Room Correction
Copyright (C) 2002-2017 Denis Sbragion
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
You can contact the author on Internet at the following address:
d.sbragion@neomerica.it
****************************************************************************/
/* Spline routines */
#ifndef Spline_h
#define Spline_h
/* Inclusioni */
#include "dsplib.h"
#include "boolean.h"
/* Tipo spline da generare */
typedef enum { SplineBDef, SplineBNat } CSplineType;
/* Valore della spline lineare nel punto X */
DLReal L1SplineValue(const DLReal * XN, const DLReal * YN,
const int N, const DLReal X);
/* Valore della spline lineare nei punti X */
/* X deve essere un array crescente strettamente monotonico */
void AL1SplineValue(const DLReal * XN, const DLReal * YN,
const int N, const DLReal * X, const int XS, DLReal * Y);
/* Prepara la base per la spline cubica interpolante, ponendola in SPD2YN */
Boolean SplinePrepare(const DLReal * XN, const DLReal * YN,
const int N, const DLReal SPD1Y1, const DLReal SPD1YN,
const CSplineType SPType, DLReal * SPD2YN);
/* Valore della spline cubica interpolante nel punto X */
DLReal SplineValue(const DLReal * XN, const DLReal * YN,
const int N, const DLReal * SPD2YN, const DLReal X);
/* Valore della spline cubica interpolante nei punti X */
/* X deve essere un array crescente strettamente monotonico */
void ASplineValue(const DLReal * XN, const DLReal * YN,
const int N, const DLReal * SPD2YN, const DLReal * X,
const int XS, DLReal * Y);
/* Valore della B spline cubica uniforme nel punto X */
DLReal B3SplineValue(const DLReal * XN, const DLReal * YN,
const int N, const DLReal X);
/* Valore della B spline cubica uniforme nei punti X */
/* X deve essere un array crescente strettamente monotonico */
void AB3SplineValue(const DLReal * XN, const DLReal * YN,
const int N, const DLReal * X, const int XS, DLReal * Y);
/* Valore della B spline cubica di tipo Catmull Rom nel punto X */
DLReal B3CRSplineValue(const DLReal * XN, const DLReal * YN,
const int N, const DLReal X);
/* Valore della B spline cubica di tipo Catmull Rom nei punti X */
/* X deve essere un array crescente strettamente monotonico */
void AB3CRSplineValue(const DLReal * XN, const DLReal * YN,
const int N, const DLReal * X, const int XS, DLReal * Y);
/* Interpolazione su scala lineare tramite B spline cubica
uniforme con riparametrizzazione arc length tramite B spline
cubica Catmull-Rom interpolante */
Boolean AB3CRMSplineValue(const DLReal * XN, const DLReal * YN,
const int N, const DLReal * X, const int XS, DLReal * Y);
/* Interpolazione su scala lineare tramite
Hermite spline cubica monotonica */
void APCHIPSplineValue(const DLReal * XN, const DLReal * YN,
const int N, const DLReal * X, const int XS, DLReal * Y);
/* Interpolazione su scala lineare tramite B spline cubica
uniforme con riparametrizzazione arc length tramite spline
cubica Hermite monotonica */
Boolean AB3HSMSplineValue(const DLReal * XN, const DLReal * YN,
const int N, const DLReal * X, const int XS, DLReal * Y);
/* Definizione tipo spline da utilizzare */
typedef enum
{
CSLLinear, /* Lineare */
CSLCSpline, /* Spline cubica interpolante classica, classe C2, non monotonica */
CSLBSpline, /* B Spline cubica approssimante, classe C2, non interpolante */
CSLCRSpline, /* CatmullRom, interpolante, non monotonica */
CSLHSSpline /* Hermite spline, interpolante, monotonica (PCHIP) */
}
CSLSplineType;
/* Definizione tipo asse da utilizzare */
typedef enum
{
CSLLinXLinY,
CSLLogXLinY,
CSLLinXLogY,
CSLLogXLogY
}
CSLAxisType;
/* Funzione generica interpolazione */
/* Nel caso si utilizzi un asse logaritmico i valori su tale
asse devono essere strettamente maggiori di 0 */
Boolean CSLASplineValue(const DLReal * XN, const DLReal * YN,
const int N, const DLReal * X, const int XS, DLReal * Y,
const CSLSplineType SplineType, const CSLAxisType AxisType);
/* Funzione generica interpolazione, versione complessa */
/* Nel caso si utilizzi un asse logaritmico i valori di ampiezza
su tale asse devono essere strettamente maggiori di 0.
I valori di fase vengono sempre considerati su ascissa lineare */
Boolean CSLCASplineValue(const DLReal * XN, const DLReal * MN,
const DLReal * PN, const int N, const DLReal * X, const int XS,
DLComplex * Y, const CSLSplineType SplineType, const CSLAxisType AxisType);
#endif
drc-3.2.2/source/fft.h 0000644 0000764 0000145 00000006554 13162156312 013513 0 ustar denis itadm /****************************************************************************
DRC: Digital Room Correction
Copyright (C) 2002, 2003 Denis Sbragion
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
You can contact the author on Internet at the following address:
d.sbragion@neomerica.it
****************************************************************************/
/****************************************************************************
Progetto : DSP Library.
File : Fft.h
Autore : Sbragion Denis
Descrizione : Funzioni per fft, ifft etc.
Revisioni :
16/10/93 : Prima stesura.
****************************************************************************/
#ifndef Fft_h
#define Fft_h
#include "boolean.h"
#include "dsplib.h"
// Ritorna la potenza N-esima di X
// Complessita` : O(log2(N)).
DLComplex Power(DLComplex X,unsigned int N);
// Ritorna la J-esima radice N-esima dell' unita`.
// La prima ha indice 0, l' ultima N-1, poi si ripetono ciclicamente.
DLComplex UnitRoot(unsigned int I,unsigned int N);
// Ritorna il primo divisore di N.
unsigned int FirstFactor(unsigned int N);
// Fft e IFft a radice 2 dell' array P di lunghezza N
// N deve essere una potenza di 2
// Complessita` : O(N*log2(N)).
void Radix2Fft(DLComplex P[],unsigned int N);
void Radix2IFft(DLComplex P[],unsigned int N);
// Fft e IFft a radice mista dell' array P di lunghezza N.
// N puo` essere qualsiasi ma se contiene pochi fattori le
// prestazione si riducono enormemente. In particolare per N primo
// la funzione ha complessita` O(N^2) come per Dft() e IDft().
// Se N contiene molti fattori uguali a 2 le prestazioni aumentano.
// Necessita di spazio libero in memoria per un array di complessi di
// lunghezza pari al piu` grande fattore di N.
// Se non vi e` spazio la funzione si arresta e ritorna False, altrimenti
// ritorna True.
// Se N e` una potenza di 2 la versione a radice 2 e` circa il 5%
// piu` veloce.
Boolean Fft(DLComplex P[],unsigned int N);
Boolean IFft(DLComplex P[],unsigned int N);
// Valutazione del polinomio P nel punto X col metodo di Horner
// Il polinomio e` considerato nella forma :
// P[0] + P[1]*X + P[2]*X^2 + ... + P[N-1]*X^(N-1)
// Complessita` : O(N).
DLComplex PolyEval(DLComplex P[],unsigned int N,DLComplex X);
// Dft e IDft del polinomio P (Valutazione nelle radici dell'unita `).
// Richiede spazio in memoria per almemo N complessi. Se l' allocazione
// non ha sucesso ritorna False altrimenti ritorna True;
// Complessita` : O(N^2).
Boolean Dft(DLComplex P[],unsigned int N);
Boolean IDft(DLComplex P[],unsigned int N);
#endif
/***************************************************************************/
drc-3.2.2/source/config.h 0000644 0000764 0000145 00000000170 13164704745 014200 0 ustar denis itadm /* Dummy config.h file */
/* Macro needed by the GSL FFT library */
#define RETURN_IF_NULL(x) if (!x) { return ; }
drc-3.2.2/source/test/ 0000755 0000764 0000145 00000000000 13165107361 013533 5 ustar denis itadm drc-3.2.2/source/test/cfgtest.sh 0000644 0000764 0000145 00000017666 13163131545 015545 0 ustar denis itadm # General DRC configuration testing.
# This file need the DRC executable to be either in the
# current path or in the current directory.
# It also needs a dirac.pcm file with a Dirac delta few seconds long in it.
# This could be created in octave with:
# dcir = zeros(2^18,1);
# dcir(round(length(dcir) / 2)) = 1.0;
# savepcm(dcir,'..\..\test\dirac.pcm');
# 44.1 kHz
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/44.1 kHz/flat-44.1.txt" --PSPointsFile="../target/44.1 kHz/flat-44.1.txt" --PSOutFile=dxp-erb-44.1.pcm --MSOutFile=dmp-erb-44.1.pcm --TCOutFile=dtc-erb-44.1.pcm "../config/44.1 kHz/erb-44.1.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/44.1 kHz/flat-44.1.txt" --PSPointsFile="../target/44.1 kHz/flat-44.1.txt" --PSOutFile=dxp-minimal-44.1.pcm --MSOutFile=dmp-minimal-44.1.pcm --TCOutFile=dtc-minimal-44.1.pcm "../config/44.1 kHz/minimal-44.1.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/44.1 kHz/flat-44.1.txt" --PSPointsFile="../target/44.1 kHz/flat-44.1.txt" --PSOutFile=dxp-soft-44.1.pcm --MSOutFile=dmp-soft-44.1.pcm --TCOutFile=dtc-soft-44.1.pcm "../config/44.1 kHz/soft-44.1.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/44.1 kHz/flat-44.1.txt" --PSPointsFile="../target/44.1 kHz/flat-44.1.txt" --PSOutFile=dxp-normal-44.1.pcm --MSOutFile=dmp-normal-44.1.pcm --TCOutFile=dtc-normal-44.1.pcm "../config/44.1 kHz/normal-44.1.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/44.1 kHz/flat-44.1.txt" --PSPointsFile="../target/44.1 kHz/flat-44.1.txt" --PSOutFile=dxp-strong-44.1.pcm --MSOutFile=dmp-strong-44.1.pcm --TCOutFile=dtc-strong-44.1.pcm "../config/44.1 kHz/strong-44.1.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/44.1 kHz/flat-44.1.txt" --PSPointsFile="../target/44.1 kHz/flat-44.1.txt" --PSOutFile=dxp-extreme-44.1.pcm --MSOutFile=dmp-extreme-44.1.pcm --TCOutFile=dtc-extreme-44.1.pcm "../config/44.1 kHz/extreme-44.1.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/44.1 kHz/flat-44.1.txt" --PSPointsFile="../target/44.1 kHz/flat-44.1.txt" --PSOutFile=dxp-insane-44.1.pcm --MSOutFile=dmp-insane-44.1.pcm --TCOutFile=dtc-insane-44.1.pcm "../config/44.1 kHz/insane-44.1.drc"
# 48.0 kHz
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/48.0 kHz/flat-48.0.txt" --PSPointsFile="../target/48.0 kHz/flat-48.0.txt" --PSOutFile=dxp-erb-48.0.pcm --MSOutFile=dmp-erb-48.0.pcm --TCOutFile=dtc-erb-48.0.pcm "../config/48.0 kHz/erb-48.0.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/48.0 kHz/flat-48.0.txt" --PSPointsFile="../target/48.0 kHz/flat-48.0.txt" --PSOutFile=dxp-minimal-48.0.pcm --MSOutFile=dmp-minimal-48.0.pcm --TCOutFile=dtc-minimal-48.0.pcm "../config/48.0 kHz/minimal-48.0.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/48.0 kHz/flat-48.0.txt" --PSPointsFile="../target/48.0 kHz/flat-48.0.txt" --PSOutFile=dxp-soft-48.0.pcm --MSOutFile=dmp-soft-48.0.pcm --TCOutFile=dtc-soft-48.0.pcm "../config/48.0 kHz/soft-48.0.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/48.0 kHz/flat-48.0.txt" --PSPointsFile="../target/48.0 kHz/flat-48.0.txt" --PSOutFile=dxp-normal-48.0.pcm --MSOutFile=dmp-normal-48.0.pcm --TCOutFile=dtc-normal-48.0.pcm "../config/48.0 kHz/normal-48.0.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/48.0 kHz/flat-48.0.txt" --PSPointsFile="../target/48.0 kHz/flat-48.0.txt" --PSOutFile=dxp-strong-48.0.pcm --MSOutFile=dmp-strong-48.0.pcm --TCOutFile=dtc-strong-48.0.pcm "../config/48.0 kHz/strong-48.0.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/48.0 kHz/flat-48.0.txt" --PSPointsFile="../target/48.0 kHz/flat-48.0.txt" --PSOutFile=dxp-extreme-48.0.pcm --MSOutFile=dmp-extreme-48.0.pcm --TCOutFile=dtc-extreme-48.0.pcm "../config/48.0 kHz/extreme-48.0.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/48.0 kHz/flat-48.0.txt" --PSPointsFile="../target/48.0 kHz/flat-48.0.txt" --PSOutFile=dxp-insane-48.0.pcm --MSOutFile=dmp-insane-48.0.pcm --TCOutFile=dtc-insane-48.0.pcm "../config/48.0 kHz/insane-48.0.drc"
# 88.2 kHz
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/88.2 kHz/flat-88.2.txt" --PSPointsFile="../target/88.2 kHz/flat-88.2.txt" --PSOutFile=dxp-erb-88.2.pcm --MSOutFile=dmp-erb-88.2.pcm --TCOutFile=dtc-erb-88.2.pcm "../config/88.2 kHz/erb-88.2.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/88.2 kHz/flat-88.2.txt" --PSPointsFile="../target/88.2 kHz/flat-88.2.txt" --PSOutFile=dxp-minimal-88.2.pcm --MSOutFile=dmp-minimal-88.2.pcm --TCOutFile=dtc-minimal-88.2.pcm "../config/88.2 kHz/minimal-88.2.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/88.2 kHz/flat-88.2.txt" --PSPointsFile="../target/88.2 kHz/flat-88.2.txt" --PSOutFile=dxp-soft-88.2.pcm --MSOutFile=dmp-soft-88.2.pcm --TCOutFile=dtc-soft-88.2.pcm "../config/88.2 kHz/soft-88.2.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/88.2 kHz/flat-88.2.txt" --PSPointsFile="../target/88.2 kHz/flat-88.2.txt" --PSOutFile=dxp-normal-88.2.pcm --MSOutFile=dmp-normal-88.2.pcm --TCOutFile=dtc-normal-88.2.pcm "../config/88.2 kHz/normal-88.2.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/88.2 kHz/flat-88.2.txt" --PSPointsFile="../target/88.2 kHz/flat-88.2.txt" --PSOutFile=dxp-strong-88.2.pcm --MSOutFile=dmp-strong-88.2.pcm --TCOutFile=dtc-strong-88.2.pcm "../config/88.2 kHz/strong-88.2.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/88.2 kHz/flat-88.2.txt" --PSPointsFile="../target/88.2 kHz/flat-88.2.txt" --PSOutFile=dxp-extreme-88.2.pcm --MSOutFile=dmp-extreme-88.2.pcm --TCOutFile=dtc-extreme-88.2.pcm "../config/88.2 kHz/extreme-88.2.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/88.2 kHz/flat-88.2.txt" --PSPointsFile="../target/88.2 kHz/flat-88.2.txt" --PSOutFile=dxp-insane-88.2.pcm --MSOutFile=dmp-insane-88.2.pcm --TCOutFile=dtc-insane-88.2.pcm "../config/88.2 kHz/insane-88.2.drc"
# 96.0 kHz
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/96.0 kHz/flat-96.0.txt" --PSPointsFile="../target/96.0 kHz/flat-96.0.txt" --PSOutFile=dxp-erb-96.0.pcm --MSOutFile=dmp-erb-96.0.pcm --TCOutFile=dtc-erb-96.0.pcm "../config/96.0 kHz/erb-96.0.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/96.0 kHz/flat-96.0.txt" --PSPointsFile="../target/96.0 kHz/flat-96.0.txt" --PSOutFile=dxp-minimal-96.0.pcm --MSOutFile=dmp-minimal-96.0.pcm --TCOutFile=dtc-minimal-96.0.pcm "../config/96.0 kHz/minimal-96.0.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/96.0 kHz/flat-96.0.txt" --PSPointsFile="../target/96.0 kHz/flat-96.0.txt" --PSOutFile=dxp-soft-96.0.pcm --MSOutFile=dmp-soft-96.0.pcm --TCOutFile=dtc-soft-96.0.pcm "../config/96.0 kHz/soft-96.0.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/96.0 kHz/flat-96.0.txt" --PSPointsFile="../target/96.0 kHz/flat-96.0.txt" --PSOutFile=dxp-normal-96.0.pcm --MSOutFile=dmp-normal-96.0.pcm --TCOutFile=dtc-normal-96.0.pcm "../config/96.0 kHz/normal-96.0.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/96.0 kHz/flat-96.0.txt" --PSPointsFile="../target/96.0 kHz/flat-96.0.txt" --PSOutFile=dxp-strong-96.0.pcm --MSOutFile=dmp-strong-96.0.pcm --TCOutFile=dtc-strong-96.0.pcm "../config/96.0 kHz/strong-96.0.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/96.0 kHz/flat-96.0.txt" --PSPointsFile="../target/96.0 kHz/flat-96.0.txt" --PSOutFile=dxp-extreme-96.0.pcm --MSOutFile=dmp-extreme-96.0.pcm --TCOutFile=dtc-extreme-96.0.pcm "../config/96.0 kHz/extreme-96.0.drc"
./drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="../target/96.0 kHz/flat-96.0.txt" --PSPointsFile="../target/96.0 kHz/flat-96.0.txt" --PSOutFile=dxp-insane-96.0.pcm --MSOutFile=dmp-insane-96.0.pcm --TCOutFile=dtc-insane-96.0.pcm "../config/96.0 kHz/insane-96.0.drc" drc-3.2.2/source/test/cfgtest.bat 0000644 0000764 0000145 00000017722 13163131506 015667 0 ustar denis itadm @echo off
rem General DRC configuration testing.
rem This file need the DRC executable to be either in the
rem current path or in the current directory.
rem It also needs a dirac.pcm file with a Dirac delta few seconds long in it.
rem This could be created in octave with:
rem dcir = zeros(2^18,1);
rem dcir(round(length(dcir) / 2)) = 1.0;
rem savepcm(dcir,'..\..\test\dirac.pcm');
rem 44.1 kHz
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\44.1 kHz\flat-44.1.txt" --PSPointsFile="..\target\44.1 kHz\flat-44.1.txt" --PSOutFile=dxp-erb-44.1.pcm --MSOutFile=dmp-erb-44.1.pcm --TCOutFile=dtc-erb-44.1.pcm "..\config\44.1 kHz\erb-44.1.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\44.1 kHz\flat-44.1.txt" --PSPointsFile="..\target\44.1 kHz\flat-44.1.txt" --PSOutFile=dxp-minimal-44.1.pcm --MSOutFile=dmp-minimal-44.1.pcm --TCOutFile=dtc-minimal-44.1.pcm "..\config\44.1 kHz\minimal-44.1.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\44.1 kHz\flat-44.1.txt" --PSPointsFile="..\target\44.1 kHz\flat-44.1.txt" --PSOutFile=dxp-soft-44.1.pcm --MSOutFile=dmp-soft-44.1.pcm --TCOutFile=dtc-soft-44.1.pcm "..\config\44.1 kHz\soft-44.1.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\44.1 kHz\flat-44.1.txt" --PSPointsFile="..\target\44.1 kHz\flat-44.1.txt" --PSOutFile=dxp-normal-44.1.pcm --MSOutFile=dmp-normal-44.1.pcm --TCOutFile=dtc-normal-44.1.pcm "..\config\44.1 kHz\normal-44.1.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\44.1 kHz\flat-44.1.txt" --PSPointsFile="..\target\44.1 kHz\flat-44.1.txt" --PSOutFile=dxp-strong-44.1.pcm --MSOutFile=dmp-strong-44.1.pcm --TCOutFile=dtc-strong-44.1.pcm "..\config\44.1 kHz\strong-44.1.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\44.1 kHz\flat-44.1.txt" --PSPointsFile="..\target\44.1 kHz\flat-44.1.txt" --PSOutFile=dxp-extreme-44.1.pcm --MSOutFile=dmp-extreme-44.1.pcm --TCOutFile=dtc-extreme-44.1.pcm "..\config\44.1 kHz\extreme-44.1.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\44.1 kHz\flat-44.1.txt" --PSPointsFile="..\target\44.1 kHz\flat-44.1.txt" --PSOutFile=dxp-insane-44.1.pcm --MSOutFile=dmp-insane-44.1.pcm --TCOutFile=dtc-insane-44.1.pcm "..\config\44.1 kHz\insane-44.1.drc"
rem 48.0 kHz
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\48.0 kHz\flat-48.0.txt" --PSPointsFile="..\target\48.0 kHz\flat-48.0.txt" --PSOutFile=dxp-erb-48.0.pcm --MSOutFile=dmp-erb-48.0.pcm --TCOutFile=dtc-erb-48.0.pcm "..\config\48.0 kHz\erb-48.0.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\48.0 kHz\flat-48.0.txt" --PSPointsFile="..\target\48.0 kHz\flat-48.0.txt" --PSOutFile=dxp-minimal-48.0.pcm --MSOutFile=dmp-minimal-48.0.pcm --TCOutFile=dtc-minimal-48.0.pcm "..\config\48.0 kHz\minimal-48.0.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\48.0 kHz\flat-48.0.txt" --PSPointsFile="..\target\48.0 kHz\flat-48.0.txt" --PSOutFile=dxp-soft-48.0.pcm --MSOutFile=dmp-soft-48.0.pcm --TCOutFile=dtc-soft-48.0.pcm "..\config\48.0 kHz\soft-48.0.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\48.0 kHz\flat-48.0.txt" --PSPointsFile="..\target\48.0 kHz\flat-48.0.txt" --PSOutFile=dxp-normal-48.0.pcm --MSOutFile=dmp-normal-48.0.pcm --TCOutFile=dtc-normal-48.0.pcm "..\config\48.0 kHz\normal-48.0.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\48.0 kHz\flat-48.0.txt" --PSPointsFile="..\target\48.0 kHz\flat-48.0.txt" --PSOutFile=dxp-strong-48.0.pcm --MSOutFile=dmp-strong-48.0.pcm --TCOutFile=dtc-strong-48.0.pcm "..\config\48.0 kHz\strong-48.0.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\48.0 kHz\flat-48.0.txt" --PSPointsFile="..\target\48.0 kHz\flat-48.0.txt" --PSOutFile=dxp-extreme-48.0.pcm --MSOutFile=dmp-extreme-48.0.pcm --TCOutFile=dtc-extreme-48.0.pcm "..\config\48.0 kHz\extreme-48.0.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\48.0 kHz\flat-48.0.txt" --PSPointsFile="..\target\48.0 kHz\flat-48.0.txt" --PSOutFile=dxp-insane-48.0.pcm --MSOutFile=dmp-insane-48.0.pcm --TCOutFile=dtc-insane-48.0.pcm "..\config\48.0 kHz\insane-48.0.drc"
rem 88.2 kHz
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\88.2 kHz\flat-88.2.txt" --PSPointsFile="..\target\88.2 kHz\flat-88.2.txt" --PSOutFile=dxp-erb-88.2.pcm --MSOutFile=dmp-erb-88.2.pcm --TCOutFile=dtc-erb-88.2.pcm "..\config\88.2 kHz\erb-88.2.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\88.2 kHz\flat-88.2.txt" --PSPointsFile="..\target\88.2 kHz\flat-88.2.txt" --PSOutFile=dxp-minimal-88.2.pcm --MSOutFile=dmp-minimal-88.2.pcm --TCOutFile=dtc-minimal-88.2.pcm "..\config\88.2 kHz\minimal-88.2.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\88.2 kHz\flat-88.2.txt" --PSPointsFile="..\target\88.2 kHz\flat-88.2.txt" --PSOutFile=dxp-soft-88.2.pcm --MSOutFile=dmp-soft-88.2.pcm --TCOutFile=dtc-soft-88.2.pcm "..\config\88.2 kHz\soft-88.2.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\88.2 kHz\flat-88.2.txt" --PSPointsFile="..\target\88.2 kHz\flat-88.2.txt" --PSOutFile=dxp-normal-88.2.pcm --MSOutFile=dmp-normal-88.2.pcm --TCOutFile=dtc-normal-88.2.pcm "..\config\88.2 kHz\normal-88.2.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\88.2 kHz\flat-88.2.txt" --PSPointsFile="..\target\88.2 kHz\flat-88.2.txt" --PSOutFile=dxp-strong-88.2.pcm --MSOutFile=dmp-strong-88.2.pcm --TCOutFile=dtc-strong-88.2.pcm "..\config\88.2 kHz\strong-88.2.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\88.2 kHz\flat-88.2.txt" --PSPointsFile="..\target\88.2 kHz\flat-88.2.txt" --PSOutFile=dxp-extreme-88.2.pcm --MSOutFile=dmp-extreme-88.2.pcm --TCOutFile=dtc-extreme-88.2.pcm "..\config\88.2 kHz\extreme-88.2.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\88.2 kHz\flat-88.2.txt" --PSPointsFile="..\target\88.2 kHz\flat-88.2.txt" --PSOutFile=dxp-insane-88.2.pcm --MSOutFile=dmp-insane-88.2.pcm --TCOutFile=dtc-insane-88.2.pcm "..\config\88.2 kHz\insane-88.2.drc"
rem 96.0 kHz
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\96.0 kHz\flat-96.0.txt" --PSPointsFile="..\target\96.0 kHz\flat-96.0.txt" --PSOutFile=dxp-erb-96.0.pcm --MSOutFile=dmp-erb-96.0.pcm --TCOutFile=dtc-erb-96.0.pcm "..\config\96.0 kHz\erb-96.0.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\96.0 kHz\flat-96.0.txt" --PSPointsFile="..\target\96.0 kHz\flat-96.0.txt" --PSOutFile=dxp-minimal-96.0.pcm --MSOutFile=dmp-minimal-96.0.pcm --TCOutFile=dtc-minimal-96.0.pcm "..\config\96.0 kHz\minimal-96.0.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\96.0 kHz\flat-96.0.txt" --PSPointsFile="..\target\96.0 kHz\flat-96.0.txt" --PSOutFile=dxp-soft-96.0.pcm --MSOutFile=dmp-soft-96.0.pcm --TCOutFile=dtc-soft-96.0.pcm "..\config\96.0 kHz\soft-96.0.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\96.0 kHz\flat-96.0.txt" --PSPointsFile="..\target\96.0 kHz\flat-96.0.txt" --PSOutFile=dxp-normal-96.0.pcm --MSOutFile=dmp-normal-96.0.pcm --TCOutFile=dtc-normal-96.0.pcm "..\config\96.0 kHz\normal-96.0.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\96.0 kHz\flat-96.0.txt" --PSPointsFile="..\target\96.0 kHz\flat-96.0.txt" --PSOutFile=dxp-strong-96.0.pcm --MSOutFile=dmp-strong-96.0.pcm --TCOutFile=dtc-strong-96.0.pcm "..\config\96.0 kHz\strong-96.0.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\96.0 kHz\flat-96.0.txt" --PSPointsFile="..\target\96.0 kHz\flat-96.0.txt" --PSOutFile=dxp-extreme-96.0.pcm --MSOutFile=dmp-extreme-96.0.pcm --TCOutFile=dtc-extreme-96.0.pcm "..\config\96.0 kHz\extreme-96.0.drc"
drc --BCInFile=dirac.pcm --MCFilterType=M --MCPointsFile="..\target\96.0 kHz\flat-96.0.txt" --PSPointsFile="..\target\96.0 kHz\flat-96.0.txt" --PSOutFile=dxp-insane-96.0.pcm --MSOutFile=dmp-insane-96.0.pcm --TCOutFile=dtc-insane-96.0.pcm "..\config\96.0 kHz\insane-96.0.drc" drc-3.2.2/source/bwprefilt.h 0000644 0000764 0000145 00000003333 13162156312 014722 0 ustar denis itadm /****************************************************************************
DRC: Digital Room Correction
Copyright (C) 2002, 2003 Denis Sbragion
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
You can contact the author on Internet at the following address:
d.sbragion@neomerica.it
****************************************************************************/
/* Prefiltratura a bande di un segnale */
#ifndef BWPreFilt_h
#define BWPreFilt_h
/* Inclusioni */
#include "dsplib.h"
#include "dspwind.h"
/* Tipo di curva parametrica da utilizzare */
typedef enum { BWPProportional, BWPBilinear } BWPPrefilteringType;
/* Calcolo potenza intera di un numero */
DLReal IntPow(DLReal X,unsigned int N);
/* Prefiltratura a bande di un segnale */
void BWPreFilt(const DLReal * InImp, const int IBS, const int FBS,
const int FilterLen, const int OctaveSplit, const DLReal WindowExponent,
const int SampleFreq, const DLReal FilterBegin, const DLReal FilterEnd,
const int WindowGap, DLReal * OutImp,
const WindowType WType, const BWPPrefilteringType BWPType);
#endif
drc-3.2.2/source/glsweep.layout 0000644 0000764 0000145 00000000554 13165107243 015464 0 ustar denis itadm
drc-3.2.2/source/MLeaks/ 0000755 0000764 0000145 00000000000 13165107360 013727 5 ustar denis itadm drc-3.2.2/source/MLeaks/_nvwa.h 0000644 0000764 0000145 00000005332 12615050533 015213 0 ustar denis itadm // -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
// vim:tabstop=4:shiftwidth=4:expandtab:
/*
* Copyright (C) 2013-2015 Wu Yongwei
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute
* it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must
* not claim that you wrote the original software. If you use this
* software in a product, an acknowledgement in the product
* documentation would be appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must
* not be misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source
* distribution.
*
* This file is part of Stones of Nvwa:
* http://sourceforge.net/projects/nvwa
*
*/
/**
* @file _nvwa.h
*
* Common definitions for preprocessing.
*
* @date 2015-10-28
*/
#ifndef NVWA_NVWA_H
#define NVWA_NVWA_H
/**
* @namespace nvwa
* Namespace of the nvwa project. Most functions and global variables
* are defined in this namespace.
*/
#ifndef NVWA_USE_NAMESPACE
#ifdef __cplusplus
#define NVWA_USE_NAMESPACE 1
#else
#define NVWA_USE_NAMESPACE 0
#endif // __cplusplus
#endif // NVWA_USE_NAMESPACE
#if NVWA_USE_NAMESPACE
#define NVWA_NAMESPACE_BEGIN namespace nvwa {
#define NVWA_NAMESPACE_END }
#define NVWA nvwa
#else // NVWA_USE_NAMESPACE
#define NVWA_NAMESPACE_BEGIN
#define NVWA_NAMESPACE_END
#define NVWA
#endif // NVWA_USE_NAMESPACE
#ifndef NVWA_APPLE
#if defined(__APPLE__) && defined(__MACH__)
#define NVWA_APPLE 1
#else
#define NVWA_APPLE 0
#endif
#endif // NVWA_APPLE
#ifndef NVWA_CYGWIN
#if defined(__CYGWIN__)
#define NVWA_CYGWIN 1
#else
#define NVWA_CYGWIN 0
#endif
#endif // NVWA_CYGWIN
#ifndef NVWA_LINUX
#if defined(__linux__) || defined(__linux)
#define NVWA_LINUX 1
#else
#define NVWA_LINUX 0
#endif
#endif // NVWA_LINUX
#ifndef NVWA_UNIX
#if defined(__unix__) || defined(__unix) || NVWA_APPLE
#define NVWA_UNIX 1
#else
#define NVWA_UNIX 0
#endif
#endif // NVWA_UNIX
#ifndef NVWA_WIN32
#if defined(_WIN32)
#define NVWA_WIN32 1
#else
#define NVWA_WIN32 0
#endif
#endif // NVWA_WIN32
#ifndef NVWA_WINDOWS
#if NVWA_CYGWIN || NVWA_WIN32
#define NVWA_WINDOWS 1
#else
#define NVWA_WINDOWS 0
#endif
#endif // NVWA_WINDOWS
#endif // NVWA_NVWA_H
drc-3.2.2/source/MLeaks/debug_new.cpp 0000644 0000764 0000145 00000110126 13000113247 016360 0 ustar denis itadm // -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
// vim:tabstop=4:shiftwidth=4:expandtab:
/*
* Copyright (C) 2004-2016 Wu Yongwei
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute
* it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must
* not claim that you wrote the original software. If you use this
* software in a product, an acknowledgement in the product
* documentation would be appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must
* not be misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source
* distribution.
*
* This file is part of Stones of Nvwa:
* http://sourceforge.net/projects/nvwa
*
*/
/**
* @file debug_new.cpp
*
* Implementation of debug versions of new and delete to check leakage.
*
* @date 2016-10-14
*/
#include // std::bad_alloc/nothrow_t
#include // assert
#include // fprintf/stderr
#include // abort
#include // strcpy/strncpy/sprintf
#include "_nvwa.h" // NVWA macros
#if NVWA_UNIX
#include // alloca
#endif
#if NVWA_WIN32
#include // alloca
#endif
#if NVWA_LINUX || NVWA_APPLE
#include // backtrace
#endif
#if NVWA_WINDOWS
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include // CaptureStackBackTrace
#endif
#include "c++11.h" // _NOEXCEPT/_NULLPTR
#include "fast_mutex.h" // nvwa::fast_mutex
#include "static_assert.h" // STATIC_ASSERT
#undef _DEBUG_NEW_EMULATE_MALLOC
#undef _DEBUG_NEW_REDEFINE_NEW
/**
* Macro to indicate whether redefinition of \c new is wanted. Here it
* is defined to \c 0 to disable the redefinition of \c new.
*/
#define _DEBUG_NEW_REDEFINE_NEW 0
#include "debug_new.h"
#if !_FAST_MUTEX_CHECK_INITIALIZATION && !defined(_NOTHREADS)
#error "_FAST_MUTEX_CHECK_INITIALIZATION not set: check_leaks may not work"
#endif
/**
* @def _DEBUG_NEW_ALIGNMENT
*
* The alignment requirement of allocated memory blocks. It must be a
* power of two.
*/
#ifndef _DEBUG_NEW_ALIGNMENT
#define _DEBUG_NEW_ALIGNMENT 16
#endif
/**
* @def _DEBUG_NEW_CALLER_ADDRESS
*
* The expression to return the caller address. nvwa#print_position will
* later on use this address to print the position information of memory
* operation points.
*/
#ifndef _DEBUG_NEW_CALLER_ADDRESS
#ifdef __GNUC__
#define _DEBUG_NEW_CALLER_ADDRESS __builtin_return_address(0)
#else
#define _DEBUG_NEW_CALLER_ADDRESS _NULLPTR
#endif
#endif
/**
* @def _DEBUG_NEW_ERROR_ACTION
*
* The action to take when an error occurs. The default behaviour is to
* call \e abort, unless \c _DEBUG_NEW_ERROR_CRASH is defined, in which
* case a segmentation fault will be triggered instead (which can be
* useful on platforms like Windows that do not generate a core dump
* when \e abort is called).
*/
#ifndef _DEBUG_NEW_ERROR_ACTION
#ifndef _DEBUG_NEW_ERROR_CRASH
#define _DEBUG_NEW_ERROR_ACTION abort()
#else
#define _DEBUG_NEW_ERROR_ACTION do { *((char*)0) = 0; abort(); } while (0)
#endif
#endif
/**
* @def _DEBUG_NEW_FILENAME_LEN
*
* The length of file name stored if greater than zero. If it is zero,
* only a const char pointer will be stored. Currently the default
* value is non-zero (thus to copy the file name) on non-Windows
* platforms, because I once found that the exit leakage check could not
* access the address of the file name on Linux (in my case, a core dump
* occurred when check_leaks tried to access the file name in a shared
* library after a \c SIGINT). This value makes the size of
* new_ptr_list_t \c 64 on non-Windows 32-bit platforms (w/o stack
* backtrace).
*/
#ifndef _DEBUG_NEW_FILENAME_LEN
#if NVWA_WINDOWS
#define _DEBUG_NEW_FILENAME_LEN 0
#else
#define _DEBUG_NEW_FILENAME_LEN 44
#endif
#endif
/**
* @def _DEBUG_NEW_PROGNAME
*
* The program (executable) name to be set at compile time. It is
* better to assign the full program path to nvwa#new_progname in \e main
* (at run time) than to use this (compile-time) macro, but this macro
* serves well as a quick hack. Note also that double quotation marks
* need to be used around the program name, i.e., one should specify a
* command-line option like -D_DEBUG_NEW_PROGNAME=\\"a.out\"
* in \e bash, or -D_DEBUG_NEW_PROGNAME=\\"a.exe\" in the
* Windows command prompt.
*/
#ifndef _DEBUG_NEW_PROGNAME
#define _DEBUG_NEW_PROGNAME _NULLPTR
#endif
/**
* @def _DEBUG_NEW_REMEMBER_STACK_TRACE
*
* Macro to indicate whether stack traces of allocations should be
* included in NVWA allocation information and be printed while leaks
* are reported. Useful to pinpoint leaks caused by strdup and other
* custom allocation functions. It is also very helpful in filtering
* out false positives caused by internal STL/C runtime operations. It
* is off by default because it is quite memory heavy. Set it to \c 1
* to make all allocations have stack trace attached, or set to \c 2 to
* make only allocations that lack calling source code information (file
* and line) have the stack trace attached.
*/
#ifndef _DEBUG_NEW_REMEMBER_STACK_TRACE
#define _DEBUG_NEW_REMEMBER_STACK_TRACE 0
#endif
/**
* @def _DEBUG_NEW_STD_OPER_NEW
*
* Macro to indicate whether the standard-conformant behaviour of
* operator new is wanted. It is on by default now, but
* the user may set it to \c 0 to revert to the old behaviour.
*/
#ifndef _DEBUG_NEW_STD_OPER_NEW
#define _DEBUG_NEW_STD_OPER_NEW 1
#endif
/**
* @def _DEBUG_NEW_TAILCHECK
*
* Macro to indicate whether a writing-past-end check will be performed.
* Define it to a positive integer as the number of padding bytes at the
* end of a memory block for checking.
*/
#ifndef _DEBUG_NEW_TAILCHECK
#define _DEBUG_NEW_TAILCHECK 0
#endif
/**
* @def _DEBUG_NEW_TAILCHECK_CHAR
*
* Value of the padding bytes at the end of a memory block.
*/
#ifndef _DEBUG_NEW_TAILCHECK_CHAR
#define _DEBUG_NEW_TAILCHECK_CHAR 0xCC
#endif
/**
* @def _DEBUG_NEW_USE_ADDR2LINE
*
* Whether to use \e addr2line to convert a caller address to file/line
* information. Defining it to a non-zero value will enable the
* conversion (automatically done if GCC is detected). Defining it to
* zero will disable the conversion.
*/
#ifndef _DEBUG_NEW_USE_ADDR2LINE
#ifdef __GNUC__
#define _DEBUG_NEW_USE_ADDR2LINE 1
#else
#define _DEBUG_NEW_USE_ADDR2LINE 0
#endif
#endif
#ifdef _MSC_VER
#pragma warning(disable: 4074) // #pragma init_seg(compiler) used
#pragma warning(disable: 4290) // C++ exception specification ignored
#if _MSC_VER >= 1400 // Visual Studio 2005 or later
#pragma warning(disable: 4996) // Use the `unsafe' strncpy
#endif
#pragma init_seg(compiler)
#endif
/**
* Gets the aligned value of memory block size.
*/
#define ALIGN(s) \
(((s) + _DEBUG_NEW_ALIGNMENT - 1) & ~(_DEBUG_NEW_ALIGNMENT - 1))
NVWA_NAMESPACE_BEGIN
/**
* The platform memory alignment. The current value works well in
* platforms I have tested: Windows XP, Windows 7 x64, and Mac OS X
* Leopard. It may be smaller than the real alignment, but must be
* bigger than \c sizeof(size_t) for it work. nvwa#debug_new_recorder
* uses it to detect misaligned pointer returned by `new
* NonPODType[size]'.
*/
const size_t PLATFORM_MEM_ALIGNMENT = sizeof(size_t) * 2;
/**
* Structure to store the position information where \c new occurs.
*/
struct new_ptr_list_t
{
new_ptr_list_t* next; ///< Pointer to the next memory block
new_ptr_list_t* prev; ///< Pointer to the previous memory block
size_t size; ///< Size of the memory block
union
{
#if _DEBUG_NEW_FILENAME_LEN == 0
const char* file; ///< Pointer to the file name of the caller
#else
char file[_DEBUG_NEW_FILENAME_LEN]; ///< File name of the caller
#endif
void* addr; ///< Address of the caller to \e new
};
unsigned line :31; ///< Line number of the caller; or \c 0
unsigned is_array:1; ///< Non-zero iff new[] is used
#if _DEBUG_NEW_REMEMBER_STACK_TRACE
void** stacktrace; ///< Pointer to stack trace information
#endif
unsigned magic; ///< Magic number for error detection
};
/**
* Definition of the constant magic number used for error detection.
*/
static const unsigned DEBUG_NEW_MAGIC = 0x4442474E;
/**
* The extra memory allocated by operator new.
*/
static const int ALIGNED_LIST_ITEM_SIZE = ALIGN(sizeof(new_ptr_list_t));
/**
* List of all new'd pointers.
*/
static new_ptr_list_t new_ptr_list = {
&new_ptr_list,
&new_ptr_list,
0,
{
#if _DEBUG_NEW_FILENAME_LEN == 0
_NULLPTR
#else
""
#endif
},
0,
0,
#if _DEBUG_NEW_REMEMBER_STACK_TRACE
_NULLPTR,
#endif
DEBUG_NEW_MAGIC
};
/**
* The mutex guard to protect simultaneous access to the pointer list.
*/
static fast_mutex new_ptr_lock;
/**
* The mutex guard to protect simultaneous output to #new_output_fp.
*/
static fast_mutex new_output_lock;
/**
* Total memory allocated in bytes.
*/
static size_t total_mem_alloc = 0;
/**
* Flag to control whether nvwa#check_leaks will be automatically called
* on program exit.
*/
bool new_autocheck_flag = true;
/**
* Flag to control whether verbose messages are output.
*/
bool new_verbose_flag = false;
/**
* Pointer to the output stream. The default output is \e stderr, and
* one may change it to a user stream if needed (say, #new_verbose_flag
* is \c true and there are a lot of (de)allocations).
*/
FILE* new_output_fp = stderr;
/**
* Pointer to the program name. Its initial value is the macro
* #_DEBUG_NEW_PROGNAME. You should try to assign the program path to
* it early in your application. Assigning argv[0] to it
* in \e main is one way. If you use \e bash or \e ksh (or similar),
* the following statement is probably what you want:
* `new_progname = getenv("_");'.
*/
const char* new_progname = _DEBUG_NEW_PROGNAME;
/**
* Pointer to the callback used to print the stack backtrace in case of
* a memory problem. A null value causes the default stack trace
* printing routine to be used.
*/
stacktrace_print_callback_t stacktrace_print_callback = _NULLPTR;
/**
* Pointer to the callback used to filter out false positives from leak
* reports. A null value means the lack of filtering.
*/
leak_whitelist_callback_t leak_whitelist_callback = _NULLPTR;
#if _DEBUG_NEW_USE_ADDR2LINE
/**
* Tries printing the position information from an instruction address.
* This is the version that uses \e addr2line.
*
* @param addr the instruction address to convert and print
* @return \c true if the address is converted successfully (and
* the result is printed); \c false if no useful
* information is got (and nothing is printed)
*/
static bool print_position_from_addr(const void* addr)
{
static const void* last_addr = _NULLPTR;
static char last_info[256] = "";
if (addr == last_addr)
{
if (last_info[0] == '\0')
return false;
fprintf(new_output_fp, "%s", last_info);
return true;
}
if (new_progname)
{
#if NVWA_APPLE
const char addr2line_cmd[] = "atos -o ";
#else
const char addr2line_cmd[] = "addr2line -e ";
#endif
#if NVWA_WINDOWS
const int exeext_len = 4;
#else
const int exeext_len = 0;
#endif
#if NVWA_UNIX && !NVWA_CYGWIN
const char ignore_err[] = " 2>/dev/null";
#elif NVWA_CYGWIN || \
(NVWA_WIN32 && defined(WINVER) && WINVER >= 0x0500)
const char ignore_err[] = " 2>nul";
#else
const char ignore_err[] = "";
#endif
char* cmd = (char*)alloca(strlen(new_progname)
+ exeext_len
+ sizeof addr2line_cmd - 1
+ sizeof ignore_err - 1
+ sizeof(void*) * 2
+ 4 /* SP + "0x" + null */);
strcpy(cmd, addr2line_cmd);
strcpy(cmd + sizeof addr2line_cmd - 1, new_progname);
size_t len = strlen(cmd);
#if NVWA_WINDOWS
if (len <= 4
|| (strcmp(cmd + len - 4, ".exe") != 0 &&
strcmp(cmd + len - 4, ".EXE") != 0))
{
strcpy(cmd + len, ".exe");
len += 4;
}
#endif
sprintf(cmd + len, " %p%s", addr, ignore_err);
FILE* fp = popen(cmd, "r");
if (fp)
{
char buffer[sizeof last_info] = "";
len = 0;
if (fgets(buffer, sizeof buffer, fp))
{
len = strlen(buffer);
if (buffer[len - 1] == '\n')
buffer[--len] = '\0';
}
int res = pclose(fp);
// Display the file/line information only if the command
// is executed successfully and the output points to a
// valid position, but the result will be cached if only
// the command is executed successfully.
if (res == 0 && len > 0)
{
last_addr = addr;
if (buffer[len - 1] == '0' && buffer[len - 2] == ':')
last_info[0] = '\0';
else
{
fprintf(new_output_fp, "%s", buffer);
strcpy(last_info, buffer);
return true;
}
}
}
}
return false;
}
#else
/**
* Tries printing the position information from an instruction address.
* This is the stub version that does nothing at all.
*
* @return \c false always
*/
static bool print_position_from_addr(const void*)
{
return false;
}
#endif // _DEBUG_NEW_USE_ADDR2LINE
/**
* Prints the position information of a memory operation point. When \c
* _DEBUG_NEW_USE_ADDR2LINE is defined to a non-zero value, this
* function will try to convert a given caller address to file/line
* information with \e addr2line.
*
* @param ptr source file name if \e line is non-zero; caller address
* otherwise
* @param line source line number if non-zero; indication that \e ptr
* is the caller address otherwise
*/
static void print_position(const void* ptr, int line)
{
if (line != 0) // Is file/line information present?
{
fprintf(new_output_fp, "%s:%d", (const char*)ptr, line);
}
else if (ptr != _NULLPTR) // Is caller address present?
{
if (!print_position_from_addr(ptr)) // Fail to get source position?
fprintf(new_output_fp, "%p", ptr);
}
else // No information is present
{
fprintf(new_output_fp, "");
}
}
#if _DEBUG_NEW_REMEMBER_STACK_TRACE
/**
* Prints the stack backtrace.
*
* When nvwa#stacktrace_print_callback is not null, it is used for
* printing the stacktrace items. Default implementation of call stack
* printing is very spartan—only stack frame pointers are
* printed—but even that output is still useful. Just do address
* lookup in LLDB etc.
*
* @param stacktrace pointer to the stack trace array
*/
static void print_stacktrace(void** stacktrace)
{
if (stacktrace_print_callback == _NULLPTR)
{
fprintf(new_output_fp, "Stack backtrace:\n");
for (size_t i = 0; stacktrace[i] != _NULLPTR; ++i)
fprintf(new_output_fp, "%p\n", stacktrace[i]);
}
else
{
stacktrace_print_callback(new_output_fp, stacktrace);
}
}
#endif
/**
* Checks whether a leak should be ignored. Its runtime performance
* depends on the callback nvwa#leak_whitelist_callback.
*
* @param ptr pointer to a new_ptr_list_t struct
* @return \c true if the leak should be whitelisted; \c false
* otherwise
*/
static bool is_leak_whitelisted(new_ptr_list_t* ptr)
{
if (leak_whitelist_callback == _NULLPTR)
return false;
char const* file = ptr->line != 0 ? ptr->file : _NULLPTR;
int line = ptr->line;
void* addr = ptr->line == 0 ? ptr->addr : _NULLPTR;
#if _DEBUG_NEW_REMEMBER_STACK_TRACE
void** stacktrace = ptr->stacktrace;
#else
void** stacktrace = _NULLPTR;
#endif
return leak_whitelist_callback(file, line, addr, stacktrace);
}
#if _DEBUG_NEW_TAILCHECK
/**
* Checks whether the padding bytes at the end of a memory block is
* tampered with.
*
* @param ptr pointer to a new_ptr_list_t struct
* @return \c true if the padding bytes are untouched; \c false
* otherwise
*/
static bool check_tail(new_ptr_list_t* ptr)
{
const unsigned char* const tail_ptr = (unsigned char*)ptr +
ALIGNED_LIST_ITEM_SIZE + ptr->size;
for (int i = 0; i < _DEBUG_NEW_TAILCHECK; ++i)
if (tail_ptr[i] != _DEBUG_NEW_TAILCHECK_CHAR)
return false;
return true;
}
#endif
/**
* Allocates memory and initializes control data.
*
* @param size size of the required memory block
* @param file null-terminated string of the file name
* @param line line number
* @param is_array boolean value whether this is an array operation
* @return pointer to the user-requested memory area; null if
* memory allocation is not successful
*/
static void* alloc_mem(size_t size, const char* file, int line, bool is_array)
{
assert(line >= 0);
#if _DEBUG_NEW_TYPE == 1
STATIC_ASSERT(_DEBUG_NEW_ALIGNMENT >= PLATFORM_MEM_ALIGNMENT,
Alignment_too_small);
#endif
STATIC_ASSERT((_DEBUG_NEW_ALIGNMENT & (_DEBUG_NEW_ALIGNMENT - 1)) == 0,
Alignment_must_be_power_of_two);
STATIC_ASSERT(_DEBUG_NEW_TAILCHECK >= 0, Invalid_tail_check_length);
size_t s = size + ALIGNED_LIST_ITEM_SIZE + _DEBUG_NEW_TAILCHECK;
new_ptr_list_t* ptr = (new_ptr_list_t*)malloc(s);
if (ptr == _NULLPTR)
{
#if _DEBUG_NEW_STD_OPER_NEW
return _NULLPTR;
#else
fast_mutex_autolock lock(new_output_lock);
fprintf(new_output_fp,
"Out of memory when allocating %lu bytes\n",
(unsigned long)size);
fflush(new_output_fp);
_DEBUG_NEW_ERROR_ACTION;
#endif
}
void* usr_ptr = (char*)ptr + ALIGNED_LIST_ITEM_SIZE;
#if _DEBUG_NEW_FILENAME_LEN == 0
ptr->file = file;
#else
if (line)
strncpy(ptr->file, file, _DEBUG_NEW_FILENAME_LEN - 1)
[_DEBUG_NEW_FILENAME_LEN - 1] = '\0';
else
ptr->addr = (void*)file;
#endif
ptr->line = line;
#if _DEBUG_NEW_REMEMBER_STACK_TRACE
ptr->stacktrace = _NULLPTR;
#if _DEBUG_NEW_REMEMBER_STACK_TRACE == 2
if (line == 0)
#endif
{
void* buffer [255];
size_t buffer_length = sizeof(buffer) / sizeof(*buffer);
#if NVWA_UNIX
int stacktrace_length = backtrace(buffer, int(buffer_length));
#endif
#if NVWA_WINDOWS
USHORT stacktrace_length = CaptureStackBackTrace(
0, DWORD(buffer_length), buffer, _NULLPTR);
#endif
size_t stacktrace_size = stacktrace_length * sizeof(void*);
ptr->stacktrace = (void**)malloc(stacktrace_size + sizeof(void*));
if (ptr->stacktrace != _NULLPTR)
{
memcpy(ptr->stacktrace, buffer, stacktrace_size);
ptr->stacktrace[stacktrace_length] = _NULLPTR;
}
}
#endif
ptr->is_array = is_array;
ptr->size = size;
ptr->magic = DEBUG_NEW_MAGIC;
{
fast_mutex_autolock lock(new_ptr_lock);
ptr->prev = new_ptr_list.prev;
ptr->next = &new_ptr_list;
new_ptr_list.prev->next = ptr;
new_ptr_list.prev = ptr;
}
#if _DEBUG_NEW_TAILCHECK
memset((char*)usr_ptr + size, _DEBUG_NEW_TAILCHECK_CHAR,
_DEBUG_NEW_TAILCHECK);
#endif
if (new_verbose_flag)
{
fast_mutex_autolock lock(new_output_lock);
fprintf(new_output_fp,
"new%s: allocated %p (size %lu, ",
is_array ? "[]" : "",
usr_ptr, (unsigned long)size);
if (line != 0)
print_position(ptr->file, ptr->line);
else
print_position(ptr->addr, ptr->line);
fprintf(new_output_fp, ")\n");
}
total_mem_alloc += size;
return usr_ptr;
}
/**
* Frees memory and adjusts pointers.
*
* @param usr_ptr pointer to the previously allocated memory
* @param addr pointer to the caller
* @param is_array flag indicating whether it is invoked by a
* delete[] call
*/
static void free_pointer(void* usr_ptr, void* addr, bool is_array)
{
if (usr_ptr == _NULLPTR)
return;
new_ptr_list_t* ptr =
(new_ptr_list_t*)((char*)usr_ptr - ALIGNED_LIST_ITEM_SIZE);
if (ptr->magic != DEBUG_NEW_MAGIC)
{
{
fast_mutex_autolock lock(new_output_lock);
fprintf(new_output_fp, "delete%s: invalid pointer %p (",
is_array ? "[]" : "", usr_ptr);
print_position(addr, 0);
fprintf(new_output_fp, ")\n");
}
check_mem_corruption();
fflush(new_output_fp);
_DEBUG_NEW_ERROR_ACTION;
}
if (is_array != ptr->is_array)
{
const char* msg;
if (is_array)
msg = "delete[] after new";
else
msg = "delete after new[]";
fast_mutex_autolock lock(new_output_lock);
fprintf(new_output_fp,
"%s: pointer %p (size %lu)\n\tat ",
msg,
(char*)ptr + ALIGNED_LIST_ITEM_SIZE,
(unsigned long)ptr->size);
print_position(addr, 0);
fprintf(new_output_fp, "\n\toriginally allocated at ");
if (ptr->line != 0)
print_position(ptr->file, ptr->line);
else
print_position(ptr->addr, ptr->line);
fprintf(new_output_fp, "\n");
fflush(new_output_fp);
_DEBUG_NEW_ERROR_ACTION;
}
#if _DEBUG_NEW_TAILCHECK
if (!check_tail(ptr))
{
check_mem_corruption();
fflush(new_output_fp);
_DEBUG_NEW_ERROR_ACTION;
}
#endif
{
fast_mutex_autolock lock(new_ptr_lock);
total_mem_alloc -= ptr->size;
ptr->magic = 0;
ptr->prev->next = ptr->next;
ptr->next->prev = ptr->prev;
}
if (new_verbose_flag)
{
fast_mutex_autolock lock(new_output_lock);
fprintf(new_output_fp,
"delete%s: freed %p (size %lu, %lu bytes still allocated)\n",
is_array ? "[]" : "",
(char*)ptr + ALIGNED_LIST_ITEM_SIZE,
(unsigned long)ptr->size, (unsigned long)total_mem_alloc);
}
#if _DEBUG_NEW_REMEMBER_STACK_TRACE
free(ptr->stacktrace);
#endif
free(ptr);
return;
}
/**
* Checks for memory leaks.
*
* @return zero if no leakage is found; the number of leaks otherwise
*/
int check_leaks()
{
int leak_cnt = 0;
int whitelisted_leak_cnt = 0;
fast_mutex_autolock lock_ptr(new_ptr_lock);
fast_mutex_autolock lock_output(new_output_lock);
new_ptr_list_t* ptr = new_ptr_list.next;
while (ptr != &new_ptr_list)
{
const char* const usr_ptr = (char*)ptr + ALIGNED_LIST_ITEM_SIZE;
if (ptr->magic != DEBUG_NEW_MAGIC)
{
fprintf(new_output_fp,
"warning: heap data corrupt near %p\n",
usr_ptr);
}
#if _DEBUG_NEW_TAILCHECK
if (!check_tail(ptr))
{
fprintf(new_output_fp,
"warning: overwritten past end of object at %p\n",
usr_ptr);
}
#endif
if (is_leak_whitelisted(ptr))
{
++whitelisted_leak_cnt;
}
else
{
fprintf(new_output_fp,
"Leaked object at %p (size %lu, ",
usr_ptr,
(unsigned long)ptr->size);
if (ptr->line != 0)
print_position(ptr->file, ptr->line);
else
print_position(ptr->addr, ptr->line);
fprintf(new_output_fp, ")\n");
#if _DEBUG_NEW_REMEMBER_STACK_TRACE
if (ptr->stacktrace != _NULLPTR)
print_stacktrace(ptr->stacktrace);
#endif
}
ptr = ptr->next;
++leak_cnt;
}
if (new_verbose_flag || leak_cnt)
{
if (whitelisted_leak_cnt > 0)
{
fprintf(new_output_fp, "*** %d leaks found (%d whitelisted)\n",
leak_cnt, whitelisted_leak_cnt);
}
else
{
fprintf(new_output_fp, "*** %d leaks found\n", leak_cnt);
}
}
return leak_cnt;
}
/**
* Checks for heap corruption.
*
* @return zero if no problem is found; the number of found memory
* corruptions otherwise
*/
int check_mem_corruption()
{
int corrupt_cnt = 0;
fast_mutex_autolock lock_ptr(new_ptr_lock);
fast_mutex_autolock lock_output(new_output_lock);
fprintf(new_output_fp, "*** Checking for memory corruption: START\n");
for (new_ptr_list_t* ptr = new_ptr_list.next;
ptr != &new_ptr_list;
ptr = ptr->next)
{
const char* const usr_ptr = (char*)ptr + ALIGNED_LIST_ITEM_SIZE;
if (ptr->magic == DEBUG_NEW_MAGIC
#if _DEBUG_NEW_TAILCHECK
&& check_tail(ptr)
#endif
)
continue;
#if _DEBUG_NEW_TAILCHECK
if (ptr->magic != DEBUG_NEW_MAGIC)
{
#endif
fprintf(new_output_fp,
"Heap data corrupt near %p (size %lu, ",
usr_ptr,
(unsigned long)ptr->size);
#if _DEBUG_NEW_TAILCHECK
}
else
{
fprintf(new_output_fp,
"Overwritten past end of object at %p (size %lu, ",
usr_ptr,
(unsigned long)ptr->size);
}
#endif
if (ptr->line != 0)
print_position(ptr->file, ptr->line);
else
print_position(ptr->addr, ptr->line);
fprintf(new_output_fp, ")\n");
#if _DEBUG_NEW_REMEMBER_STACK_TRACE
if (ptr->stacktrace != _NULLPTR)
print_stacktrace(ptr->stacktrace);
#endif
++corrupt_cnt;
}
fprintf(new_output_fp, "*** Checking for memory corruption: %d FOUND\n",
corrupt_cnt);
return corrupt_cnt;
}
/**
* Processes the allocated memory and inserts file/line informatin.
* It will only be done when it can ensure the memory is allocated by
* one of our operator new variants.
*
* @param usr_ptr pointer returned by a new-expression
*/
void debug_new_recorder::_M_process(void* usr_ptr)
{
if (usr_ptr == _NULLPTR)
return;
// In an expression `new NonPODType[size]', the pointer returned is
// not the pointer returned by operator new[], but offset by size_t
// to leave room for the size. It needs to be compensated here.
size_t offset = (char*)usr_ptr - (char*)_NULLPTR;
if (offset % PLATFORM_MEM_ALIGNMENT != 0) {
offset -= sizeof(size_t);
if (offset % PLATFORM_MEM_ALIGNMENT != 0) {
fast_mutex_autolock lock(new_output_lock);
fprintf(new_output_fp,
"warning: memory unaligned; skipping processing (%s:%d)\n",
_M_file, _M_line);
return;
}
usr_ptr = (char*)usr_ptr - sizeof(size_t);
}
new_ptr_list_t* ptr =
(new_ptr_list_t*)((char*)usr_ptr - ALIGNED_LIST_ITEM_SIZE);
if (ptr->magic != DEBUG_NEW_MAGIC || ptr->line != 0)
{
fast_mutex_autolock lock(new_output_lock);
fprintf(new_output_fp,
"warning: debug_new used with placement new (%s:%d)\n",
_M_file, _M_line);
return;
}
if (new_verbose_flag) {
fast_mutex_autolock lock(new_output_lock);
fprintf(new_output_fp,
"info: pointer %p allocated from %s:%d\n",
usr_ptr, _M_file, _M_line);
}
#if _DEBUG_NEW_FILENAME_LEN == 0
ptr->file = _M_file;
#else
strncpy(ptr->file, _M_file, _DEBUG_NEW_FILENAME_LEN - 1)
[_DEBUG_NEW_FILENAME_LEN - 1] = '\0';
#endif
ptr->line = _M_line;
#if _DEBUG_NEW_REMEMBER_STACK_TRACE == 2
free(ptr->stacktrace);
ptr->stacktrace = _NULLPTR;
#endif
}
/**
* Count of source files that use debug_new.
*/
int debug_new_counter::_S_count = 0;
/**
* Constructor to increment the count.
*/
debug_new_counter::debug_new_counter()
{
++_S_count;
}
/**
* Destructor to decrement the count. When the count is zero,
* nvwa#check_leaks will be called.
*/
debug_new_counter::~debug_new_counter()
{
if (--_S_count == 0 && new_autocheck_flag)
if (check_leaks())
{
new_verbose_flag = true;
#if defined(__GNUC__) && __GNUC__ == 3
if (!getenv("GLIBCPP_FORCE_NEW") && !getenv("GLIBCXX_FORCE_NEW"))
fprintf(new_output_fp,
"*** WARNING: GCC 3 is detected, please make sure the environment\n"
" variable GLIBCPP_FORCE_NEW (GCC 3.2 and 3.3) or GLIBCXX_FORCE_NEW\n"
" (GCC 3.4) is defined. Check the README file for details.\n");
#endif
}
}
NVWA_NAMESPACE_END
#if NVWA_USE_NAMESPACE
using namespace nvwa;
#endif // NVWA_USE_NAMESPACE
/**
* Allocates memory with file/line information.
*
* @param size size of the required memory block
* @param file null-terminated string of the file name
* @param line line number
* @return pointer to the memory allocated; or null if memory is
* insufficient (#_DEBUG_NEW_STD_OPER_NEW is 0)
* @throw bad_alloc memory is insufficient (#_DEBUG_NEW_STD_OPER_NEW is 1)
*/
void* operator new(size_t size, const char* file, int line)
{
void* ptr = alloc_mem(size, file, line, false);
#if _DEBUG_NEW_STD_OPER_NEW
if (ptr)
return ptr;
else
throw std::bad_alloc();
#else
return ptr;
#endif
}
/**
* Allocates array memory with file/line information.
*
* @param size size of the required memory block
* @param file null-terminated string of the file name
* @param line line number
* @return pointer to the memory allocated; or null if memory is
* insufficient (#_DEBUG_NEW_STD_OPER_NEW is 0)
* @throw bad_alloc memory is insufficient (#_DEBUG_NEW_STD_OPER_NEW is 1)
*/
void* operator new[](size_t size, const char* file, int line)
{
void* ptr = alloc_mem(size, file, line, true);
#if _DEBUG_NEW_STD_OPER_NEW
if (ptr)
return ptr;
else
throw std::bad_alloc();
#else
return ptr;
#endif
}
/**
* Allocates memory without file/line information.
*
* @param size size of the required memory block
* @return pointer to the memory allocated; or null if memory is
* insufficient (#_DEBUG_NEW_STD_OPER_NEW is 0)
* @throw bad_alloc memory is insufficient (#_DEBUG_NEW_STD_OPER_NEW is 1)
*/
void* operator new(size_t size) throw(std::bad_alloc)
{
return operator new(size, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0);
}
/**
* Allocates array memory without file/line information.
*
* @param size size of the required memory block
* @return pointer to the memory allocated; or null if memory is
* insufficient (#_DEBUG_NEW_STD_OPER_NEW is 0)
* @throw bad_alloc memory is insufficient (#_DEBUG_NEW_STD_OPER_NEW is 1)
*/
void* operator new[](size_t size) throw(std::bad_alloc)
{
return operator new[](size, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0);
}
/**
* Allocates memory with no-throw guarantee.
*
* @param size size of the required memory block
* @return pointer to the memory allocated; or null if memory is
* insufficient
*/
void* operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
{
return alloc_mem(size, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0, false);
}
/**
* Allocates array memory with no-throw guarantee.
*
* @param size size of the required memory block
* @return pointer to the memory allocated; or null if memory is
* insufficient
*/
void* operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
{
return alloc_mem(size, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0, true);
}
/**
* Deallocates memory.
*
* @param ptr pointer to the previously allocated memory
*/
void operator delete(void* ptr) _NOEXCEPT
{
free_pointer(ptr, _DEBUG_NEW_CALLER_ADDRESS, false);
}
/**
* Deallocates array memory.
*
* @param ptr pointer to the previously allocated memory
*/
void operator delete[](void* ptr) _NOEXCEPT
{
free_pointer(ptr, _DEBUG_NEW_CALLER_ADDRESS, true);
}
#if __cplusplus >= 201402L
// GCC under C++14 wants these definitions
void operator delete(void* ptr, size_t) _NOEXCEPT
{
free_pointer(ptr, _DEBUG_NEW_CALLER_ADDRESS, false);
}
void operator delete[](void* ptr, size_t) _NOEXCEPT
{
free_pointer(ptr, _DEBUG_NEW_CALLER_ADDRESS, true);
}
#endif
/**
* Placement deallocation function. For details, please check Section
* 5.3.4 of the C++ 1998 or 2011 Standard.
*
* @param ptr pointer to the previously allocated memory
* @param file null-terminated string of the file name
* @param line line number
*
* @see http://www.csci.csusb.edu/dick/c++std/cd2/expr.html#expr.new
* @see http://wyw.dcweb.cn/leakage.htm
*/
void operator delete(void* ptr, const char* file, int line) _NOEXCEPT
{
if (new_verbose_flag)
{
fast_mutex_autolock lock(new_output_lock);
fprintf(new_output_fp,
"info: exception thrown on initializing object at %p (",
ptr);
print_position(file, line);
fprintf(new_output_fp, ")\n");
}
operator delete(ptr);
}
/**
* Placement deallocation function. For details, please check Section
* 5.3.4 of the C++ 1998 or 2011 Standard.
*
* @param ptr pointer to the previously allocated memory
* @param file null-terminated string of the file name
* @param line line number
*/
void operator delete[](void* ptr, const char* file, int line) _NOEXCEPT
{
if (new_verbose_flag)
{
fast_mutex_autolock lock(new_output_lock);
fprintf(new_output_fp,
"info: exception thrown on initializing objects at %p (",
ptr);
print_position(file, line);
fprintf(new_output_fp, ")\n");
}
operator delete[](ptr);
}
/**
* Placement deallocation function. For details, please check Section
* 5.3.4 of the C++ 1998 or 2011 Standard.
*
* @param ptr pointer to the previously allocated memory
*/
void operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
{
operator delete(ptr, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0);
}
/**
* Placement deallocation function. For details, please check Section
* 5.3.4 of the C++ 1998 or 2011 Standard.
*
* @param ptr pointer to the previously allocated memory
*/
void operator delete[](void* ptr, const std::nothrow_t&) _NOEXCEPT
{
operator delete[](ptr, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0);
}
// This is to make Doxygen happy
#undef _DEBUG_NEW_REMEMBER_STACK_TRACE
#define _DEBUG_NEW_REMEMBER_STACK_TRACE 0
drc-3.2.2/source/MLeaks/LICENCE 0000644 0000764 0000145 00000001612 13067063424 014717 0 ustar denis itadm Copyright (C) 2004-2017 Wu Yongwei
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgement in the product documentation would
be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
drc-3.2.2/source/MLeaks/c++11.h 0000644 0000764 0000145 00000023245 13070424152 014614 0 ustar denis itadm // -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
// vim:tabstop=4:shiftwidth=4:expandtab:
/*
* Copyright (C) 2013-2017 Wu Yongwei
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute
* it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must
* not claim that you wrote the original software. If you use this
* software in a product, an acknowledgement in the product
* documentation would be appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must
* not be misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source
* distribution.
*
* This file is part of Stones of Nvwa:
* http://sourceforge.net/projects/nvwa
*
*/
/**
* @file c++11.h
*
* C++11 feature detection macros and workarounds.
*
* @date 2017-04-03
*/
#ifndef NVWA_CXX11_H
#define NVWA_CXX11_H
// Only Clang provides these macros; they need to be defined as follows
// to get a valid expression in preprocessing by other compilers.
#ifndef __has_extension
#define __has_extension(x) 0
#endif
#ifndef __has_feature
#define __has_feature(x) 0
#endif
#ifndef __has_include
#define __has_include(x) 0
#endif
// Detect whether C++11 mode is on (for GCC and Clang). MSVC does not
// have a special C++11 mode, so it is always on for Visual C++ 2010 and
// later.
#if __cplusplus >= 201103L || \
defined(__GXX_EXPERIMENTAL_CXX0X__) || \
(defined(_MSC_VER) && _MSC_VER >= 1600)
#define NVWA_CXX11_MODE 1
#else
#define NVWA_CXX11_MODE 0
#endif
/* Feature checks */
#if !defined(HAVE_CXX11_ATOMIC)
#if NVWA_CXX11_MODE && \
((__has_include() && !defined(__MINGW32__)) || \
(defined(_MSC_VER) && _MSC_VER >= 1700) || \
(((defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 405) || \
defined(__clang__)) && \
(!defined(__MINGW32__) || defined(_POSIX_THREADS))))
// Note: MinGW GCC, unless built with POSIX threads (as in
// MinGW-builds), does not support atomics as of 4.8.
#define HAVE_CXX11_ATOMIC 1
#else
#define HAVE_CXX11_ATOMIC 0
#endif
#endif
#if !defined(HAVE_CXX11_AUTO_TYPE)
#if NVWA_CXX11_MODE && \
(__has_feature(cxx_auto_type) || \
(defined(_MSC_VER) && _MSC_VER >= 1600) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 404))
#define HAVE_CXX11_AUTO_TYPE 1
#else
#define HAVE_CXX11_AUTO_TYPE 0
#endif
#endif
#if !defined(HAVE_CXX11_DELETED_FUNCTION)
#if NVWA_CXX11_MODE && \
(__has_feature(cxx_deleted_functions) || \
(defined(_MSC_VER) && _MSC_VER >= 1800) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 404))
#define HAVE_CXX11_DELETED_FUNCTION 1
#else
#define HAVE_CXX11_DELETED_FUNCTION 0
#endif
#endif
#if !defined(HAVE_CXX11_EXPLICIT_CONVERSION)
#if NVWA_CXX11_MODE && \
(__has_feature(cxx_explicit_conversions) || \
(defined(_MSC_VER) && _MSC_VER >= 1900) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 405))
#define HAVE_CXX11_EXPLICIT_CONVERSION 1
#else
#define HAVE_CXX11_EXPLICIT_CONVERSION 0
#endif
#endif
#if !defined(HAVE_CXX11_FINAL)
#if NVWA_CXX11_MODE && \
(__has_feature(cxx_override_control) || \
(defined(_MSC_VER) && _MSC_VER >= 1700) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 407))
#define HAVE_CXX11_FINAL 1
#else
#define HAVE_CXX11_FINAL 0
#endif
#endif
#if !defined(HAVE_CXX11_FUTURE)
#if NVWA_CXX11_MODE && \
((__has_include() && !defined(__MINGW32__)) || \
(defined(_MSC_VER) && _MSC_VER >= 1700) || \
(((defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 405) || \
defined(__clang__)) && \
(!defined(__MINGW32__) || defined(_POSIX_THREADS))))
// Note: MinGW GCC, unless built with POSIX threads (as in
// MinGW-builds), does not support futures as of 4.8.
#define HAVE_CXX11_FUTURE 1
#else
#define HAVE_CXX11_FUTURE 0
#endif
#endif
#if !defined(HAVE_CXX11_GENERALIZED_INITIALIZER)
#if NVWA_CXX11_MODE && \
(__has_feature(cxx_generalized_initializers) || \
(defined(_MSC_VER) && _MSC_VER >= 1800) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 404))
#define HAVE_CXX11_GENERALIZED_INITIALIZER 1
#else
#define HAVE_CXX11_GENERALIZED_INITIALIZER 0
#endif
#endif
#if !defined(HAVE_CXX11_LAMBDA)
#if NVWA_CXX11_MODE && \
(__has_feature(cxx_lambdas) || \
(defined(_MSC_VER) && _MSC_VER >= 1600) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 405))
#define HAVE_CXX11_LAMBDA 1
#else
#define HAVE_CXX11_LAMBDA 0
#endif
#endif
#if !defined(HAVE_CXX11_MUTEX)
#if NVWA_CXX11_MODE && \
((__has_include() && !defined(__MINGW32__)) || \
(defined(_MSC_VER) && _MSC_VER >= 1700) || \
(((defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 403) || \
defined(__clang__)) && \
(!defined(__MINGW32__) || defined(_POSIX_THREADS))))
// Note: MinGW GCC, unless built with POSIX threads (as in
// MinGW-builds), does not support std::mutex as of 4.8.
#define HAVE_CXX11_MUTEX 1
#else
#define HAVE_CXX11_MUTEX 0
#endif
#endif
#if !defined(HAVE_CXX11_NOEXCEPT)
#if NVWA_CXX11_MODE && \
(__has_feature(cxx_noexcept) || \
(defined(_MSC_VER) && _MSC_VER >= 1900) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 406))
#define HAVE_CXX11_NOEXCEPT 1
#else
#define HAVE_CXX11_NOEXCEPT 0
#endif
#endif
#if !defined(HAVE_CXX11_NULLPTR)
#if NVWA_CXX11_MODE && \
(__has_feature(cxx_nullptr) || \
(defined(_MSC_VER) && _MSC_VER >= 1600) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 406))
#define HAVE_CXX11_NULLPTR 1
#else
#define HAVE_CXX11_NULLPTR 0
#endif
#endif
#if !defined(HAVE_CXX11_OVERRIDE)
#if NVWA_CXX11_MODE && \
(__has_feature(cxx_override_control) || \
(defined(_MSC_VER) && _MSC_VER >= 1600) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 407))
#define HAVE_CXX11_OVERRIDE 1
#else
#define HAVE_CXX11_OVERRIDE 0
#endif
#endif
#if !defined(HAVE_CXX11_RANGE_FOR)
#if NVWA_CXX11_MODE && \
(__has_feature(cxx_range_for) || \
(defined(_MSC_VER) && _MSC_VER >= 1700) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 406))
#define HAVE_CXX11_RANGE_FOR 1
#else
#define HAVE_CXX11_RANGE_FOR 0
#endif
#endif
#if !defined(HAVE_CXX11_RVALUE_REFERENCE)
#if NVWA_CXX11_MODE && \
(__has_feature(cxx_rvalue_references) || \
(defined(_MSC_VER) && _MSC_VER >= 1600) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 405))
#define HAVE_CXX11_RVALUE_REFERENCE 1
#else
#define HAVE_CXX11_RVALUE_REFERENCE 0
#endif
#endif
#if !defined(HAVE_CXX11_STATIC_ASSERT)
#if NVWA_CXX11_MODE && \
(__has_feature(cxx_static_assert) || \
(defined(_MSC_VER) && _MSC_VER >= 1600) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 403))
#define HAVE_CXX11_STATIC_ASSERT 1
#else
#define HAVE_CXX11_STATIC_ASSERT 0
#endif
#endif
#if !defined(HAVE_CXX11_THREAD)
#if NVWA_CXX11_MODE && \
((__has_include() && !defined(__MINGW32__)) || \
(defined(_MSC_VER) && _MSC_VER >= 1700) || \
(((defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 404) || \
defined(__clang__)) && \
(!defined(__MINGW32__) || defined(_POSIX_THREADS))))
// Note: MinGW GCC, unless built with POSIX threads (as in
// MinGW-builds), does not support std::thread as of 4.8.
#define HAVE_CXX11_THREAD 1
#else
#define HAVE_CXX11_THREAD 0
#endif
#endif
#if !defined(HAVE_CXX11_THREAD_LOCAL)
#if NVWA_CXX11_MODE && \
(__has_feature(cxx_thread_local) || \
(defined(_MSC_VER) && _MSC_VER >= 1900) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 408))
#define HAVE_CXX11_THREAD_LOCAL 1
#else
#define HAVE_CXX11_THREAD_LOCAL 0
#endif
#endif
#if !defined(HAVE_CXX11_TYPE_TRAITS)
#if NVWA_CXX11_MODE && \
(__has_include() || \
(defined(_MSC_VER) && _MSC_VER >= 1600) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 403))
#define HAVE_CXX11_TYPE_TRAITS 1
#else
#define HAVE_CXX11_TYPE_TRAITS 0
#endif
#endif
#if !defined(HAVE_CXX11_UNICODE_LITERAL)
#if NVWA_CXX11_MODE && \
(__has_feature(cxx_unicode_literals) || \
(defined(_MSC_VER) && _MSC_VER >= 1900) || \
(defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 405))
#define HAVE_CXX11_UNICODE_LITERAL 1
#else
#define HAVE_CXX11_UNICODE_LITERAL 0
#endif
#endif
/* Workarounds */
#if HAVE_CXX11_DELETED_FUNCTION
#define _DELETED = delete
#else
#define _DELETED
#endif
#if HAVE_CXX11_FINAL
#define _FINAL final
#else
#define _FINAL
#endif
#if HAVE_CXX11_OVERRIDE
#define _OVERRIDE override
#else
#define _OVERRIDE
#endif
#if HAVE_CXX11_NOEXCEPT
#define _NOEXCEPT noexcept
#define _NOEXCEPT_(x) noexcept(x)
#else
#ifdef _MSC_VER
#define _NOEXCEPT throw ()
#else
#define _NOEXCEPT throw()
#endif
#define _NOEXCEPT_(x)
#endif
#if HAVE_CXX11_NULLPTR
#define _NULLPTR nullptr
#else
#define _NULLPTR NULL
#endif
#if HAVE_CXX11_THREAD_LOCAL
#define _THREAD_LOCAL thread_local
#else
#ifdef _MSC_VER
#define _THREAD_LOCAL __declspec(thread)
#else
#define _THREAD_LOCAL __thread
#endif
#endif
#endif // NVWA_CXX11_H
drc-3.2.2/source/MLeaks/static_assert.h 0000644 0000764 0000145 00000003455 12212607123 016751 0 ustar denis itadm // -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
// vim:tabstop=4:shiftwidth=4:expandtab:
/*
* Copyright (C) 2004-2013 Wu Yongwei
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute
* it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must
* not claim that you wrote the original software. If you use this
* software in a product, an acknowledgement in the product
* documentation would be appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must
* not be misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source
* distribution.
*
* This file is part of Stones of Nvwa:
* http://sourceforge.net/projects/nvwa
*
*/
/**
* @file static_assert.h
*
* Template class to check validity duing compile time (adapted from Loki).
*
* @date 2013-09-07
*/
#ifndef STATIC_ASSERT
#include "c++11.h"
#if HAVE_CXX11_STATIC_ASSERT
#define STATIC_ASSERT(_Expr, _Msg) static_assert(_Expr, #_Msg)
#else
namespace nvwa {
template struct compile_time_error;
template <> struct compile_time_error {};
#define STATIC_ASSERT(_Expr, _Msg) \
{ \
nvwa::compile_time_error<((_Expr) != 0)> ERROR_##_Msg; \
(void)ERROR_##_Msg; \
}
}
#endif // HAVE_CXX11_STATIC_ASSERT
#endif // STATIC_ASSERT
drc-3.2.2/source/MLeaks/fast_mutex.h 0000644 0000764 0000145 00000031754 12615050550 016266 0 ustar denis itadm // -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
// vim:tabstop=4:shiftwidth=4:expandtab:
/*
* Copyright (C) 2004-2015 Wu Yongwei
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute
* it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must
* not claim that you wrote the original software. If you use this
* software in a product, an acknowledgement in the product
* documentation would be appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must
* not be misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source
* distribution.
*
* This file is part of Stones of Nvwa:
* http://sourceforge.net/projects/nvwa
*
*/
/**
* @file fast_mutex.h
*
* A fast mutex implementation for POSIX, Win32, and modern C++.
*
* @date 2015-05-19
*/
#ifndef NVWA_FAST_MUTEX_H
#define NVWA_FAST_MUTEX_H
#include "_nvwa.h" // NVWA_NAMESPACE_*
#include "c++11.h" // HAVE_CXX11_MUTEX
# if !defined(_NOTHREADS)
# if !defined(NVWA_USE_CXX11_MUTEX) && HAVE_CXX11_MUTEX != 0 && \
!defined(_WIN32THREADS) && !defined(NVWA_WIN32THREADS) && \
!defined(NVWA_PTHREADS) && !defined(NVWA_NOTHREADS) && \
defined(_WIN32) && defined(_MT) && \
(!defined(_MSC_VER) || defined(_DLL))
// Prefer using std::mutex on Windows to avoid the namespace
// pollution caused by . However, MSVC has a re-entry
// issue with its std::mutex implementation, and std::mutex should
// not be used unless /MD or /MDd is used. For more information,
// check out:
//
// https://connect.microsoft.com/VisualStudio/feedback/details/776596/std-mutex-not-a-constexpr-with-mtd-compiler-flag
// http://stackoverflow.com/questions/14319344/stdmutex-lock-hangs-when-overriding-the-new-operator
//
# define NVWA_USE_CXX11_MUTEX 1
# endif
# if !defined(_WIN32THREADS) && \
(defined(_WIN32) && defined(_MT))
// Automatically use _WIN32THREADS when specifying -MT/-MD in MSVC,
// or -mthreads in MinGW GCC.
# define _WIN32THREADS
# elif !defined(_PTHREADS) && \
defined(_REENTRANT)
// Automatically use _PTHREADS when specifying -pthread in GCC or Clang.
# define _PTHREADS
# endif
# endif
# ifndef NVWA_USE_CXX11_MUTEX
# if HAVE_CXX11_MUTEX != 0 && \
!defined(_NOTHREADS) && !defined(NVWA_NOTHREADS) && \
!defined(_PTHREADS) && !defined(NVWA_PTHREADS) && \
!defined(_WIN32THREADS) && !defined(NVWA_WIN32THREADS)
# define NVWA_USE_CXX11_MUTEX 1
# else
# define NVWA_USE_CXX11_MUTEX 0
# endif
# endif
# if !defined(_PTHREADS) && !defined(_WIN32THREADS) && \
!defined(_NOTHREADS) && NVWA_USE_CXX11_MUTEX == 0
# define _NOTHREADS
# endif
# if defined(_NOTHREADS)
# if defined(_PTHREADS) || defined(_WIN32THREADS) || \
NVWA_USE_CXX11_MUTEX != 0
# undef _NOTHREADS
# error "Cannot define multi-threaded mode with -D_NOTHREADS"
# endif
# endif
# if defined(__MINGW32__) && defined(_WIN32THREADS) && !defined(_MT)
# error "Be sure to specify -mthreads with -D_WIN32THREADS"
# endif
// With all the heuristics above, things may still go wrong, maybe even
// due to a specific inclusion order. So they may be overridden by
// manually defining the NVWA_* macros below.
# if NVWA_USE_CXX11_MUTEX == 0 && \
!defined(NVWA_WIN32THREADS) && \
!defined(NVWA_PTHREADS) && \
!defined(NVWA_NOTHREADS)
// _WIN32THREADS takes precedence, as some C++ libraries have _PTHREADS
// defined even on Win32 platforms.
# if defined(_WIN32THREADS)
# define NVWA_WIN32THREADS
# elif defined(_PTHREADS)
# define NVWA_PTHREADS
# else
# define NVWA_NOTHREADS
# endif
# endif
# ifndef _FAST_MUTEX_CHECK_INITIALIZATION
/**
* Macro to control whether to check for initialization status for each
* lock/unlock operation. Defining it to a non-zero value will enable
* the check, so that the construction/destruction of a static object
* using a static fast_mutex not yet constructed or already destroyed
* will work (with lock/unlock operations ignored). Defining it to zero
* will disable to check.
*/
# define _FAST_MUTEX_CHECK_INITIALIZATION 1
# endif
# ifdef _DEBUG
# include
# include
/** Macro for fast_mutex assertions. Real version (for debug mode). */
# define _FAST_MUTEX_ASSERT(_Expr, _Msg) \
if (!(_Expr)) { \
fprintf(stderr, "fast_mutex::%s\n", _Msg); \
abort(); \
}
# else
/** Macro for fast_mutex assertions. Fake version (for release mode). */
# define _FAST_MUTEX_ASSERT(_Expr, _Msg) \
((void)0)
# endif
# if NVWA_USE_CXX11_MUTEX != 0
# include
NVWA_NAMESPACE_BEGIN
/**
* Macro alias to `volatile' semantics. Here it is truly volatile since
* it is in a multi-threaded (C++11) environment.
*/
# define __VOLATILE volatile
/**
* Class for non-reentrant fast mutexes. This is the implementation
* using the C++11 mutex.
*/
class fast_mutex
{
std::mutex _M_mtx_impl;
# if _FAST_MUTEX_CHECK_INITIALIZATION
bool _M_initialized;
# endif
# ifdef _DEBUG
bool _M_locked;
# endif
public:
fast_mutex()
# ifdef _DEBUG
: _M_locked(false)
# endif
{
# if _FAST_MUTEX_CHECK_INITIALIZATION
_M_initialized = true;
# endif
}
~fast_mutex()
{
_FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
# if _FAST_MUTEX_CHECK_INITIALIZATION
_M_initialized = false;
# endif
}
void lock()
{
# if _FAST_MUTEX_CHECK_INITIALIZATION
if (!_M_initialized)
return;
# endif
_M_mtx_impl.lock();
# ifdef _DEBUG
_FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
_M_locked = true;
# endif
}
void unlock()
{
# if _FAST_MUTEX_CHECK_INITIALIZATION
if (!_M_initialized)
return;
# endif
# ifdef _DEBUG
_FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
_M_locked = false;
# endif
_M_mtx_impl.unlock();
}
private:
fast_mutex(const fast_mutex&);
fast_mutex& operator=(const fast_mutex&);
};
NVWA_NAMESPACE_END
# elif defined(NVWA_PTHREADS)
# include
NVWA_NAMESPACE_BEGIN
/**
* Macro alias to `volatile' semantics. Here it is truly volatile since
* it is in a multi-threaded (POSIX threads) environment.
*/
# define __VOLATILE volatile
/**
* Class for non-reentrant fast mutexes. This is the implementation
* for POSIX threads.
*/
class fast_mutex
{
pthread_mutex_t _M_mtx_impl;
# if _FAST_MUTEX_CHECK_INITIALIZATION
bool _M_initialized;
# endif
# ifdef _DEBUG
bool _M_locked;
# endif
public:
fast_mutex()
# ifdef _DEBUG
: _M_locked(false)
# endif
{
::pthread_mutex_init(&_M_mtx_impl, NULL);
# if _FAST_MUTEX_CHECK_INITIALIZATION
_M_initialized = true;
# endif
}
~fast_mutex()
{
_FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
# if _FAST_MUTEX_CHECK_INITIALIZATION
_M_initialized = false;
# endif
::pthread_mutex_destroy(&_M_mtx_impl);
}
void lock()
{
# if _FAST_MUTEX_CHECK_INITIALIZATION
if (!_M_initialized)
return;
# endif
::pthread_mutex_lock(&_M_mtx_impl);
# ifdef _DEBUG
// The following assertion should _always_ be true for a
// real `fast' pthread_mutex. However, this assertion can
// help sometimes, when people forget to use `-lpthread' and
// glibc provides an empty implementation. Having this
// assertion is also more consistent.
_FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
_M_locked = true;
# endif
}
void unlock()
{
# if _FAST_MUTEX_CHECK_INITIALIZATION
if (!_M_initialized)
return;
# endif
# ifdef _DEBUG
_FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
_M_locked = false;
# endif
::pthread_mutex_unlock(&_M_mtx_impl);
}
private:
fast_mutex(const fast_mutex&);
fast_mutex& operator=(const fast_mutex&);
};
NVWA_NAMESPACE_END
# elif defined(NVWA_WIN32THREADS)
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif /* WIN32_LEAN_AND_MEAN */
# include
NVWA_NAMESPACE_BEGIN
/**
* Macro alias to `volatile' semantics. Here it is truly volatile since
* it is in a multi-threaded (Win32 threads) environment.
*/
# define __VOLATILE volatile
/**
* Class for non-reentrant fast mutexes. This is the implementation
* for Win32 threads.
*/
class fast_mutex
{
CRITICAL_SECTION _M_mtx_impl;
# if _FAST_MUTEX_CHECK_INITIALIZATION
bool _M_initialized;
# endif
# ifdef _DEBUG
bool _M_locked;
# endif
public:
fast_mutex()
# ifdef _DEBUG
: _M_locked(false)
# endif
{
::InitializeCriticalSection(&_M_mtx_impl);
# if _FAST_MUTEX_CHECK_INITIALIZATION
_M_initialized = true;
# endif
}
~fast_mutex()
{
_FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
# if _FAST_MUTEX_CHECK_INITIALIZATION
_M_initialized = false;
# endif
::DeleteCriticalSection(&_M_mtx_impl);
}
void lock()
{
# if _FAST_MUTEX_CHECK_INITIALIZATION
if (!_M_initialized)
return;
# endif
::EnterCriticalSection(&_M_mtx_impl);
# ifdef _DEBUG
_FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
_M_locked = true;
# endif
}
void unlock()
{
# if _FAST_MUTEX_CHECK_INITIALIZATION
if (!_M_initialized)
return;
# endif
# ifdef _DEBUG
_FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
_M_locked = false;
# endif
::LeaveCriticalSection(&_M_mtx_impl);
}
private:
fast_mutex(const fast_mutex&);
fast_mutex& operator=(const fast_mutex&);
};
NVWA_NAMESPACE_END
# elif defined(NVWA_NOTHREADS)
NVWA_NAMESPACE_BEGIN
/**
* Macro alias to `volatile' semantics. Here it is not truly volatile
* since it is in a single-threaded environment.
*/
# define __VOLATILE
/**
* Class for non-reentrant fast mutexes. This is the null
* implementation for single-threaded environments.
*/
class fast_mutex
{
# ifdef _DEBUG
bool _M_locked;
# endif
public:
fast_mutex()
# ifdef _DEBUG
: _M_locked(false)
# endif
{
}
~fast_mutex()
{
_FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
}
void lock()
{
# ifdef _DEBUG
_FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
_M_locked = true;
# endif
}
void unlock()
{
# ifdef _DEBUG
_FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
_M_locked = false;
# endif
}
private:
fast_mutex(const fast_mutex&);
fast_mutex& operator=(const fast_mutex&);
};
NVWA_NAMESPACE_END
# endif // Definition of class fast_mutex
NVWA_NAMESPACE_BEGIN
/** RAII lock class for fast_mutex. */
class fast_mutex_autolock
{
fast_mutex& _M_mtx;
public:
explicit fast_mutex_autolock(fast_mutex& mtx) : _M_mtx(mtx)
{
_M_mtx.lock();
}
~fast_mutex_autolock()
{
_M_mtx.unlock();
}
private:
fast_mutex_autolock(const fast_mutex_autolock&);
fast_mutex_autolock& operator=(const fast_mutex_autolock&);
};
NVWA_NAMESPACE_END
#endif // NVWA_FAST_MUTEX_H
drc-3.2.2/source/MLeaks/debug_new.h 0000644 0000764 0000145 00000015740 12615050550 016043 0 ustar denis itadm // -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
// vim:tabstop=4:shiftwidth=4:expandtab:
/*
* Copyright (C) 2004-2015 Wu Yongwei
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute
* it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must
* not claim that you wrote the original software. If you use this
* software in a product, an acknowledgement in the product
* documentation would be appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must
* not be misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source
* distribution.
*
* This file is part of Stones of Nvwa:
* http://sourceforge.net/projects/nvwa
*
*/
/**
* @file debug_new.h
*
* Header file for checking leaks caused by unmatched new/delete.
*
* @date 2015-10-25
*/
#ifndef NVWA_DEBUG_NEW_H
#define NVWA_DEBUG_NEW_H
#include // size_t/std::bad_alloc
#include // FILE
#include "_nvwa.h" // NVWA_NAMESPACE_*
#include "c++11.h" // _NOEXCEPT
/* Special allocation/deallocation functions in the global scope */
void* operator new(size_t size, const char* file, int line);
void* operator new[](size_t size, const char* file, int line);
void operator delete(void* ptr, const char* file, int line) _NOEXCEPT;
void operator delete[](void* ptr, const char* file, int line) _NOEXCEPT;
NVWA_NAMESPACE_BEGIN
/**
* @def _DEBUG_NEW_REDEFINE_NEW
*
* Macro to indicate whether redefinition of \c new is wanted. If one
* wants to define one's own operator new, or to call
* operator new directly, it should be defined to \c 0 to
* alter the default behaviour. Unless, of course, one is willing to
* take the trouble to write something like:
* @code
* # ifdef new
* # define _NEW_REDEFINED
* # undef new
* # endif
*
* // Code that uses new is here
*
* # ifdef _NEW_REDEFINED
* # ifdef DEBUG_NEW
* # define new DEBUG_NEW
* # endif
* # undef _NEW_REDEFINED
* # endif
* @endcode
*/
#ifndef _DEBUG_NEW_REDEFINE_NEW
#define _DEBUG_NEW_REDEFINE_NEW 1
#endif
/**
* @def _DEBUG_NEW_TYPE
*
* Macro to indicate which variant of #DEBUG_NEW is wanted. The
* default value \c 1 allows the use of placement new (like
* %new(std::nothrow)), but the verbose output (when
* nvwa#new_verbose_flag is \c true) looks worse than some older
* versions (no file/line information for allocations). Define it
* to \c 2 to revert to the old behaviour that records file and line
* information directly on the call to operator new.
*/
#ifndef _DEBUG_NEW_TYPE
#define _DEBUG_NEW_TYPE 1
#endif
/**
* Callback type for stack trace printing.
*
* @param fp pointer to the output stream
* @param stacktrace pointer to the stack trace array (null-terminated)
*/
typedef void (*stacktrace_print_callback_t)(FILE* fp, void** stacktrace);
/**
* Callback type for the leak whitelist function. \a file, \a address,
* and \a backtrace might be null depending on library configuration,
* platform, and amount of runtime information available. \a line can
* be 0 when line number info is not available at runtime.
*
* @param file null-terminated string of the file name
* @param line line number
* @param addr address of code where leakage happens
* @param stacktrace pointer to the stack trace array (null-terminated)
* @return \c true if the leak should be whitelisted;
* \c false otherwise
*/
typedef bool (*leak_whitelist_callback_t)(char const* file, int line,
void* addr, void** stacktrace);
/* Prototypes */
int check_leaks();
int check_mem_corruption();
/* Control variables */
extern bool new_autocheck_flag; // default to true: call check_leaks() on exit
extern bool new_verbose_flag; // default to false: no verbose information
extern FILE* new_output_fp; // default to stderr: output to console
extern const char* new_progname;// default to null; should be assigned argv[0]
extern stacktrace_print_callback_t stacktrace_print_callback;// default to null
extern leak_whitelist_callback_t leak_whitelist_callback; // default to null
/**
* @def DEBUG_NEW
*
* Macro to catch file/line information on allocation. If
* #_DEBUG_NEW_REDEFINE_NEW is \c 0, one can use this macro directly;
* otherwise \c new will be defined to it, and one must use \c new
* instead.
*/
# if _DEBUG_NEW_TYPE == 1
# define DEBUG_NEW NVWA::debug_new_recorder(__FILE__, __LINE__) ->* new
# else
# define DEBUG_NEW new(__FILE__, __LINE__)
# endif
# if _DEBUG_NEW_REDEFINE_NEW
# define new DEBUG_NEW
# endif
# ifdef _DEBUG_NEW_EMULATE_MALLOC
# include
# ifdef new
# define malloc(s) ((void*)(new char[s]))
# else
# define malloc(s) ((void*)(DEBUG_NEW char[s]))
# endif
# define free(p) delete[] (char*)(p)
# endif
/**
* Recorder class to remember the call context.
*
* The idea comes from Greg Herlihy's post in comp.lang.c++.moderated.
*/
class debug_new_recorder
{
const char* _M_file;
const int _M_line;
void _M_process(void* ptr);
public:
/**
* Constructor to remember the call context. The information will
* be used in debug_new_recorder::operator->*.
*/
debug_new_recorder(const char* file, int line)
: _M_file(file), _M_line(line) {}
/**
* Operator to write the context information to memory.
* operator->* is chosen because it has the right
* precedence, it is rarely used, and it looks good: so people can
* tell the special usage more quickly.
*/
template _Tp* operator->*(_Tp* ptr)
{ _M_process(ptr); return ptr; }
private:
debug_new_recorder(const debug_new_recorder&);
debug_new_recorder& operator=(const debug_new_recorder&);
};
/**
* Counter class for on-exit leakage check.
*
* This technique is learnt from The C++ Programming Language by
* Bjarne Stroustup.
*/
class debug_new_counter
{
static int _S_count;
public:
debug_new_counter();
~debug_new_counter();
};
/** Counting object for each file including debug_new.h. */
static debug_new_counter __debug_new_count;
NVWA_NAMESPACE_END
#endif // NVWA_DEBUG_NEW_H
drc-3.2.2/source/MLeaks/README 0000644 0000764 0000145 00000030260 13066737767 014634 0 ustar denis itadm === Stones of Nvwa ===
The Name
Nvwa ("v" is pronounced like the French "u"), is one of the most
ancient Chinese goddesses. She was said to have created human beings,
and, when the evil god Gong-gong crashed himself upon one of the
pillars that support the sky and made a hole in it, she mended the sky
with five-coloured stones.
I thought of the name Nvwa by analogy with Loki. Since it is so small
a project and it contains utilities instead of a complete framework, I
think "stones" a good metaphor.
Code Organization
Nvwa versions prior to 1.0 did not use a namespace. It looked to me
overkill to use a namespace in this small project. However, having
had more project experience and seen more good examples, I have
changed my mind. All nvwa functions and global variables are now
inside the namespace "nvwa".
This said, I do not want to break backward compatibility abruptly.
First, people are still able to disable the namespace by defining the
macro NVWA_USE_NAMESPACE to 0 (not really recommended, though).
Second, I still use the quotation mark (") to include header files
internally so that old users do not have to change the include
directory (again, not recommended and intended to help the transition
only). Third, I have not changed most of the macro names -- that
would break existing code and could do more harm than good now. In
addition, I am not a fan of macro prefixes anyway.
Overall, I am quite happy with the changes: some code is simplified,
and in many cases I do not have to use the uglified names to avoid
potential name conflicts. The changes also do not mean anything to
new users. You just need to follow the modern C++ way. You should
add the root directory of this project to your include directory
(there should be a "nvwa" directory inside it with the source files).
To include the header file, use "#include ".
Contents
A brief introduction follows. Check the Doxygen documentation for
more (technical) details.
* boolarray.cpp
* boolarray.h
A replacement of std::vector. I wrote it before I knew of
vector, or I might not have written it at all. However, it is
faster than many vector implementations (your mileage may
vary), and it has members like at, set, reset, flip, and count. I
personally find "count" very useful.
* c++11.h
Detection macros for certain features of C++11 that might be of
interest to code/library writers. I have used existing online
resources, and I have tested them on popular platforms and compilers
that I have access to (Windows, OS X, and Linux; MSVC, Clang, and
GCC), but of course not all versions or all combinations. Patches
are welcome for corrections and amendments.
* class_level_lock.h
The Loki ClassLevelLockable adapted to use the fast_mutex layer. One
minor divergence from Loki is that the template has an additional
template parameter _RealLock to boost the performance in non-locking
scenarios. Unless HAVE_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION is
explicitly defined to 0, this is enabled automatically. Cf.
object_level_lock.h.
* cont_ptr_utils.h
Utility functors for containers of pointers adapted from Scott Meyers'
Effective STL.
* debug_new.cpp
* debug_new.h
A cross-platform, thread-safe memory leak detector. It is a
light-weight one designed only to catch unmatched pairs of
new/delete. I know there are already many existing memory leak
detectors, but as far as I know, free solutions are generally slow,
memory-consuming, and quite complicated to use. This solution is
very easy to use, and has very low space/time overheads. Just link
in debug_new.cpp for leakage report, and include debug_new.h for
additional file/line information. It will automatically switch on
multi-threading when the appropriate option of a recognized compiler
is specified. Check fast_mutex.h for more threading details.
Special support for gcc/binutils has been added to debug_new lately.
Even if the header file debug_new.h is not included, or
_DEBUG_NEW_REDEFINE_NEW is defined to 0 when it is included,
file/line information can be displayed if debugging symbols are
present in the executable, since debug_new stores the caller
addresses of memory allocation/deallocation routines and they will be
converted with addr2line (or atos on a Mac) on the fly. This makes
memory tracing much easier.
NOTE for Mac OS X users: If you use OS X 10.7 or later, you may need
to add "-Wl,-no_pie" at the end of the command line. By default OS X
will now create position-independent executables (PIE), and the OS
will load a PIE at a random address each time it is executed, making
it difficult to convert the address to symbols. (I Googled a while
for a way to get the base address of a process, but could not find
working code. If you know how to do it right, drop me a message.)
With an idea from Greg Herlihy's post in comp.lang.c++.moderated, the
implementation was much improved in 2007. The most significant
result is that placement new can be used with debug_new now! Full
support for new(std::nothrow) is provided, with its null-returning
error semantics (by default). Memory corruption will be checked on
freeing the pointers and checking the leaks, and a new function
check_mem_corruption is added for your on-demand use in debugging.
You may also want to define _DEBUG_NEW_TAILCHECK to something like 4
for past-end memory corruption check, which is off by default to
ensure performance is not affected.
An article on its design and implementation is available at
http://nvwa.sourceforge.net/article/debug_new.htm
* fast_mutex.h
The threading transparent layer simulating a non-recursive mutex. It
supports C++11 mutex, POSIX mutex, and Win32 critical section, as
well as a no-threads mode. Unlike Loki and some other libraries,
threading mode is not to be specified in code, but detected from the
environment. It will automatically switch on multi-threading mode
(inter-thread exclusion) when the "-MT"/"-MD" option of MSVC, the
"-mthreads" option of MinGW GCC, or the "-pthread" option of GCC
under POSIX environments, is used. One advantage of the current
implementation is that the construction and destruction of a static
object using a static fast_mutex not yet constructed or already
destroyed are allowed to work (with lock/unlock operations ignored),
and there are re-entry checks for lock/unlock operations when the
preprocessing symbol _DEBUG is defined.
* fc_queue.h
A queue that has a fixed capacity (maximum number of allowed items).
All memory is pre-allocated when the queue is initialized, so memory
consumption is well controlled. When the queue is full, inserting a
new item will discard the oldest item in the queue. Care is taken to
ensure this class template provides the strong exception safety
guarantee.
This class template is a good exercise for me to make a STL-type
container. Depending on your needs, you may find circular_buffer in
Boost more useful, which provides similar functionalities and a
richer API. However, the design philosophies behind the two
implementations are quite different. fc_queue is modelled closely on
std::queue, and I optimize mainly for a lockless producer-consumer
pattern -- when there is one producer and one consumer, and the
producer does not try to queue an element when the queue is already
full, no lock is needed for the queue operations.
* file_line_reader.cpp
* file_line_reader.h
This is one of the line reading classes I implemented modelling the
Python approach. They make reading lines from a file a simple loop.
This specific class allows reading from a traditional FILE*.
Cf. istream_line_reader.h and mmap_line_reader.h.
See the following blog for the motivation and example code:
https://yongweiwu.wordpress.com/2016/11/12/performance-of-my-line-readers/
* fixed_mem_pool.h
A memory pool implementation that requires initialization (allocates
a fixed-size chunk) prior to its use. It is simple and makes no
memory fragmentation, but the memory pool size cannot be changed
after initialization. Macros are provided to easily make a class use
pooled new/delete.
* functional.h
This is my test bed for functional programming. If you are into
functional programming, check it out. It includes functional
programming patterns like:
- map
- reduce
- compose
- fixed-point combinator
- curry
- optional
My blogs on functional programming may be helpful:
https://yongweiwu.wordpress.com/2014/12/07/study-notes-functional-programming-with-cplusplus/
https://yongweiwu.wordpress.com/2014/12/14/y-combinator-and-cplusplus/
https://yongweiwu.wordpress.com/2014/12/29/type-deduction-and-my-reference-mistakes/
https://yongweiwu.wordpress.com/2015/01/03/generic-lambdas-and-the-compose-function/
* istream_line_reader.h
This is one of the line reading classes I implemented modelling the
Python approach. They make reading lines from a file a simple loop.
This specific class allows reading from an input stream.
Cf. file_line_reader.h and mmap_line_reader.h.
See the following blogs for the motivation and example code:
https://yongweiwu.wordpress.com/2016/08/16/python-yield-and-cplusplus-coroutines/
https://yongweiwu.wordpress.com/2016/11/12/performance-of-my-line-readers/
* mem_pool_base.cpp
* mem_pool_base.h
A class solely to be inherited by memory pool implementations. It is
used by static_mem_pool and fixed_mem_pool.
* mmap_line_reader.cpp
* mmap_line_reader.h
This is one of the line reading classes I implemented modelling the
Python approach. They make reading lines from a file a simple loop.
This specific class allows reading from an on-disk file via memory-
mapped file I/O. Cf. istream_line_reader.h and file_line_reader.h.
See the following blog for the motivation and example code:
https://yongweiwu.wordpress.com/2016/11/12/performance-of-my-line-readers/
* object_level_lock.h
The Loki ObjectLevelLockable adapted to use the fast_mutex layer.
The member function get_locked_object does not exist in Loki, but is
also taken from Mr Alexandrescu's article. Cf. class_level_lock.h.
* pctimer.h
A function to get a high-resolution timer for Win32/Cygwin/Unix. It
is quite useful for measurement and optimization.
* set_assign.h
Utility routines to make up for the fact that STL only has set_union
(+) and set_difference (-) algorithms but no corresponding += and -=
operations available.
* static_mem_pool.cpp
* static_mem_pool.h
A memory pool implementation to pool memory blocks according to
compile-time block sizes. Macros are provided to easily make a class
use pooled new/delete.
An article on its design and implementation is available at
http://nvwa.sourceforge.net/article/static_mem_pool.htm
* tree.h
A generic tree class template along with traversal utilities.
Besides the usual template argument of value type, it has an
additional argument of storage policy, which can be either unique or
shared. Traversal utility classed are provided so that traversing a
tree can be simply done in a range-based for loop. The test code,
test/test_tree.cpp, shows its basic usage.
* type_traits.h
This file was separated from fc_queue.h. Type traits were not
standardized until C++11, and, in addition, there were late changes
in the trait names that did not go into even the 2012 releases of
MSVC and GCC. So I made a nvwa::is_trivially_destructible that can
work across main compilers.
In the post-C++11 world, this is no longer useful. Use of this file
is deprecated.
$Id: README,v 1.1 2017/03/29 14:08:55 adah Exp $
vim:autoindent:expandtab:formatoptions=tcqlm:textwidth=72:
drc-3.2.2/source/drccfg.h 0000644 0000764 0000145 00000016004 13162156445 014162 0 ustar denis itadm /****************************************************************************
DRC: Digital Room Correction
Copyright (C) 2002-2017 Denis Sbragion
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
You can contact the author on Internet at the following address:
d.sbragion@neomerica.it
****************************************************************************/
/* Opzioni di configurazione DRC */
#ifndef DRCCfg_h
#define DRCCfg_h
/* Inclusioni */
#include "drc.h"
#include "cmdline.h"
/* Posizione opzione directory base di configurazione
nella lista parametri */
#define BCBaseDirParmPos 0
/* Struttura definizione configurazione */
/* Prefissi variabili
BC = Base Configuration
HD = Homomorphic Deconvolution
MP = Minimum phase frequency dependent windowing
DL = Dip limiting stage
EP = Excess phase frequency dependent windowing
PC = Prefiltering completion stage
IS = Inversion stage
PT = Psychoacoustic target stage
PL = Peak limiting stage
RT = Ringing truncation stage
PS = Postfiltering stage
MC = Mic compensation stage
MS = Minimum phase filter extraction stage
TC = Test convolution stage
*/
typedef struct
{
/* Base configuration */
char * BCBaseDir;
char * BCInFile;
char * BCInFileType;
int BCSampleRate;
char * BCImpulseCenterMode;
int BCImpulseCenter;
int BCInitWindow;
int BCPreWindowLen;
int BCPreWindowGap;
DRCFloat BCNormFactor;
char * BCNormType;
/* Mic compensation stage */
char * MCFilterType;
char * MCInterpolationType;
int MCMultExponent;
int MCFilterLen;
int MCNumPoints;
char * MCPointsFile;
char * MCMagType;
int MCOutWindow;
char * MCFilterFile;
char * MCFilterFileType;
DRCFloat MCNormFactor;
char * MCNormType;
char * MCOutFile;
char * MCOutFileType;
/* Base configuration dip limiting stage */
char * BCDLType;
DRCFloat BCDLMinGain;
DRCFloat BCDLStart;
DRCFloat BCDLStartFreq;
DRCFloat BCDLEndFreq;
int BCDLMultExponent;
/* Homomorphic Deconvolution */
int HDMultExponent;
DRCFloat HDMPNormFactor;
char * HDMPNormType;
char * HDMPOutFile;
char * HDMPOutFileType;
DRCFloat HDEPNormFactor;
char * HDEPNormType;
char * HDEPOutFile;
char * HDEPOutFileType;
/* Minimum phase prefiltering stage */
char * MPPrefilterType;
char * MPPrefilterFctn;
int MPWindowGap;
int MPLowerWindow;
int MPUpperWindow;
DRCFloat MPStartFreq;
DRCFloat MPEndFreq;
DRCFloat MPWindowExponent;
int MPFilterLen;
DRCFloat MPFSharpness;
int MPBandSplit;
char * MPHDRecover;
char * MPEPPreserve;
int MPHDMultExponent;
int MPPFFinalWindow;
DRCFloat MPPFNormFactor;
char * MPPFNormType;
char * MPPFOutFile;
char * MPPFOutFileType;
/* Dip limiting stage */
char * DLType;
DRCFloat DLMinGain;
DRCFloat DLStart;
DRCFloat DLStartFreq;
DRCFloat DLEndFreq;
int DLMultExponent;
/* Excess fase phase prefiltering stage */
char * EPPrefilterType;
char * EPPrefilterFctn;
int EPWindowGap;
int EPLowerWindow;
int EPUpperWindow;
DRCFloat EPStartFreq;
DRCFloat EPEndFreq;
DRCFloat EPWindowExponent;
int EPFilterLen;
DRCFloat EPFSharpness;
int EPBandSplit;
DRCFloat EPPFFlatGain;
DRCFloat EPPFOGainFactor;
char * EPPFFlatType;
int EPPFFGMultExponent;
int EPPFFinalWindow;
DRCFloat EPPFNormFactor;
char * EPPFNormType;
char * EPPFOutFile;
char * EPPFOutFileType;
/* Prefiltering completion stage */
int PCOutWindow;
DRCFloat PCNormFactor;
char * PCNormType;
char * PCOutFile;
char * PCOutFileType;
/* Inversion stage */
char * ISType;
char * ISPETType;
char * ISPrefilterFctn;
int ISPELowerWindow;
int ISPEUpperWindow;
int ISPEStartFreq;
int ISPEEndFreq;
int ISPEFilterLen;
DRCFloat ISPEFSharpness;
int ISPEBandSplit;
DRCFloat ISPEWindowExponent;
DRCFloat ISPEOGainFactor;
int ISSMPMultExponent;
int ISOutWindow;
DRCFloat ISNormFactor;
char * ISNormType;
char * ISOutFile;
char * ISOutFileType;
/* Psychoacoustic target stage */
char * PTType;
int PTReferenceWindow;
char * PTDLType;
DRCFloat PTDLMinGain;
DRCFloat PTDLStart;
DRCFloat PTDLStartFreq;
DRCFloat PTDLEndFreq;
int PTDLMultExponent;
DRCFloat PTBandWidth;
DRCFloat PTPeakDetectionStrength;
int PTMultExponent;
int PTFilterLen;
char * PTFilterFile;
char * PTFilterFileType;
DRCFloat PTNormFactor;
char * PTNormType;
char * PTOutFile;
char * PTOutFileType;
int PTOutWindow;
/* Peak limiting stage */
char * PLType;
DRCFloat PLMaxGain;
DRCFloat PLStart;
DRCFloat PLStartFreq;
DRCFloat PLEndFreq;
int PLMultExponent;
int PLOutWindow;
DRCFloat PLNormFactor;
char * PLNormType;
char * PLOutFile;
char * PLOutFileType;
/* Ringing truncation stage */
char * RTType;
char * RTPrefilterFctn;
int RTWindowGap;
int RTLowerWindow;
int RTUpperWindow;
DRCFloat RTStartFreq;
DRCFloat RTEndFreq;
DRCFloat RTWindowExponent;
int RTFilterLen;
DRCFloat RTFSharpness;
int RTBandSplit;
int RTOutWindow;
DRCFloat RTNormFactor;
char * RTNormType;
char * RTOutFile;
char * RTOutFileType;
/* Target response stage */
char * PSFilterType;
char * PSInterpolationType;
int PSMultExponent;
int PSFilterLen;
int PSNumPoints;
char * PSPointsFile;
char * PSMagType;
int PSOutWindow;
DRCFloat PSNormFactor;
char * PSNormType;
char * PSOutFile;
char * PSOutFileType;
/* Minimum phase filter extraction stage */
int MSMultExponent;
int MSOutWindow;
int MSFilterDelay;
DRCFloat MSNormFactor;
char * MSNormType;
char * MSOutFile;
char * MSOutFileType;
/* Test convolution stage */
DRCFloat TCNormFactor;
char * TCNormType;
char * TCOutFile;
char * TCOutFileType;
char * TCOWFile;
char * TCOWFileType;
DRCFloat TCOWNormFactor;
char * TCOWNormType;
int TCOWSkip;
int TCOWPrewindow;
int TCOWLength;
}
CfgParmsType;
/* Opzioni di configurazione */
extern CfgParmsType Cfg;
/* Definizione struttura file di configurazione */
extern CfgParameter CfgParmsDef[];
/* Controllo validit parametri di configurazione */
int CheckDRCCfg(const CfgParmsType * DRCCfg);
/* Impostazione directory base di lavoro */
int SetupDRCCfgBaseDir(CfgParmsType * DRCCfg, const CfgParameter * CfgParmsDef,
const CmdLineType * OptData);
#endif
drc-3.2.2/source/baselib.cpp 0000644 0000764 0000145 00000044027 13162156311 014664 0 ustar denis itadm /****************************************************************************
DRC: Digital Room Correction
Copyright (C) 2002, 2003 Denis Sbragion
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
You can contact the author on Internet at the following address:
d.sbragion@neomerica.it
****************************************************************************/
/* Funzioni di libreria base */
/* Inclusioni */
#include "baselib.h"
#include "fft.h"
#include
#include
#include
/* Memory leaks debugger */
#ifdef DebugMLeaks
#include "debug_new.h"
#endif
/* Output stringhe con sync output e parametro */
int sputsp(const char * s, const char * p)
{
int Res;
if (p == NULL)
Res = puts(s);
else
Res = printf("%s%s\n",s,p);
fflush(stdout);
return(Res);
}
/* Output stringhe con sync output */
int sputs(const char * s)
{
return(sputsp(s, NULL));
}
/* Determina la lunghezza di un file */
size_t FSize(FILE * F)
{
long CPos;
long FS;
CPos = ftell(F);
fseek(F,0,SEEK_END);
FS = ftell(F);
fseek(F,CPos,SEEK_SET);
return (size_t) FS;
}
/* Legge parte di un file di ingresso e lo pone nell'array indicato
di dimensione InitWindow.
Ritorna true se l'operazione ha successo.
*/
Boolean ReadSignal(const char * FName,DRCFloat * Dst,const int InitWindow,
const int ImpulseCenter,const IFileType FType,
int * PreSpikeStart, int * PostSpikeEnd)
{
int I;
int IStart;
int IEnd;
int WHalf;
DRCFileDouble RWD;
DRCFileFloat RWF;
DRCFileInt RWI;
int RWDim;
/* File gestione IO */
FILE * IOF;
long FS;
/* Azzera l'array destinazione */
for (I = 0;I < InitWindow;I++)
Dst[I] = 0;
/* Salva la dimensione del blocco lettura */
RWDim = sizeof(DRCFileFloat);
switch (FType)
{
case PcmFloat64Bit:
RWDim = sizeof(DRCFileDouble);
break;
case PcmFloat32Bit:
RWDim = sizeof(DRCFileFloat);
break;
case PcmInt16Bit:
RWDim = sizeof(DRCFileInt);
break;
}
/* Apre il file di input */
if ((IOF = fopen(FName,"rb")) == NULL)
{
perror("\nUnable to open input file");
return False;
}
/* Recupera la dimensione del file */
FS = FSize(IOF) / RWDim;
/* Controllo validit parametri */
if (FS == 0)
{
puts("\nInput file is zero length.");
return False;
}
if (ImpulseCenter > FS)
{
puts("\nImpulseCenter is out of input file range.");
return False;
}
/* Calcolo la posizione centrale finestra */
if (InitWindow % 2 == 0)
WHalf = (InitWindow - 1) / 2;
else
WHalf = InitWindow / 2;
/* Calcola gli estremi lettura finestra */
if (ImpulseCenter > WHalf)
{
if (fseek(IOF,(ImpulseCenter - WHalf) * RWDim,SEEK_SET) != 0)
{
perror("\nError reading input file");
return False;
}
IStart = 0;
if (InitWindow > FS - (ImpulseCenter - WHalf))
IEnd = FS - (ImpulseCenter - WHalf);
else
IEnd = InitWindow;
}
else
{
IStart = WHalf - ImpulseCenter;
if (InitWindow > IStart + FS)
IEnd = IStart + FS;
else
IEnd = InitWindow;
}
/* Imposta inizio pre spike */
if (PreSpikeStart != NULL)
*PreSpikeStart = IStart;
/* Imposta fine post spike */
if (PostSpikeEnd != NULL)
*PostSpikeEnd = IEnd;
/* Legge la risposta all'impulso */
switch (FType)
{
case PcmFloat64Bit:
for (I = IStart; I < IEnd; I++)
{
if (fread((void *) &RWD,sizeof(DRCFileDouble),1,IOF) != 1)
{
perror("\nError reading input file");
return False;
}
Dst[I] = (DLReal) RWD;
}
break;
case PcmFloat32Bit:
for (I = IStart; I < IEnd; I++)
{
if (fread((void *) &RWF,sizeof(DRCFileFloat),1,IOF) != 1)
{
perror("\nError reading input file");
return False;
}
Dst[I] = (DLReal) RWF;
}
break;
case PcmInt16Bit:
for (I = IStart; I < IEnd; I++)
{
if (fread((void *) &RWI,sizeof(DRCFileInt),1,IOF) != 1)
{
perror("\nError reading input file");
return False;
}
Dst[I] = (DLReal) RWI;
}
break;
}
/* Chiude il file */
fclose(IOF);
/* Operazione completata */
return True;
}
/* Scrive il segnale indicato su disco */
Boolean WriteSignal(const char * FName,const DRCFloat * Src,const int SSize,
const IFileType FType)
{
/* File gestione IO */
FILE * IOF;
int I;
DRCFileDouble RWD;
DRCFileFloat RWF;
DRCFileInt RWI;
/* Apre il file di output */
if ((IOF = fopen(FName,"wb")) == NULL)
{
perror("\nUnable to open output file");
return False;
}
/* Salva la risposta risultante */
switch (FType)
{
case PcmFloat64Bit:
for (I = 0; I < SSize; I++)
{
RWD = (DRCFileDouble) Src[I];
if (fwrite((void *) &RWD,sizeof(DRCFileDouble),1,IOF) != 1)
{
perror("\nError writing output file");
return False;
}
}
break;
case PcmFloat32Bit:
for (I = 0; I < SSize; I++)
{
RWF = (DRCFileFloat) Src[I];
if (fwrite((void *) &RWF,sizeof(DRCFileFloat),1,IOF) != 1)
{
perror("\nError writing output file");
return False;
}
}
break;
case PcmInt16Bit:
for (I = 0; I < SSize; I++)
{
RWI = (DRCFileInt) floor(0.5 + Src[I]);
if (fwrite((void *) &RWI,sizeof(DRCFileInt),1,IOF) != 1)
{
perror("\nError writing output file");
return False;
}
}
break;
}
/* Chiude il file */
fclose(IOF);
/* Operazione completata */
return True;
}
/* Sovrascrive il segnale indicato su disco */
Boolean OverwriteSignal(const char * FName,const DRCFloat * Src,const int SSize, const int Skip,
const IFileType FType)
{
/* File gestione IO */
FILE * IOF;
int I;
DRCFileDouble RWD;
DRCFileFloat RWF;
DRCFileInt RWI;
/* Apre il file di output */
IOF = fopen(FName,"r+b");
/* Salva la risposta risultante */
switch (FType)
{
case PcmFloat64Bit:
fseek(IOF,Skip * sizeof(DRCFileDouble), SEEK_SET);
for (I = 0; I < SSize; I++)
{
RWD = (DRCFileDouble) Src[I];
if (fwrite((void *) &RWD,sizeof(DRCFileDouble),1,IOF) != 1)
{
perror("\nError writing output file.");
return False;
}
}
break;
case PcmFloat32Bit:
fseek(IOF,Skip * sizeof(DRCFileFloat), SEEK_SET);
for (I = 0; I < SSize; I++)
{
RWF = (DRCFileFloat) Src[I];
if (fwrite((void *) &RWF,sizeof(DRCFileFloat),1,IOF) != 1)
{
perror("\nError writing output file.");
return False;
}
}
break;
case PcmInt16Bit:
fseek(IOF,Skip * sizeof(DRCFileInt), SEEK_SET);
for (I = 0; I < SSize; I++)
{
RWI = (DRCFileInt) floor(0.5 + Src[I]);
if (fwrite((void *) &RWI,sizeof(DRCFileInt),1,IOF) != 1)
{
perror("\nError writing output file.");
return False;
}
}
break;
}
/* Chiude il file */
fclose(IOF);
/* Operazione completata */
return True;
}
/* Calcola l'autocorrelazione del segnale S */
Boolean AutoCorrelation(DLReal * S, int N)
{
DLComplex * C;
int I;
if ((C = new DLComplex[N]) == NULL)
return False;
for (I = 0; I < N; I++)
C[I] = S[I];
Fft(C,N);
for (I = 0; I < N; I++)
/* C[I] = C[I] * std::conj(C[I]); */
C[I] = std::real(C[I]) * std::real(C[I]) + std::imag(C[I]) * std::imag(C[I]);
IFft(C,N);
for (I = 0; I < N; I++)
S[I] = std::real(C[I]) / N;
delete[] C;
return True;
}
/* Calcola la cross correlazione tra S1 e S2 */
/* XC deve avere lunghezza 2N - 1 */
Boolean CrossCorrelation(DLReal * S1, DLReal * S2, int N, DLReal * XC)
{
DLComplex * C1;
DLComplex * C2;
int I;
if ((C1 = new DLComplex[2 * N]) == NULL)
return False;
if ((C2 = new DLComplex[2 * N]) == NULL)
{
delete[] C1;
return False;
}
for (I = 0; I < N; I++)
{
C1[I] = S1[I];
C2[I] = S2[I];
}
for (I = N; I < 2 * N; I++)
{
C1[I] = 0;
C2[I] = 0;
}
Fft(C1,2 * N);
Fft(C2,2 * N);
for (I = 0; I < 2 * N; I++)
C1[I] *= std::conj(C2[I]);
delete[] C2;
IFft(C1,2 * N);
for (I = 0; I < 2 * N - 1; I++)
XC[I] = std::real(C1[I]) / N;
delete[] C1;
return True;
}
/* Calcola il ritardo di gruppo del segnale S */
Boolean GroupDelay(const DLReal * S, const int N, DLReal * GD)
{
DLComplex * HA;
DLComplex * DHA;
int I;
if ((HA = new DLComplex[N]) == NULL)
return False;
if ((DHA = new DLComplex[N]) == NULL)
{
delete[] HA;
return False;
}
for(I = 0;I < N;I++)
{
HA[I] = S[I];
DHA[I] = S[I] * I;
}
Fft(HA,N);
Fft(DHA,N);
for(I = 0;I < N;I++)
GD[I] = std::real(DHA[I] / HA[I]);
delete[] HA;
delete[] DHA;
return True;
}
/* I/O Delay computation, reliable only for simple impulse responses */
DLReal LinearDelay(DLReal * Hn,unsigned int N,unsigned int Np,
DLReal MZE)
{
unsigned int I;
DLComplex * H;
DLComplex * H1;
DLComplex Sum,i(0,1);
if (Np == 0)
for(Np = 2;Np < N;Np <<= 1);
Np = 2*Np;
if ((H = new DLComplex[Np]) == NULL)
return(-1);
if ((H1 = new DLComplex[Np]) == NULL)
{
delete[](H);
return(-1);
}
for(I = 0;I < N;I++)
H[I] = Hn[I];
for(I = N;I < Np;I++)
H[I] = 0;
if (Fft(H,Np) == False)
{
delete[](H);
delete[](H1);
return(-1);
}
for(I = 0;I < N;I++)
H1[I] = I*Hn[I];
for(I = N;I < Np;I++)
H1[I] = 0;
if (Fft(H1,Np) == False)
{
delete[](H);
delete[](H1);
return(-1);
}
for(I = 0;I < Np;I++)
if (std::abs(H[I]) <= MZE)
{
H[I] = 1;
H1[I] = 0;
}
Sum = 0;
for(I = 0;I < Np;I++)
Sum += (-i*H1[I])/H[I];
delete[](H);
delete[](H1);
return(std::real(-Sum/(i*(DLReal) Np)));
}
/* Conta il numero di righe in un file */
int FLineCount(const char * FName)
{
/* File gestione IO */
FILE * IOF;
/* Variabili ausiliarie */
int LC;
char InStr[256];
/* Apre il file di input */
if ((IOF = fopen(FName,"rt")) == NULL)
{
perror("\nUnable to open input file.");
return False;
}
/* Conta le righe */
LC = 0;
while (fgets(InStr,256,IOF) != NULL)
LC++;
/* Chiude il file di input */
fclose(IOF);
/* Ritorna il numero di righe */
return LC;
}
/* Legge i punti di generazione filtro FIR dal file indicato */
Boolean ReadPoints(char * CorrFile,const TFMagType MagType,
DLReal * FilterFreqs,DLReal * FilterM,DLReal * FilterP,const int NPoints,
int SampleRate)
{
/* File gestione IO */
FILE * IOF;
/* Variabili ausiliarie */
int I;
float Freq;
float Mag;
float Phase;
char InStr[256];
/* Apre il file di correzione */
if ((IOF = fopen(CorrFile,"rt")) == NULL)
{
perror("\nUnable to open correction file.");
return False;
}
/* Legge i valori */
for (I = 0; I < NPoints; I++)
{
if (fgets(InStr,256,IOF) == NULL)
{
perror("\nError reading correction file");
return False;
}
Phase = 0;
if (sscanf(InStr,"%f %f %f",&Freq,&Mag,&Phase) < 2)
{
printf("Not enough parameters on line %d.",I);
sputs("Error reading correction file.");
return False;
}
/* Verifica il tipo di ampiezza */
if (MagType == MAGdB)
/* Ricava l'ampiezza assoluta dai dB */
Mag = (DLReal) pow(10.0,Mag / 20.0);
/* Imposta i punti per il filtro */
FilterFreqs[I] = (DLReal) (2 * Freq) / SampleRate;
FilterM[I] = (DLReal) Mag;
FilterP[I] = (DLReal) ((Phase * M_PI) / 180);
}
FilterFreqs[NPoints - 1] = (DLReal) 1.0;
/* Chiude il file di input */
fclose(IOF);
/* Operazione completata */
return True;
}
/* Integra due funzioni di trsferimento definite per punti, usando
una interpolazione lineare, ritorna il numero di punti generati,
che non sono mai pi di NPoints1 + NPoints2 */
int LITFMerge(DLReal * FilterFreqs1,DLComplex * FilterPoints1,const int NPoints1,
DLReal * FilterFreqs2,DLComplex * FilterPoints2,const int NPoints2,
DLReal * FilterFreqsOut,DLComplex * FilterPointsOut)
{
/* Indice sull'array di output */
int OI;
/* Indice sugli array di ingresso */
int I1;
int I2;
/* Calcolo interpolazione */
DLReal DMag;
DLReal DArg;
DLReal DFreq;
/* Inizializza gli indici ciclo interpolazione */
OI = 0;
I1 = 0;
I2 = 0;
/* Ciclo interpolazione */
while (I1 < NPoints1 || I2 < NPoints2)
{
if (FilterFreqs1[I1] == FilterFreqs2[I2])
{
/* Calcola il punto di uscita */
FilterFreqsOut[OI] = FilterFreqs1[I1];
FilterPointsOut[OI] = FilterPoints1[I1] * FilterPoints2[I2];
/* Avanza gli indici elaborati */
I1++;
I2++;
}
else
if (FilterFreqs1[I1] > FilterFreqs2[I2])
{
/* Calcola la frequeunza del punto di uscita */
FilterFreqsOut[OI] = FilterFreqs2[I2];
/* Calcola le variazioni per l'interpolazione */
DMag = std::abs(FilterPoints1[I1]) -
std::abs(FilterPoints1[I1 - 1]);
DArg = std::arg(FilterPoints1[I1]) -
std::arg(FilterPoints1[I1 - 1]);
DFreq = FilterFreqs1[I1] -
FilterFreqs1[I1 - 1];
/* Calcola il punto di uscita */
FilterPointsOut[OI] = FilterPoints2[I2] *
std::polar(std::abs(FilterPoints1[I1 - 1]) +
(FilterFreqsOut[OI] - FilterFreqs1[I1 - 1]) * DMag / DFreq,
std::arg(FilterPoints1[I1 - 1]) +
(FilterFreqsOut[OI] - FilterFreqs1[I1 - 1]) * DArg / DFreq);
/* Avanza l'indice elaborato */
I2++;
}
else
{
/* Calcola la frequeunza del punto di uscita */
FilterFreqsOut[OI] = FilterFreqs1[I1];
/* Calcola le variazioni per l'interpolazione */
DMag = std::abs(FilterPoints2[I2]) -
std::abs(FilterPoints2[I2 - 1]);
DArg = std::arg(FilterPoints2[I2]) -
std::arg(FilterPoints2[I2 - 1]);
DFreq = FilterFreqs2[I2] -
FilterFreqs2[I2 - 1];
/* Calcola il punto di uscita */
FilterPointsOut[OI] = FilterPoints1[I1] *
std::polar(std::abs(FilterPoints2[I2 - 1]) +
(FilterFreqsOut[OI] - FilterFreqs2[I2 - 1]) * DMag / DFreq,
std::arg(FilterPoints2[I2 - 1]) +
(FilterFreqsOut[OI] - FilterFreqs2[I2 - 1]) * DArg / DFreq);
/* Avanza l'indice elaborato */
I1++;
}
/* Avanza l'indice di uscita */
OI++;
}
/* Ritorna il numero punti generati */
return OI;
}
/* Trova il valore massimo all'interno di un file. Versione float 64 bit. */
static int FindMaxPcmFloat64Bit(const char * FName)
{
DRCFileDouble RWD;
int MaxPos;
int Pos;
DRCFileDouble PcmMax;
/* File gestione IO */
FILE * IOF;
/* Apre il file di input */
if ((IOF = fopen(FName,"rb")) == NULL)
{
perror("\nUnable to open input file.");
return -1;
}
/* Ciclo ricerca massimo */
Pos = 0;
MaxPos = 0;
PcmMax = 0;
while(feof(IOF) == 0)
{
if (fread((void *) &RWD,sizeof(DRCFileDouble),1,IOF) != 1)
{
if (feof(IOF) == 0)
{
perror("\nError reading input file.");
return -1;
}
}
if (((DRCFileFloat) fabs(RWD)) > PcmMax)
{
PcmMax = (DRCFileFloat) fabs(RWD);
MaxPos = Pos;
}
Pos++;
}
/* Chiude il file di input */
fclose(IOF);
/* Operazione completata */
return MaxPos;
}
/* Trova il valore massimo all'interno di un file. Versione float 32 bit. */
static int FindMaxPcmFloat32Bit(const char * FName)
{
DRCFileFloat RWF;
int MaxPos;
int Pos;
DRCFileFloat PcmMax;
/* File gestione IO */
FILE * IOF;
/* Apre il file di input */
if ((IOF = fopen(FName,"rb")) == NULL)
{
perror("\nUnable to open input file.");
return -1;
}
/* Ciclo ricerca massimo */
Pos = 0;
MaxPos = 0;
PcmMax = 0;
while(feof(IOF) == 0)
{
if (fread((void *) &RWF,sizeof(DRCFileFloat),1,IOF) != 1)
{
if (feof(IOF) == 0)
{
perror("\nError reading input file.");
return -1;
}
}
if (((DRCFileFloat) fabs(RWF)) > PcmMax)
{
PcmMax = (DRCFileFloat) fabs(RWF);
MaxPos = Pos;
}
Pos++;
}
/* Chiude il file di input */
fclose(IOF);
/* Operazione completata */
return MaxPos;
}
/* Trova il valore massimo all'interno di un file. Versione int 16 Bit. */
static int FindMaxPcmInt16Bit(const char * FName)
{
DRCFileInt RWI;
int MaxPos;
int Pos;
DRCFileInt PcmMax;
/* File gestione IO */
FILE * IOF;
/* Apre il file di input */
if ((IOF = fopen(FName,"rb")) == NULL)
{
perror("\nUnable to open input file.");
return -1;
}
/* Ciclo ricerca massimo */
Pos = 0;
MaxPos = 0;
PcmMax = 0;
while(feof(IOF) == 0)
{
if (fread((void *) &RWI,sizeof(DRCFileInt),1,IOF) != 1)
{
if (feof(IOF) == 0)
{
perror("\nError reading input file.");
return -1;
}
}
if (((DRCFileInt) abs(RWI)) > PcmMax)
{
PcmMax = (DRCFileInt) abs(RWI);
MaxPos = Pos;
}
Pos++;
}
/* Chiude il file di input */
fclose(IOF);
/* Operazione completata */
return MaxPos;
}
/* Trova il valore massimo all'interno di un file. */
int FindMaxPcm(const char * FName,const IFileType FType)
{
/* Controlla il tipo file */
switch (FType)
{
case PcmFloat64Bit:
return FindMaxPcmFloat64Bit(FName);
case PcmFloat32Bit:
return FindMaxPcmFloat32Bit(FName);
case PcmInt16Bit:
return FindMaxPcmInt16Bit(FName);
}
/* Tipo file errato */
return -1;
}
drc-3.2.2/source/target/ 0000755 0000764 0000145 00000000000 13165107361 014042 5 ustar denis itadm drc-3.2.2/source/target/48.0 kHz/ 0000755 0000764 0000145 00000000000 13165107361 015150 5 ustar denis itadm drc-3.2.2/source/target/48.0 kHz/pa-48.0.txt 0000644 0000764 0000145 00000000121 11320622144 016662 0 ustar denis itadm 0 -30.0
10 -10.0
20 0.00
22.4 0.00
18000 0.00
20000 0.00
22000 -3.00
24000 -30.0
drc-3.2.2/source/target/48.0 kHz/bk-2-48.0.txt 0000644 0000764 0000145 00000000121 11320622144 017015 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
200 0.00
12800 -3.00
20000 -3.50
21500 -10.0
24000 -20.0 drc-3.2.2/source/target/48.0 kHz/bk-3-spline-48.0.txt 0000644 0000764 0000145 00000000151 11320622144 020311 0 ustar denis itadm 0 -40.0
18 0.00
19 0.00
20 0.00
50 0.00
100 0.00
150 0.00
19900 -3.95
20000 -4.00
20500 -4.00
24000 -40.0 drc-3.2.2/source/target/48.0 kHz/bk-3-48.0.txt 0000644 0000764 0000145 00000000121 11320622144 017016 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
100 0.00
12800 -3.50
20000 -4.00
21500 -10.0
24000 -20.0 drc-3.2.2/source/target/48.0 kHz/bk-2-spline-48.0.txt 0000644 0000764 0000145 00000000152 11320622144 020311 0 ustar denis itadm 0 -40.0
18 0.00
19 0.00
20 0.00
150 0.00
200 0.00
250 0.00
19900 -3.45
20000 -3.50
20500 -3.50
24000 -40.0 drc-3.2.2/source/target/48.0 kHz/bk-spline-48.0.txt 0000644 0000764 0000145 00000000152 11320622144 020152 0 ustar denis itadm 0 -40.0
18 0.00
19 0.00
20 0.00
350 0.00
400 0.00
450 0.00
19900 -5.95
20000 -6.00
20500 -6.00
24000 -40.0 drc-3.2.2/source/target/48.0 kHz/ultra-48.0.txt 0000644 0000764 0000145 00000000051 11320622144 017413 0 ustar denis itadm 0 0.00
20000 0.00
21500 -10.0
24000 -20.0 drc-3.2.2/source/target/48.0 kHz/bk-2-sub-48.0.txt 0000644 0000764 0000145 00000000123 11320622144 017606 0 ustar denis itadm 0 -200.0
16 -120.0
18 0.00
200 0.00
12800 -3.00
20000 -3.50
21500 -10.0
24000 -20.0 drc-3.2.2/source/target/48.0 kHz/bk-48.0.txt 0000644 0000764 0000145 00000000121 11320622144 016656 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
400 0.00
12800 -5.00
20000 -6.00
21500 -10.0
24000 -20.0 drc-3.2.2/source/target/48.0 kHz/flat-48.0.txt 0000644 0000764 0000145 00000000017 11320622144 017214 0 ustar denis itadm 0 0.0
24000 0.0 drc-3.2.2/source/target/48.0 kHz/subultra-48.0.txt 0000644 0000764 0000145 00000000073 11320622144 020131 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
20000 0.00
21500 -10.0
24000 -20.0 drc-3.2.2/source/target/48.0 kHz/bk-3-sub-48.0.txt 0000644 0000764 0000145 00000000123 11320622144 017607 0 ustar denis itadm 0 -200.0
16 -120.0
18 0.00
100 0.00
12800 -3.50
20000 -4.00
21500 -10.0
24000 -20.0 drc-3.2.2/source/target/48.0 kHz/bk-sub-spline-48.0.txt 0000644 0000764 0000145 00000000223 11320622144 020740 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
350 0.00
400 0.00
450 0.00
19900 -5.95
20000 -6.00
20500 -6.00
24000 -40.0 drc-3.2.2/source/target/48.0 kHz/bk-3-subultra-spline-48.0.txt 0000644 0000764 0000145 00000000306 11320622144 022152 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
50 0.00
100 0.00
150 0.00
19900 -3.95
20000 -4.00
20100 -4.00
20200 -98.0
20300 -200.0
20400 -200.0
20500 -200.0
24000 -200.0 drc-3.2.2/source/target/48.0 kHz/bk-2-sub-spline-48.0.txt 0000644 0000764 0000145 00000000223 11320622144 021077 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
150 0.00
200 0.00
250 0.00
19900 -3.45
20000 -3.50
20500 -3.50
24000 -40.0 drc-3.2.2/source/target/48.0 kHz/bk-3-sub-spline-48.0.txt 0000644 0000764 0000145 00000000222 11320622144 021077 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
50 0.00
100 0.00
150 0.00
19900 -3.95
20000 -4.00
20500 -4.00
24000 -40.0 drc-3.2.2/source/target/48.0 kHz/bk-sub-48.0.txt 0000644 0000764 0000145 00000000123 11320622144 017447 0 ustar denis itadm 0 -200.0
16 -120.0
18 0.00
400 0.00
12800 -5.00
20000 -6.00
21500 -10.0
24000 -20.0 drc-3.2.2/source/target/96.0 kHz/ 0000755 0000764 0000145 00000000000 13165107361 015153 5 ustar denis itadm drc-3.2.2/source/target/96.0 kHz/bk-3-96.0.txt 0000644 0000764 0000145 00000000121 11320622157 017030 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
100 0.00
12800 -3.50
20000 -4.00
21500 -10.0
48000 -20.0 drc-3.2.2/source/target/96.0 kHz/bk-2-spline-96.0.txt 0000644 0000764 0000145 00000000152 11320622157 020323 0 ustar denis itadm 0 -40.0
18 0.00
19 0.00
20 0.00
150 0.00
200 0.00
250 0.00
19900 -3.45
20000 -3.50
20500 -3.50
48000 -40.0 drc-3.2.2/source/target/96.0 kHz/bk-3-spline-96.0.txt 0000644 0000764 0000145 00000000151 11320622157 020323 0 ustar denis itadm 0 -40.0
18 0.00
19 0.00
20 0.00
50 0.00
100 0.00
150 0.00
19900 -3.95
20000 -4.00
20500 -4.00
48000 -40.0 drc-3.2.2/source/target/96.0 kHz/pa-96.0.txt 0000644 0000764 0000145 00000000121 11320622157 016674 0 ustar denis itadm 0 -30.0
10 -10.0
20 0.00
22.4 0.00
18000 0.00
20000 0.00
34000 -3.00
48000 -30.0
drc-3.2.2/source/target/96.0 kHz/bk-2-sub-spline-96.0.txt 0000644 0000764 0000145 00000000223 11320622157 021111 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
150 0.00
200 0.00
250 0.00
19900 -3.45
20000 -3.50
20500 -3.50
48000 -40.0 drc-3.2.2/source/target/96.0 kHz/bk-2-96.0.txt 0000644 0000764 0000145 00000000121 11320622157 017027 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
200 0.00
12800 -3.00
20000 -3.50
21500 -10.0
48000 -20.0 drc-3.2.2/source/target/96.0 kHz/bk-spline-96.0.txt 0000644 0000764 0000145 00000000152 11320622157 020164 0 ustar denis itadm 0 -40.0
18 0.00
19 0.00
20 0.00
350 0.00
400 0.00
450 0.00
19900 -5.95
20000 -6.00
20500 -6.00
48000 -40.0 drc-3.2.2/source/target/96.0 kHz/bk-96.0.txt 0000644 0000764 0000145 00000000121 11320622157 016670 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
400 0.00
12800 -5.00
20000 -6.00
21500 -10.0
48000 -20.0 drc-3.2.2/source/target/96.0 kHz/bk-3-subultra-spline-96.0.txt 0000644 0000764 0000145 00000000306 11320622157 022164 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
50 0.00
100 0.00
150 0.00
19900 -3.95
20000 -4.00
20100 -4.00
20200 -98.0
20300 -200.0
20400 -200.0
20500 -200.0
48000 -200.0 drc-3.2.2/source/target/96.0 kHz/bk-2-sub-96.0.txt 0000644 0000764 0000145 00000000123 11320622157 017620 0 ustar denis itadm 0 -200.0
16 -120.0
18 0.00
200 0.00
12800 -3.00
20000 -3.50
21500 -10.0
48000 -20.0 drc-3.2.2/source/target/96.0 kHz/subultra-96.0.txt 0000644 0000764 0000145 00000000073 11320622157 020143 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
20000 0.00
21500 -10.0
48000 -20.0 drc-3.2.2/source/target/96.0 kHz/ultra-96.0.txt 0000644 0000764 0000145 00000000051 11320622157 017425 0 ustar denis itadm 0 0.00
20000 0.00
21500 -10.0
48000 -20.0 drc-3.2.2/source/target/96.0 kHz/bk-3-sub-spline-96.0.txt 0000644 0000764 0000145 00000000222 11320622157 021111 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
50 0.00
100 0.00
150 0.00
19900 -3.95
20000 -4.00
20500 -4.00
48000 -40.0 drc-3.2.2/source/target/96.0 kHz/bk-sub-96.0.txt 0000644 0000764 0000145 00000000123 11320622157 017461 0 ustar denis itadm 0 -200.0
16 -120.0
18 0.00
400 0.00
12800 -5.00
20000 -6.00
21500 -10.0
48000 -20.0 drc-3.2.2/source/target/96.0 kHz/bk-3-sub-96.0.txt 0000644 0000764 0000145 00000000123 11320622157 017621 0 ustar denis itadm 0 -200.0
16 -120.0
18 0.00
100 0.00
12800 -3.50
20000 -4.00
21500 -10.0
48000 -20.0 drc-3.2.2/source/target/96.0 kHz/flat-96.0.txt 0000644 0000764 0000145 00000000017 11320622157 017226 0 ustar denis itadm 0 0.0
48000 0.0 drc-3.2.2/source/target/96.0 kHz/bk-sub-spline-96.0.txt 0000644 0000764 0000145 00000000223 11320622157 020752 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
350 0.00
400 0.00
450 0.00
19900 -5.95
20000 -6.00
20500 -6.00
48000 -40.0 drc-3.2.2/source/target/44.1 kHz/ 0000755 0000764 0000145 00000000000 13165107360 015144 5 ustar denis itadm drc-3.2.2/source/target/44.1 kHz/bk-sub-spline-44.1.txt 0000644 0000764 0000145 00000000223 11320622136 020733 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
350 0.00
400 0.00
450 0.00
19900 -5.95
20000 -6.00
20500 -6.00
22050 -40.0 drc-3.2.2/source/target/44.1 kHz/bk-3-spline-44.1.txt 0000644 0000764 0000145 00000000151 11320622136 020304 0 ustar denis itadm 0 -40.0
18 0.00
19 0.00
20 0.00
50 0.00
100 0.00
150 0.00
19900 -3.95
20000 -4.00
20500 -4.00
22050 -40.0 drc-3.2.2/source/target/44.1 kHz/subultra-44.1.txt 0000644 0000764 0000145 00000000073 11320622136 020124 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
20000 0.00
21500 -10.0
22050 -20.0 drc-3.2.2/source/target/44.1 kHz/bk-2-sub-spline-44.1.txt 0000644 0000764 0000145 00000000223 11320622136 021072 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
150 0.00
200 0.00
250 0.00
19900 -3.45
20000 -3.50
20500 -3.50
22050 -40.0 drc-3.2.2/source/target/44.1 kHz/bk-sub-44.1.txt 0000644 0000764 0000145 00000000123 11320622136 017442 0 ustar denis itadm 0 -200.0
16 -120.0
18 0.00
400 0.00
12800 -5.00
20000 -6.00
21500 -10.0
22050 -20.0 drc-3.2.2/source/target/44.1 kHz/pa-44.1.txt 0000644 0000764 0000145 00000000121 11320622136 016655 0 ustar denis itadm 0 -30.0
10 -10.0
20 0.00
22.4 0.00
18000 0.00
20000 0.00
21000 -3.00
22050 -30.0
drc-3.2.2/source/target/44.1 kHz/bk-2-44.1.txt 0000644 0000764 0000145 00000000121 11320622136 017010 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
200 0.00
12800 -3.00
20000 -3.50
21500 -10.0
22050 -20.0 drc-3.2.2/source/target/44.1 kHz/bk-2-spline-44.1.txt 0000644 0000764 0000145 00000000152 11320622136 020304 0 ustar denis itadm 0 -40.0
18 0.00
19 0.00
20 0.00
150 0.00
200 0.00
250 0.00
19900 -3.45
20000 -3.50
20500 -3.50
22050 -40.0 drc-3.2.2/source/target/44.1 kHz/ultra-44.1.txt 0000644 0000764 0000145 00000000051 11320622136 017406 0 ustar denis itadm 0 0.00
20000 0.00
21500 -10.0
22050 -20.0 drc-3.2.2/source/target/44.1 kHz/flat-44.1.txt 0000644 0000764 0000145 00000000017 11320622136 017207 0 ustar denis itadm 0 0.0
22050 0.0 drc-3.2.2/source/target/44.1 kHz/bk-spline-44.1.txt 0000644 0000764 0000145 00000000152 11320622136 020145 0 ustar denis itadm 0 -40.0
18 0.00
19 0.00
20 0.00
350 0.00
400 0.00
450 0.00
19900 -5.95
20000 -6.00
20500 -6.00
22050 -40.0 drc-3.2.2/source/target/44.1 kHz/bk-3-sub-44.1.txt 0000644 0000764 0000145 00000000123 11320622136 017602 0 ustar denis itadm 0 -200.0
16 -120.0
18 0.00
100 0.00
12800 -3.50
20000 -4.00
21500 -10.0
22050 -20.0 drc-3.2.2/source/target/44.1 kHz/bk-44.1.txt 0000644 0000764 0000145 00000000121 11320622136 016651 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
400 0.00
12800 -5.00
20000 -6.00
21500 -10.0
22050 -20.0 drc-3.2.2/source/target/44.1 kHz/bk-3-44.1.txt 0000644 0000764 0000145 00000000121 11320622136 017011 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
100 0.00
12800 -3.50
20000 -4.00
21500 -10.0
22050 -20.0 drc-3.2.2/source/target/44.1 kHz/bk-3-sub-spline-44.1.txt 0000644 0000764 0000145 00000000222 11320622136 021072 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
50 0.00
100 0.00
150 0.00
19900 -3.95
20000 -4.00
20500 -4.00
22050 -40.0 drc-3.2.2/source/target/44.1 kHz/bk-3-subultra-spline-44.1.txt 0000644 0000764 0000145 00000000306 11320622136 022145 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
50 0.00
100 0.00
150 0.00
19900 -3.95
20000 -4.00
20100 -4.00
20200 -98.0
20300 -200.0
20400 -200.0
20500 -200.0
22050 -200.0 drc-3.2.2/source/target/44.1 kHz/bk-2-sub-44.1.txt 0000644 0000764 0000145 00000000123 11320622136 017601 0 ustar denis itadm 0 -200.0
16 -120.0
18 0.00
200 0.00
12800 -3.00
20000 -3.50
21500 -10.0
22050 -20.0 drc-3.2.2/source/target/88.2 kHz/ 0000755 0000764 0000145 00000000000 13165107360 015155 5 ustar denis itadm drc-3.2.2/source/target/88.2 kHz/ultra-88.2.txt 0000644 0000764 0000145 00000000051 11320622152 017426 0 ustar denis itadm 0 0.00
20000 0.00
21500 -10.0
44100 -20.0 drc-3.2.2/source/target/88.2 kHz/bk-sub-88.2.txt 0000644 0000764 0000145 00000000123 11320622152 017462 0 ustar denis itadm 0 -200.0
16 -120.0
18 0.00
400 0.00
12800 -5.00
20000 -6.00
21500 -10.0
44100 -20.0 drc-3.2.2/source/target/88.2 kHz/bk-2-88.2.txt 0000644 0000764 0000145 00000000121 11320622152 017030 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
200 0.00
12800 -3.00
20000 -3.50
21500 -10.0
44100 -20.0 drc-3.2.2/source/target/88.2 kHz/flat-88.2.txt 0000644 0000764 0000145 00000000017 11320622152 017227 0 ustar denis itadm 0 0.0
44100 0.0 drc-3.2.2/source/target/88.2 kHz/bk-3-subultra-spline-88.2.txt 0000644 0000764 0000145 00000000306 11320622152 022165 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
50 0.00
100 0.00
150 0.00
19900 -3.95
20000 -4.00
20100 -4.00
20200 -98.0
20300 -200.0
20400 -200.0
20500 -200.0
44100 -200.0 drc-3.2.2/source/target/88.2 kHz/subultra-88.2.txt 0000644 0000764 0000145 00000000073 11320622152 020144 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
20000 0.00
21500 -10.0
44100 -20.0 drc-3.2.2/source/target/88.2 kHz/bk-3-88.2.txt 0000644 0000764 0000145 00000000121 11320622152 017031 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
100 0.00
12800 -3.50
20000 -4.00
21500 -10.0
44100 -20.0 drc-3.2.2/source/target/88.2 kHz/bk-sub-spline-88.2.txt 0000644 0000764 0000145 00000000223 11320622152 020753 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
350 0.00
400 0.00
450 0.00
19900 -5.95
20000 -6.00
20500 -6.00
44100 -40.0 drc-3.2.2/source/target/88.2 kHz/bk-2-sub-spline-88.2.txt 0000644 0000764 0000145 00000000223 11320622152 021112 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
150 0.00
200 0.00
250 0.00
19900 -3.45
20000 -3.50
20500 -3.50
44100 -40.0 drc-3.2.2/source/target/88.2 kHz/bk-88.2.txt 0000644 0000764 0000145 00000000121 11320622152 016671 0 ustar denis itadm 0 -20.0
10 -10.0
20 0.00
400 0.00
12800 -5.00
20000 -6.00
21500 -10.0
44100 -20.0 drc-3.2.2/source/target/88.2 kHz/bk-2-sub-88.2.txt 0000644 0000764 0000145 00000000123 11320622152 017621 0 ustar denis itadm 0 -200.0
16 -120.0
18 0.00
200 0.00
12800 -3.00
20000 -3.50
21500 -10.0
44100 -20.0 drc-3.2.2/source/target/88.2 kHz/bk-3-spline-88.2.txt 0000644 0000764 0000145 00000000151 11320622152 020324 0 ustar denis itadm 0 -40.0
18 0.00
19 0.00
20 0.00
50 0.00
100 0.00
150 0.00
19900 -3.95
20000 -4.00
20500 -4.00
44100 -40.0 drc-3.2.2/source/target/88.2 kHz/bk-3-sub-spline-88.2.txt 0000644 0000764 0000145 00000000222 11320622152 021112 0 ustar denis itadm 0 -200.0
14 -200.0
15 -200.0
16 -200.0
17 -100.0
18 0.00
19 0.00
20 0.00
50 0.00
100 0.00
150 0.00
19900 -3.95
20000 -4.00
20500 -4.00
44100 -40.0 drc-3.2.2/source/target/88.2 kHz/pa-88.2.txt 0000644 0000764 0000145 00000000121 11320622152 016675 0 ustar denis itadm 0 -30.0
10 -10.0
20 0.00
22.4 0.00
18000 0.00
20000 0.00
32050 -3.00
44100 -30.0
drc-3.2.2/source/target/88.2 kHz/bk-2-spline-88.2.txt 0000644 0000764 0000145 00000000152 11320622152 020324 0 ustar denis itadm 0 -40.0
18 0.00
19 0.00
20 0.00
150 0.00
200 0.00
250 0.00
19900 -3.45
20000 -3.50
20500 -3.50
44100 -40.0 drc-3.2.2/source/target/88.2 kHz/bk-3-sub-88.2.txt 0000644 0000764 0000145 00000000123 11320622152 017622 0 ustar denis itadm 0 -200.0
16 -120.0
18 0.00
100 0.00
12800 -3.50
20000 -4.00
21500 -10.0
44100 -20.0 drc-3.2.2/source/target/88.2 kHz/bk-spline-88.2.txt 0000644 0000764 0000145 00000000152 11320622152 020165 0 ustar denis itadm 0 -40.0
18 0.00
19 0.00
20 0.00
350 0.00
400 0.00
450 0.00
19900 -5.95
20000 -6.00
20500 -6.00
44100 -40.0 drc-3.2.2/source/bwprefilt.cpp 0000644 0000764 0000145 00000014536 13165104476 015273 0 ustar denis itadm /****************************************************************************
DRC: Digital Room Correction
Copyright (C) 2002, 2003 Denis Sbragion
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
You can contact the author on Internet at the following address:
d.sbragion@neomerica.it
****************************************************************************/
/* Prefiltratura a bande di un segnale */
#include
#include "bwprefilt.h"
#include "convol.h"
#include "fir.h"
#include "level.h"
/* Memory leaks debugger */
#ifdef DebugMLeaks
#include "debug_new.h"
#endif
/* Calcolo potenza intera di un numero */
DLReal IntPow(DLReal X,unsigned int N)
{
unsigned int I;
DLReal Pow = 1;
for(I = 1;I <= N;I <<= 1)
{
if ((I & N) != 0)
Pow *= X;
X *= X;
}
return(Pow);
}
/* Prefiltratura a bande di un segnale */
void BWPreFilt(const DLReal * InImp, const int IBS, const int FBS,
const int FilterLen, const int BandSplit, const DLReal WindowExponent,
const int SampleFreq, const DLReal StartFreq, const DLReal EndFreq,
const int WindowGap, DLReal * OutImp,
const WindowType WType, const BWPPrefilteringType BWPType)
{
/* Array risultati parziali */
DLReal * COut;
/* Array filtro FIR */
DLReal * FIRFilter;
/* Array finestratura segnale di ingresso */
DLReal * CIn;
/* Array temporanei convoluzione */
DLComplex * CA;
DLComplex * CB;
/* Numero banda corrente */
int Band;
/* Estremi della banda. */
DLReal BLow;
DLReal BHigh;
/* Larghezza banda */
DLReal BWidth;
/* Inizio e fine filtratura */
DLReal FilterBegin;
DLReal FilterEnd;
/* Posizione finestra su segnale */
int WStart;
int WLen = 0;
int I;
int OBS;
/* Coefficienti calcolo finestra su segnale */
DLReal A = 0;
DLReal Q = 0;
DLReal B = 0;
/* Calcola la dimensione del blocco in uscita dalla convoluzione */
OBS = IBS + FilterLen - 1;
/* Calcola inizio e fine della prefiltratura */
FilterBegin = (2 * StartFreq) / SampleFreq;
FilterEnd = (2 * EndFreq) / SampleFreq;
/* Alloca gli array temporanei */
CIn = new DLReal[IBS];
COut = new DLReal[OBS];
FIRFilter = new DLReal[FilterLen];
/* Calcola la dimensione degli array di appoggio convoluzione */
for (I = 1; I < OBS; I <<= 1)
{
}
/* Alloca gli array di appoggio convoluzione */
CA = new DLComplex[I];
CB = new DLComplex[I];
/* Imposta i parametri iniziali */
Band = 0;
BLow = 0;
BHigh = 0;
BWidth = (DLReal) pow(2,1.0/BandSplit);
/* Verifica il tipo di curva di prefiltratura */
switch (BWPType)
{
/* Proporzionale */
case BWPProportional:
/* Calcola i coefficienti per il calcolo finestratura */
B = (DLReal) exp(log(((DLReal) FBS) / IBS) / WindowExponent);
Q = (DLReal) (B * FilterEnd - FilterBegin) / (1.0 - B);
A = (DLReal) (1.0 / (IBS * pow(FilterBegin + Q,WindowExponent)));
break;
/* Bilineare */
case BWPBilinear:
/* Calcola i coefficienti per il calcolo finestratura */
A = (DLReal) (IBS - FBS);
Q = (DLReal) ((pow(WindowExponent,4.0) * (FilterBegin / FilterEnd)) - 1.0);
B = (DLReal) (Q + 1.0);
break;
}
/* Ciclo sulle bande */
while (BHigh < FilterEnd)
{
/* Calcola gli estremi banda */
if (Band == 0)
BLow = 0;
else
BLow = (DLReal) (FilterBegin * IntPow(BWidth,Band - 1));
BHigh = (DLReal) (FilterBegin * IntPow(BWidth,Band));
if (BHigh > FilterEnd)
BHigh = 1.0;
/* Verifica la banda di finestratura */
if (Band == 0)
WLen = IBS;
else
{
/* Verifica il tipo di curva di prefiltratura */
switch (BWPType)
{
/* Proporzionale */
case BWPProportional:
/* Calcola l'intervallo di finestratura */
WLen = 1 + (int) (ceil(0.5 / (A * pow(BHigh + Q,WindowExponent))) * 2);
break;
/* Bilineare */
case BWPBilinear:
/* Calcola l'intervallo di finestratura */
WLen = 1 + (int) (ceil(0.5 * (FBS + A * (1.0 - ((BHigh - FilterBegin) /
(B - (BHigh - FilterBegin) * Q))))) * 2);
break;
}
}
/* Controlla che non vi siano errori di arrotondamento */
if (WLen >= IBS)
WLen = ((IBS / 2) * 2) - 1;
if (WLen < FBS)
WLen = FBS;
/* Calcola il punto di partenza */
WStart = (IBS - WLen) / 2;
/* Riporta la banda */
printf("Band: %3d, %7.1f - %7.1f Hz, FIR, ", (int) Band,
(double) (BLow * SampleFreq) / 2, (double) (BHigh * SampleFreq) / 2);
fflush(stdout);
printf("wind: %6d, ", (int) WLen);
fflush(stdout);
/* Effettua la finestratura del segnale */
for (I = 0; I < IBS; I++)
CIn[I] = InImp[I];
if (WindowGap > WLen)
SpacedBlackmanWindow(&CIn[WStart],WLen,WindowGap,WType);
else
if (WLen > 2)
SpacedBlackmanWindow(&CIn[WStart],WLen,WLen - 2,WType);
else
SpacedBlackmanWindow(&CIn[WStart],WLen,0,WType);
/* Azzeramento parte esterna alla finestra */
if (WType != WRight)
for (I = 0; I < WStart; I++)
CIn[I] = 0;
if (WType != WLeft)
for (I = WStart + WLen; I < IBS; I++)
CIn[I] = 0;
/* Calcola il filtro passa banda */
BandPassFir(FIRFilter,FilterLen,BLow,BHigh);
BlackmanWindow(FIRFilter,FilterLen);
printf("conv, ");
fflush(stdout);
/* Effettua la convoluzione tra segnale e filtro */
DFftConvolve(FIRFilter,FilterLen,CIn,IBS,COut,CA,CB);
printf("sum, ");
fflush(stdout);
/* Aggiunge il segnale al segnale risultante */
for (I = 0; I < OBS; I++)
OutImp[I] += COut[I];
printf("done.\n");
fflush(stdout);
Band++;
}
/* Dealloca gli array intermedi */
delete[] CIn;
delete[] COut;
delete[] FIRFilter;
delete[] CA;
delete[] CB;
}
drc-3.2.2/source/lsconv.cbp 0000644 0000764 0000145 00000004553 13165106030 014545 0 ustar denis itadm
drc-3.2.2/source/makefile 0000644 0000764 0000145 00000010267 13165106622 014261 0 ustar denis itadm # DRC base makefile
# DRC version
VERSION=3.2.2
# Destination directory
DESTDIR=
# Where to install
INSTALL_PREFIX=$(DESTDIR)/usr
# Compiler
CC=g++
# Standard optimization settings, with support for
# default compilation flags
CFLAGS+=-O2 -I.
# Standard optimization settings,
# tested also on Mac OS X
# CFLAGS=-O -s -I.
# Standard optimization settings, for systems missing getopt
# CFLAGS=-O2 -I. -I./getopt
# i686 optimizaztions settings
# CFLAGS=-march=pentium3 -O -mfancy-math-387 -msse -mtune=pentium3 -I.
# Pentium 3 or greater optimizaztions settings with SSE support
# Be careful: -mfpmath=sse sometimes causes accuracy problems
# CFLAGS=-march=pentium3 -O -s -mfancy-math-387 -msse -mfpmath=sse -mtune=pentium3 -I.
# Same as above, but tested on recent Mac OS X
# Be careful: -mfpmath=sse sometimes causes accuracy problems
# CFLAGS=-march=pentium3 -O -s -m32 -mfancy-math-387 -msse -mfpmath=sse -mtune=pentium3 -I.
# Athlon64 settings
# CFLAGS=-march=athlon64 -O3 -s -fPIC -I.
# Vectorization settings (GCC 4 Only, experimental, only partially working)
# CFLAGS=-march=pentium3 -O3 -s -pg -g -mfancy-math-387 -msse -mfpmath=sse -mtune=pentium3 -ftree-vectorize -ftree-vectorizer-verbose=2 -I.
# Debug settings
# Warning check pedantic settings
# Strong optimization is enabled because some warning are't checked without it
# Remove the optimization options for normal debugging
# CFLAGS=-O3 -pedantic -Wextra -Wall -g -DDebugMLeaks -D_DEBUG_NEW_EMULATE_MALLOC -I. -IMLeaks
# Profiling settings
# CFLAGS=-march=pentium3 -O -pg -g -mfancy-math-387 -msse -mfpmath=sse -mtune=pentium3 -I.
# Optimization settings for glsweep
# Some of the strong optimization settings provided above may
# cause accuracy problems with glsweep. If you decide to use them
# it's better to use some specific settings for glsweep, for example like:
#
# GLSCFLAGS=-O2 -I.
#
GLSCFLAGS=$(CFLAGS)
# DRC sources
DRCSRC=baselib.cpp drc.cpp fft.cpp hd.cpp slprefilt.cpp bwprefilt.cpp convol.cpp dspwind.cpp spline.cpp fir.cpp level.cpp toeplitz.cpp kirkebyfd.cpp drccfg.cpp psychoacoustic.cpp cmdline.cpp cfgparse.cpp fftsg.c gsl/gsl_fft.c gsl/error.c gsl/stream.c minIni/minIni.c
# DRC sources for debug and warning checks
# DRCSRC=baselib.cpp drc.cpp fft.cpp hd.cpp slprefilt.cpp bwprefilt.cpp convol.cpp dspwind.cpp spline.cpp fir.cpp level.cpp toeplitz.cpp kirkebyfd.cpp drccfg.cpp psychoacoustic.cpp cmdline.cpp cfgparse.cpp fftsg.c gsl/gsl_fft.c gsl/error.c gsl/stream.c minIni/minIni.c MLeaks/debug_new.cpp
# DRC sources for systems missing getopt
# DRCSRC=baselib.cpp drc.cpp fft.cpp hd.cpp slprefilt.cpp bwprefilt.cpp convol.cpp dspwind.cpp spline.cpp fir.cpp level.cpp toeplitz.cpp kirkebyfd.cpp drccfg.cpp psychoacoustic.cpp cmdline.cpp cfgparse.cpp fftsg.c gsl/gsl_fft.c gsl/error.c gsl/stream.c minIni/minIni.c getopt/getopt.c getopt/getopt1.c
# GLSweep sources
GLSWEEPSRC=glsweep.c
# LSConv sources
LSCONVSRC=lsconv.c fftsg_h.c
# Compiled objects
OBJS=drc lsconv glsweep
# Installation definitions
CONFIG_TARGETS=config/*
TARGET_TARGETS=target/*
MIC_TARGETS=mic/*
DOC_TARGETS=readme.txt
BIN_TARGETS=drc lsconv glsweep
# Targets
ALL: drc glsweep lsconv
drc: $(DRCSRC)
$(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) -o drc $(DRCSRC) -lm -lstdc++
glsweep: $(GLSWEEPSRC)
$(CC) $(LDFLAGS) $(CPPFLAGS) $(GLSCFLAGS) -o glsweep $(GLSWEEPSRC) -lm
lsconv: $(LSCONVSRC)
$(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) -o lsconv $(LSCONVSRC) -lm
clean:
rm -f $(OBJS)
install: $(CONFIG_TARGETS) $(TARGET_TARGETS) $(MIC_TARGETS) $(DOC_TARGETS) $(BIN_TARGETS)
install -d $(INSTALL_PREFIX)/bin
install $(BIN_TARGETS) $(INSTALL_PREFIX)/bin
install -d $(INSTALL_PREFIX)/share/drc/config/
cp --recursive --no-dereference --preserve=links --no-preserve=ownership $(CONFIG_TARGETS) $(INSTALL_PREFIX)/share/drc/config/
install -d $(INSTALL_PREFIX)/share/drc/target/
cp --recursive --no-dereference --preserve=links --no-preserve=ownership $(TARGET_TARGETS) $(INSTALL_PREFIX)/share/drc/target/
install -d $(INSTALL_PREFIX)/share/drc/mic/
cp --recursive --no-dereference --preserve=links --no-preserve=ownership $(MIC_TARGETS) $(INSTALL_PREFIX)/share/drc/mic/
install -d $(INSTALL_PREFIX)/share/doc/drc-$(VERSION)/
install $(DOC_TARGETS) $(INSTALL_PREFIX)/share/doc/drc-$(VERSION)/
drc-3.2.2/source/minIni/ 0000755 0000764 0000145 00000000000 13165107360 013776 5 ustar denis itadm drc-3.2.2/source/minIni/minIni.h 0000644 0000764 0000145 00000013355 11707302012 015370 0 ustar denis itadm /* minIni - Multi-Platform INI file parser, suitable for embedded systems
*
* Copyright (c) CompuPhase, 2008-2012
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Version: $Id: minIni.h 42 2012-01-04 12:14:54Z thiadmer.riemersma $
*/
#ifndef MININI_H
#define MININI_H
#include "minGlue.h"
#if (defined _UNICODE || defined __UNICODE__ || defined UNICODE) && !defined INI_ANSIONLY
#include
#elif !defined __T
typedef char TCHAR;
#endif
#if !defined INI_BUFFERSIZE
#define INI_BUFFERSIZE 512
#endif
#if defined __cplusplus
extern "C" {
#endif
int ini_getbool(const TCHAR *Section, const TCHAR *Key, int DefValue, const TCHAR *Filename);
long ini_getl(const TCHAR *Section, const TCHAR *Key, long DefValue, const TCHAR *Filename);
int ini_gets(const TCHAR *Section, const TCHAR *Key, const TCHAR *DefValue, TCHAR *Buffer, int BufferSize, const TCHAR *Filename);
int ini_getsection(int idx, TCHAR *Buffer, int BufferSize, const TCHAR *Filename);
int ini_getkey(const TCHAR *Section, int idx, TCHAR *Buffer, int BufferSize, const TCHAR *Filename);
#if defined INI_REAL
INI_REAL ini_getf(const TCHAR *Section, const TCHAR *Key, INI_REAL DefValue, const TCHAR *Filename);
#endif
#if !defined INI_READONLY
int ini_putl(const TCHAR *Section, const TCHAR *Key, long Value, const TCHAR *Filename);
int ini_puts(const TCHAR *Section, const TCHAR *Key, const TCHAR *Value, const TCHAR *Filename);
#if defined INI_REAL
int ini_putf(const TCHAR *Section, const TCHAR *Key, INI_REAL Value, const TCHAR *Filename);
#endif
#endif /* INI_READONLY */
#if !defined INI_NOBROWSE
typedef int (*INI_CALLBACK)(const TCHAR *Section, const TCHAR *Key, const TCHAR *Value, const void *UserData);
int ini_browse(INI_CALLBACK Callback, const void *UserData, const TCHAR *Filename);
#endif /* INI_NOBROWSE */
#if defined __cplusplus
}
#endif
#if defined __cplusplus
#if defined __WXWINDOWS__
#include "wxMinIni.h"
#else
#include
/* The C++ class in minIni.h was contributed by Steven Van Ingelgem. */
class minIni
{
public:
minIni(const std::string& filename) : iniFilename(filename)
{ }
bool getbool(const std::string& Section, const std::string& Key, bool DefValue=false) const
{ return static_cast(ini_getbool(Section.c_str(), Key.c_str(), int(DefValue), iniFilename.c_str())); }
long getl(const std::string& Section, const std::string& Key, long DefValue=0) const
{ return ini_getl(Section.c_str(), Key.c_str(), DefValue, iniFilename.c_str()); }
int geti(const std::string& Section, const std::string& Key, int DefValue=0) const
{ return static_cast(this->getl(Section, Key, long(DefValue))); }
std::string gets(const std::string& Section, const std::string& Key, const std::string& DefValue="") const
{
char buffer[INI_BUFFERSIZE];
ini_gets(Section.c_str(), Key.c_str(), DefValue.c_str(), buffer, INI_BUFFERSIZE, iniFilename.c_str());
return buffer;
}
std::string getsection(int idx) const
{
char buffer[INI_BUFFERSIZE];
ini_getsection(idx, buffer, INI_BUFFERSIZE, iniFilename.c_str());
return buffer;
}
std::string getkey(const std::string& Section, int idx) const
{
char buffer[INI_BUFFERSIZE];
ini_getkey(Section.c_str(), idx, buffer, INI_BUFFERSIZE, iniFilename.c_str());
return buffer;
}
#if defined INI_REAL
INI_REAL getf(const std::string& Section, const std::string& Key, INI_REAL DefValue=0) const
{ return ini_getf(Section.c_str(), Key.c_str(), DefValue, iniFilename.c_str()); }
#endif
#if ! defined INI_READONLY
bool put(const std::string& Section, const std::string& Key, long Value) const
{ return (bool)ini_putl(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()); }
bool put(const std::string& Section, const std::string& Key, int Value) const
{ return (bool)ini_putl(Section.c_str(), Key.c_str(), (long)Value, iniFilename.c_str()); }
bool put(const std::string& Section, const std::string& Key, bool Value) const
{ return (bool)ini_putl(Section.c_str(), Key.c_str(), (long)Value, iniFilename.c_str()); }
bool put(const std::string& Section, const std::string& Key, const std::string& Value) const
{ return (bool)ini_puts(Section.c_str(), Key.c_str(), Value.c_str(), iniFilename.c_str()); }
bool put(const std::string& Section, const std::string& Key, const char* Value) const
{ return (bool)ini_puts(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()); }
#if defined INI_REAL
bool put(const std::string& Section, const std::string& Key, INI_REAL Value) const
{ return (bool)ini_putf(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()); }
#endif
bool del(const std::string& Section, const std::string& Key) const
{ return (bool)ini_puts(Section.c_str(), Key.c_str(), 0, iniFilename.c_str()); }
bool del(const std::string& Section) const
{ return (bool)ini_puts(Section.c_str(), 0, 0, iniFilename.c_str()); }
#endif
private:
std::string iniFilename;
};
#endif /* __WXWINDOWS__ */
#endif /* __cplusplus */
#endif /* MININI_H */
drc-3.2.2/source/minIni/LICENSE 0000644 0000764 0000145 00000025047 11414637524 015020 0 ustar denis itadm
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
EXCEPTION TO THE APACHE 2.0 LICENSE
As a special exception to the Apache License 2.0 (and referring to the
definitions in Section 1 of this license), you may link, statically or
dynamically, the "Work" to other modules to produce an executable file
containing portions of the "Work", and distribute that executable file
in "Object" form under the terms of your choice, without any of the
additional requirements listed in Section 4 of the Apache License 2.0.
This exception applies only to redistributions in "Object" form (not
"Source" form) and only if no modifications have been made to the "Work".
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
drc-3.2.2/source/minIni/NOTICE 0000644 0000764 0000145 00000001023 11200251160 014660 0 ustar denis itadm minIni is a programmer's library to read and write "INI" files in embedded
systems. The library takes little resources and can be configured for various
kinds of file I/O libraries.
The method for portable INI file management in minIni is, in part based, on the
article "Multiplatform .INI Files" by Joseph J. Graf in the March 1994 issue of
Dr. Dobb's Journal.
The C++ class in minIni.h was contributed by Steven Van Ingelgem.
The option to compile minIni as a read-only library was contributed by Luca
Bassanello.
drc-3.2.2/source/minIni/minIni.pdf 0000644 0000764 0000145 00000655726 11701040400 015722 0 ustar denis itadm %PDF-1.4
%쏢
5 0 obj
<>
stream
x[YsĔ_2xAG"E#&y@Œx*?>
` gyH\sTbW
̛3q>[O]wv/B@>G; :7ndkuK[B3B@