Audacity 3.2.0
Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
FormatClassifier Class Reference

FormatClassifier classifies the sample format and endianness of raw audio files. More...

#include <FormatClassifier.h>

Collaboration diagram for FormatClassifier:
[legend]

Classes

struct  FormatClassT
 

Public Types

typedef std::vector< FormatClassTFormatVectorT
 
typedef std::vector< FormatClassT >::iterator FormatVectorIt
 

Public Member Functions

 FormatClassifier (const char *filename)
 
 ~FormatClassifier ()
 
FormatClassT GetResultFormat ()
 
int GetResultFormatLibSndfile ()
 
unsigned GetResultChannels ()
 

Private Member Functions

void Run ()
 
void ReadSignal (FormatClassT format, size_t stride)
 
void ConvertSamples (void *in, float *out, FormatClassT format)
 
void Add (float *in1, float *in2, size_t len)
 
void Sub (float *in, float subt, size_t len)
 
void Div (float *in, float div, size_t len)
 
void Abs (float *in, float *out, size_t len)
 
float Mean (float *in, size_t len)
 
float Max (float *in, size_t len)
 
float Max (float *in, size_t len, size_t *maxidx)
 
template<class T >
void ToFloat (T *in, float *out, size_t len)
 

Private Attributes

FormatVectorT mClasses
 
MultiFormatReader mReader
 
SpecPowerCalculation mMeter
 
Floats mSigBuffer { cSiglen }
 
Floats mAuxBuffer { cSiglen }
 
ArrayOf< uint8_t > mRawBuffer { cSiglen * 8 }
 
Floats mMonoFeat
 
Floats mStereoFeat
 
FormatClassT mResultFormat
 
unsigned mResultChannels { 0 }
 

Static Private Attributes

static const size_t cSiglen = 512
 
static const size_t cNumInts = 32
 

Detailed Description

FormatClassifier classifies the sample format and endianness of raw audio files.

The classifier operates in the frequency domain and exploits the low-pass-like spectral behaviour of natural audio signals for classification of the sample format and the used endianness.

Definition at line 58 of file FormatClassifier.h.

Member Typedef Documentation

◆ FormatVectorIt

typedef std::vector<FormatClassT>::iterator FormatClassifier::FormatVectorIt

Definition at line 69 of file FormatClassifier.h.

◆ FormatVectorT

Definition at line 68 of file FormatClassifier.h.

Constructor & Destructor Documentation

◆ FormatClassifier()

FormatClassifier::FormatClassifier ( const char *  filename)

Definition at line 32 of file FormatClassifier.cpp.

32 :
33 mReader(filename),
35{
36 // Define the classification classes
37 for ( auto endianness : {
40 } )
41 for ( auto format : {
48 } )
49 mClasses.push_back( { format, endianness } );
50
51 // Build feature vectors
52 mMonoFeat = Floats{ mClasses.size() };
53 mStereoFeat = Floats{ mClasses.size() };
54
55#ifdef FORMATCLASSIFIER_SIGNAL_DEBUG
56 // Build a debug writer
57 char dfile [1024];
58 sprintf(dfile, "%s.sig", filename);
59 mpWriter = std::make_unique<DebugWriter>(dfile);
60#endif
61
62 // Run it
63 Run();
64
65#ifdef FORMATCLASSIFIER_SIGNAL_DEBUG
66 for (unsigned int n = 0; n < mClasses.size(); n++)
67 {
68 wxPrintf("Class [%i] Machine [%i]: Mono: %3.7f Stereo: %3.7f\n", mClasses[n].format, mClasses[n].endian, mMonoFeat[n], mStereoFeat[n]);
69 }
70#endif
71
72}
int format
Definition: ExportPCM.cpp:56
MultiFormatReader mReader
FormatVectorT mClasses
SpecPowerCalculation mMeter
static const size_t cSiglen

References MachineEndianness::Big, MultiFormatReader::Double, MultiFormatReader::Float, format, MultiFormatReader::Int16, MultiFormatReader::Int32, MultiFormatReader::Int8, MachineEndianness::Little, mClasses, mMonoFeat, mStereoFeat, Run(), and MultiFormatReader::Uint8.

Here is the call graph for this function:

◆ ~FormatClassifier()

FormatClassifier::~FormatClassifier ( )

Definition at line 74 of file FormatClassifier.cpp.

75{
76}

Member Function Documentation

◆ Abs()

void FormatClassifier::Abs ( float *  in,
float *  out,
size_t  len 
)
private

Definition at line 294 of file FormatClassifier.cpp.

