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 56 of file FormatClassifier.h.

Member Typedef Documentation

◆ FormatVectorIt

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

Definition at line 67 of file FormatClassifier.h.

◆ FormatVectorT

Definition at line 66 of file FormatClassifier.h.

Constructor & Destructor Documentation

◆ FormatClassifier()

FormatClassifier::FormatClassifier ( const char *  filename)

Definition at line 31 of file FormatClassifier.cpp.

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

References MachineEndianness::Big, MultiFormatReader::Double, MultiFormatReader::Float, anonymous_namespace{ExportPCM.cpp}::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 73 of file FormatClassifier.cpp.

74{
75}

Member Function Documentation

◆ Abs()

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

Definition at line 293 of file FormatClassifier.cpp.

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

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 268 of file FormatClassifier.cpp.

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

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 237 of file FormatClassifier.cpp.

238{
239 switch(format.format)
240 {
242 ToFloat((int8_t*) in, out, cSiglen);
243 break;
245 ToFloat((int16_t*) in, out, cSiglen);
246 break;
248 ToFloat((int32_t*) in, out, cSiglen);
249 break;
251 ToFloat((uint8_t*) in, out, cSiglen);
252 break;
254 ToFloat((uint16_t*) in, out, cSiglen);
255 break;
257 ToFloat((uint32_t*) in, out, cSiglen);
258 break;
260 ToFloat((float*) in, out, cSiglen);
261 break;
263 ToFloat((double*) in, out, cSiglen);
264 break;
265 }
266}
void ToFloat(T *in, float *out, size_t len)

References cSiglen, MultiFormatReader::Double, MultiFormatReader::Float, anonymous_namespace{ExportPCM.cpp}::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 284 of file FormatClassifier.cpp.

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

Referenced by Run().

Here is the caller graph for this function:

◆ GetResultChannels()

unsigned FormatClassifier::GetResultChannels ( )

Definition at line 124 of file FormatClassifier.cpp.

125{
126 return mResultChannels;
127}
unsigned mResultChannels

References mResultChannels.

Referenced by ImportRawDialog::OnDetect().

Here is the caller graph for this function:

◆ GetResultFormat()

FormatClassifier::FormatClassT FormatClassifier::GetResultFormat ( )

Definition at line 77 of file FormatClassifier.cpp.

78{
79 return mResultFormat;
80}
FormatClassT mResultFormat

References mResultFormat.

◆ GetResultFormatLibSndfile()

int FormatClassifier::GetResultFormatLibSndfile ( )

Definition at line 82 of file FormatClassifier.cpp.

83{
84 int format = SF_FORMAT_RAW;
85
86 switch(mResultFormat.format)
87 {
89 format |= SF_FORMAT_PCM_S8;
90 break;
92 format |= SF_FORMAT_PCM_16;
93 break;
95 format |= SF_FORMAT_PCM_32;
96 break;
98 format |= SF_FORMAT_PCM_U8;
99 break;
101 format |= SF_FORMAT_FLOAT;
102 break;
104 format |= SF_FORMAT_DOUBLE;
105 break;
106 default:
107 format |= SF_FORMAT_PCM_16;
108 break;
109 }
110
111 switch(mResultFormat.endian)
112 {
114 format |= SF_ENDIAN_LITTLE;
115 break;
117 format |= SF_ENDIAN_BIG;
118 break;
119 }
120
121 return format;
122}
MultiFormatReader::FormatT format
MachineEndianness::EndiannessT endian

References MachineEndianness::Big, MultiFormatReader::Double, FormatClassifier::FormatClassT::endian, MultiFormatReader::Float, anonymous_namespace{ExportPCM.cpp}::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 322 of file FormatClassifier.cpp.

323{
324 size_t dummyidx;
325 return Max(in, len, &dummyidx);
326}
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 328 of file FormatClassifier.cpp.

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

◆ Mean()

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

Definition at line 308 of file FormatClassifier.cpp.

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

Referenced by Run().

Here is the caller graph for this function:

◆ ReadSignal()

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

Definition at line 199 of file FormatClassifier.cpp.

200{
201 size_t actRead = 0;
202 unsigned int n = 0;
203
204 mReader.Reset();
205
206 // Do a dummy read of 1024 bytes to skip potential header information
208
209 do
210 {
211 actRead = mReader.ReadSamples(mRawBuffer.get(), cSiglen, stride, format.format, format.endian);
212
213 if (n == 0)
214 {
216 }
217 else
218 {
219 if (actRead == cSiglen)
220 {
222
223 // Integrate signals
224 Add(mSigBuffer.get(), mAuxBuffer.get(), cSiglen);
225
226 // Do some dummy reads to break signal coherence
227 mReader.ReadSamples(mRawBuffer.get(), n + 1, stride, format.format, format.endian);
228 }
229 }
230
231 n++;
232
233 } while ((n < cNumInts) && (actRead == cSiglen));
234
235}
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, anonymous_namespace{ExportPCM.cpp}::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 129 of file FormatClassifier.cpp.

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

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

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 345 of file FormatClassifier.cpp.

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

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 72 of file FormatClassifier.h.

Referenced by ReadSignal().

◆ cSiglen

const size_t FormatClassifier::cSiglen = 512
staticprivate

Definition at line 71 of file FormatClassifier.h.

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

◆ mAuxBuffer

Floats FormatClassifier::mAuxBuffer { cSiglen }
private

Definition at line 83 of file FormatClassifier.h.

Referenced by ReadSignal(), and Run().

◆ mClasses

FormatVectorT FormatClassifier::mClasses
private

Definition at line 74 of file FormatClassifier.h.

Referenced by FormatClassifier(), and Run().

◆ mMeter

SpecPowerCalculation FormatClassifier::mMeter
private

Definition at line 76 of file FormatClassifier.h.

Referenced by Run().

◆ mMonoFeat

Floats FormatClassifier::mMonoFeat
private

Definition at line 86 of file FormatClassifier.h.

Referenced by FormatClassifier(), and Run().

◆ mRawBuffer

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

Definition at line 84 of file FormatClassifier.h.

Referenced by ReadSignal().

◆ mReader

MultiFormatReader FormatClassifier::mReader
private

Definition at line 75 of file FormatClassifier.h.

Referenced by ReadSignal().

◆ mResultChannels

unsigned FormatClassifier::mResultChannels { 0 }
private

Definition at line 90 of file FormatClassifier.h.

Referenced by GetResultChannels(), and Run().

◆ mResultFormat

FormatClassT FormatClassifier::mResultFormat
private

Definition at line 89 of file FormatClassifier.h.

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

◆ mSigBuffer

Floats FormatClassifier::mSigBuffer { cSiglen }
private

Definition at line 82 of file FormatClassifier.h.

Referenced by ReadSignal(), and Run().

◆ mStereoFeat

Floats FormatClassifier::mStereoFeat
private

Definition at line 87 of file FormatClassifier.h.

Referenced by FormatClassifier(), and Run().


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