295{
296 for (unsigned int n = 0; n < len; n++)
297 {
298 if (in[n] < 0.0f)
299 {
300 out[n] = -in[n];
301 }
302 else
303 {
304 out[n] = in[n];
305 }
306 }
307}

Referenced by Run().

Here is the caller graph for this function:

◆ Add()

void FormatClassifier::Add ( float *  in1,
float *  in2,
size_t  len 
)
private

Definition at line 269 of file FormatClassifier.cpp.

270{
271 for (unsigned int n = 0; n < len; n++)
272 {
273 in1[n] += in2[n];
274 }
275}

Referenced by ReadSignal().

Here is the caller graph for this function:

◆ ConvertSamples()

void FormatClassifier::ConvertSamples ( void *  in,
float *  out,
FormatClassT  format 
)
private

Definition at line 238 of file FormatClassifier.cpp.

239{
240 switch(format.format)
241 {
243 ToFloat((int8_t*) in, out, cSiglen);
244 break;
246 ToFloat((int16_t*) in, out, cSiglen);
247 break;
249 ToFloat((int32_t*) in, out, cSiglen);
250 break;
252 ToFloat((uint8_t*) in, out, cSiglen);
253 break;
255 ToFloat((uint16_t*) in, out, cSiglen);
256 break;
258 ToFloat((uint32_t*) in, out, cSiglen);
259 break;
261 ToFloat((float*) in, out, cSiglen);
262 break;
264 ToFloat((double*) in, out, cSiglen);
265 break;
266 }
267}
void ToFloat(T *in, float *out, size_t len)

References cSiglen, MultiFormatReader::Double, MultiFormatReader::Float, format, MultiFormatReader::Int16, MultiFormatReader::Int32, MultiFormatReader::Int8, ToFloat(), MultiFormatReader::Uint16, MultiFormatReader::Uint32, and MultiFormatReader::Uint8.

Referenced by ReadSignal().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Div()

void FormatClassifier::Div ( float *  in,
float  div,
size_t  len 
)
private

Definition at line 285 of file FormatClassifier.cpp.

286{
287 for (unsigned int n = 0; n < len; n++)
288 {
289 in[n] /= div;
290 }
291}

Referenced by Run().

Here is the caller graph for this function:

◆ GetResultChannels()

unsigned FormatClassifier::GetResultChannels ( )

Definition at line 125 of file FormatClassifier.cpp.

126{
127 return mResultChannels;
128}
unsigned mResultChannels

References mResultChannels.

Referenced by ImportRawDialog::OnDetect().

Here is the caller graph for this function:

◆ GetResultFormat()

FormatClassifier::FormatClassT FormatClassifier::GetResultFormat ( )

Definition at line 78 of file FormatClassifier.cpp.

79{
80 return mResultFormat;
81}
FormatClassT mResultFormat

References mResultFormat.

◆ GetResultFormatLibSndfile()

int FormatClassifier::GetResultFormatLibSndfile ( )

Definition at line 83 of file FormatClassifier.cpp.

84{
85 int format = SF_FORMAT_RAW;
86
87 switch(mResultFormat.format)
88 {
90 format |= SF_FORMAT_PCM_S8;
91 break;
93 format |= SF_FORMAT_PCM_16;
94 break;
96 format |= SF_FORMAT_PCM_32;
97 break;
99 format |= SF_FORMAT_PCM_U8;
100 break;
102 format |= SF_FORMAT_FLOAT;
103 break;
105 format |= SF_FORMAT_DOUBLE;
106 break;
107 default:
108 format |= SF_FORMAT_PCM_16;
109 break;
110 }
111
112 switch(mResultFormat.endian)
113 {
115 format |= SF_ENDIAN_LITTLE;
116 break;
118 format |= SF_ENDIAN_BIG;
119 break;
120 }
121
122 return format;
123}
MultiFormatReader::FormatT format
MachineEndianness::EndiannessT endian

References MachineEndianness::Big, MultiFormatReader::Double, FormatClassifier::FormatClassT::endian, MultiFormatReader::Float, format, FormatClassifier::FormatClassT::format, MultiFormatReader::Int16, MultiFormatReader::Int32, MultiFormatReader::Int8, MachineEndianness::Little, mResultFormat, and MultiFormatReader::Uint8.

Referenced by ImportRawDialog::OnDetect().

Here is the caller graph for this function:

◆ Max() [1/2]

float FormatClassifier::Max ( float *  in,
size_t  len 
)
private

Definition at line 323 of file FormatClassifier.cpp.

324{
325 size_t dummyidx;
326 return Max(in, len, &dummyidx);
327}
float Max(float *in, size_t len)

References Max().

Referenced by Max(), and Run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Max() [2/2]

float FormatClassifier::Max ( float *  in,
size_t  len,
size_t *  maxidx 
)
private

Definition at line 329 of file FormatClassifier.cpp.

330{
331 float max = -FLT_MAX;
332 *maxidx = 0;
333
334 for (unsigned int n = 0; n < len; n++)
335 {
336 if (in[n] > max)
337 {
338 max = in[n];
339 *maxidx = n;
340 }
341 }
342
343 return max;
344}

◆ Mean()

float FormatClassifier::Mean ( float *  in,
size_t  len 
)
private

Definition at line 309 of file FormatClassifier.cpp.

310{
311 float mean = 0.0f;
312
313 for (unsigned int n = 0; n < len; n++)
314 {
315 mean += in[n];
316 }
317
318 mean /= len;
319
320 return mean;
321}

Referenced by Run().

Here is the caller graph for this function:

◆ ReadSignal()

void FormatClassifier::ReadSignal ( FormatClassT  format,
size_t  stride 
)
private

Definition at line 200 of file FormatClassifier.cpp.

201{
202 size_t actRead = 0;
203 unsigned int n = 0;
204
205 mReader.Reset();
206
207 // Do a dummy read of 1024 bytes to skip potential header information
209
210 do
211 {
212 actRead = mReader.ReadSamples(mRawBuffer.get(), cSiglen, stride, format.format, format.endian);
213
214 if (n == 0)
215 {
217 }
218 else
219 {
220 if (actRead == cSiglen)
221 {
223
224 // Integrate signals
225 Add(mSigBuffer.get(), mAuxBuffer.get(), cSiglen);
226
227 // Do some dummy reads to break signal coherence
228 mReader.ReadSamples(mRawBuffer.get(), n + 1, stride, format.format, format.endian);
229 }
230 }
231
232 n++;
233
234 } while ((n < cNumInts) && (actRead == cSiglen));
235
236}
void ConvertSamples(void *in, float *out, FormatClassT format)
static const size_t cNumInts
ArrayOf< uint8_t > mRawBuffer
void Add(float *in1, float *in2, size_t len)
size_t ReadSamples(void *buffer, size_t len, MultiFormatReader::FormatT format, MachineEndianness::EndiannessT end)

References Add(), cNumInts, ConvertSamples(), cSiglen, format, MachineEndianness::Little, mAuxBuffer, mRawBuffer, mReader, mSigBuffer, MultiFormatReader::ReadSamples(), MultiFormatReader::Reset(), and MultiFormatReader::Uint8.

Referenced by Run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Run()

void FormatClassifier::Run ( )
private

Definition at line 130 of file FormatClassifier.cpp.

131{
132 // Calc the mono feature vector
133 for (unsigned int n = 0; n < mClasses.size(); n++)
134 {
135 // Read the signal
136 ReadSignal(mClasses[n], 1);
137#ifdef FORMATCLASSIFIER_SIGNAL_DEBUG
138 mpWriter->WriteSignal(mSigBuffer, cSiglen);
139#endif
140
141 // Do some simple preprocessing
142 // Remove DC offset
143 float smean = Mean(mSigBuffer.get(), cSiglen);
144 Sub(mSigBuffer.get(), smean, cSiglen);
145 // Normalize to +- 1.0
146 Abs(mSigBuffer.get(), mAuxBuffer.get(), cSiglen);
147 float smax = Max(mAuxBuffer.get(), cSiglen);
148 Div(mSigBuffer.get(), smax, cSiglen);
149
150 // Now actually fill the feature vector
151 // Low to high band power ratio
152 float pLo = mMeter.CalcPower(mSigBuffer.get(), 0.15f, 0.3f);
153 float pHi = mMeter.CalcPower(mSigBuffer.get(), 0.45f, 0.1f);
154 mMonoFeat[n] = pLo / pHi;
155 }
156
157 // Calc the stereo feature vector
158 for (unsigned int n = 0; n < mClasses.size(); n++)
159 {
160 // Read the signal
161 ReadSignal(mClasses[n], 2);
162#ifdef FORMATCLASSIFIER_SIGNAL_DEBUG
163 mpWriter->WriteSignal(mSigBuffer, cSiglen);
164#endif
165
166 // Do some simple preprocessing
167 // Remove DC offset
168 float smean = Mean(mSigBuffer.get(), cSiglen);
169 Sub(mSigBuffer.get(), smean, cSiglen);
170 // Normalize to +- 1.0
171 Abs(mSigBuffer.get(), mAuxBuffer.get(), cSiglen);
172 float smax = Max(mAuxBuffer.get(), cSiglen);
173 Div(mSigBuffer.get(), smax, cSiglen);
174
175 // Now actually fill the feature vector
176 // Low to high band power ratio
177 float pLo = mMeter.CalcPower(mSigBuffer.get(), 0.15f, 0.3f);
178 float pHi = mMeter.CalcPower(mSigBuffer.get(), 0.45f, 0.1f);
179 mStereoFeat[n] = pLo / pHi;
180 }
181
182 // Get the results
183 size_t midx, sidx;
184 float monoMax = Max(mMonoFeat.get(), mClasses.size(), &midx);
185 float stereoMax = Max(mStereoFeat.get(), mClasses.size(), &sidx);
186
187 if (monoMax > stereoMax)
188 {
189 mResultChannels = 1;
190 mResultFormat = mClasses[midx];
191 }
192 else
193 {
194 mResultChannels = 2;
195 mResultFormat = mClasses[sidx];
196 }
197
198}
void Abs(float *in, float *out, size_t len)
void Sub(float *in, float subt, size_t len)
void Div(float *in, float div, size_t len)
float Mean(float *in, size_t len)
void ReadSignal(FormatClassT format, size_t stride)
float CalcPower(float *sig, float fc, float bw)

References Abs(), SpecPowerCalculation::CalcPower(), cSiglen, Div(), mAuxBuffer, Max(), mClasses, Mean(), mMeter, mMonoFeat, mResultChannels, mResultFormat, mSigBuffer, mStereoFeat, ReadSignal(), and Sub().

Referenced by FormatClassifier().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Sub()

void FormatClassifier::Sub ( float *  in,
float  subt,
size_t  len 
)
private

Definition at line 277 of file FormatClassifier.cpp.

278{
279 for (unsigned int n = 0; n < len; n++)
280 {
281 in[n] -= subt;
282 }
283}

Referenced by Run().

Here is the caller graph for this function:

◆ ToFloat()

template<class T >
void FormatClassifier::ToFloat ( T *  in,
float *  out,
size_t  len 
)
private

Definition at line 346 of file FormatClassifier.cpp.

347{
348 for(unsigned int n = 0; n < len; n++)
349 {
350 out[n] = (float) in[n];
351 }
352}

Referenced by ConvertSamples().

Here is the caller graph for this function:

Member Data Documentation

◆ cNumInts

const size_t FormatClassifier::cNumInts = 32
staticprivate

Definition at line 74 of file FormatClassifier.h.

Referenced by ReadSignal().

◆ cSiglen

const size_t FormatClassifier::cSiglen = 512
staticprivate

Definition at line 73 of file FormatClassifier.h.

Referenced by ConvertSamples(), ReadSignal(), and Run().

◆ mAuxBuffer

Floats FormatClassifier::mAuxBuffer { cSiglen }
private

Definition at line 85 of file FormatClassifier.h.

Referenced by ReadSignal(), and Run().

◆ mClasses

FormatVectorT FormatClassifier::mClasses
private

Definition at line 76 of file FormatClassifier.h.

Referenced by FormatClassifier(), and Run().

◆ mMeter

SpecPowerCalculation FormatClassifier::mMeter
private

Definition at line 78 of file FormatClassifier.h.

Referenced by Run().

◆ mMonoFeat

Floats FormatClassifier::mMonoFeat
private

Definition at line 88 of file FormatClassifier.h.

Referenced by FormatClassifier(), and Run().

◆ mRawBuffer

ArrayOf<uint8_t> FormatClassifier::mRawBuffer { cSiglen * 8 }
private

Definition at line 86 of file FormatClassifier.h.

Referenced by ReadSignal().

◆ mReader

MultiFormatReader FormatClassifier::mReader
private

Definition at line 77 of file FormatClassifier.h.

Referenced by ReadSignal().

◆ mResultChannels

unsigned FormatClassifier::mResultChannels { 0 }
private

Definition at line 92 of file FormatClassifier.h.

Referenced by GetResultChannels(), and Run().

◆ mResultFormat

FormatClassT FormatClassifier::mResultFormat
private

Definition at line 91 of file FormatClassifier.h.

Referenced by GetResultFormat(), GetResultFormatLibSndfile(), and Run().

◆ mSigBuffer

Floats FormatClassifier::mSigBuffer { cSiglen }
private

Definition at line 84 of file FormatClassifier.h.

Referenced by ReadSignal(), and Run().

◆ mStereoFeat

Floats FormatClassifier::mStereoFeat
private

Definition at line 89 of file FormatClassifier.h.

Referenced by FormatClassifier(), and Run().


The documentation for this class was generated from the following files: