Audacity  2.2.2
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>

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

Member Typedef Documentation

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

Definition at line 70 of file FormatClassifier.h.

Definition at line 69 of file FormatClassifier.h.

Constructor & Destructor Documentation

FormatClassifier::FormatClassifier ( const char *  filename)

Definition at line 33 of file FormatClassifier.cpp.

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

33  :
34  mReader(filename),
36 {
37  FormatClassT fClass;
38 
39  // Define the classification classes
40  fClass.endian = MachineEndianness::Little;
41  fClass.format = MultiFormatReader::Int8;
42  mClasses.push_back(fClass);
43  fClass.format = MultiFormatReader::Int16;
44  mClasses.push_back(fClass);
45  fClass.format = MultiFormatReader::Int32;
46  mClasses.push_back(fClass);
47  fClass.format = MultiFormatReader::Uint8;
48  mClasses.push_back(fClass);
49  fClass.format = MultiFormatReader::Float;
50  mClasses.push_back(fClass);
51  fClass.format = MultiFormatReader::Double;
52  mClasses.push_back(fClass);
53 
54  fClass.endian = MachineEndianness::Big;
55  fClass.format = MultiFormatReader::Int8;
56  mClasses.push_back(fClass);
57  fClass.format = MultiFormatReader::Int16;
58  mClasses.push_back(fClass);
59  fClass.format = MultiFormatReader::Int32;
60  mClasses.push_back(fClass);
61  fClass.format = MultiFormatReader::Uint8;
62  mClasses.push_back(fClass);
63  fClass.format = MultiFormatReader::Float;
64  mClasses.push_back(fClass);
65  fClass.format = MultiFormatReader::Double;
66  mClasses.push_back(fClass);
67 
68  // Build feature vectors
69  mMonoFeat = Floats{ mClasses.size() };
70  mStereoFeat = Floats{ mClasses.size() };
71 
72 #ifdef FORMATCLASSIFIER_SIGNAL_DEBUG
73  // Build a debug writer
74  char dfile [1024];
75  sprintf(dfile, "%s.sig", filename);
76  mpWriter = std::make_unique<DebugWriter>(dfile);
77 #endif
78 
79  // Run it
80  Run();
81 
82 #ifdef FORMATCLASSIFIER_SIGNAL_DEBUG
83  for (unsigned int n = 0; n < mClasses.size(); n++)
84  {
85  wxPrintf("Class [%i] Machine [%i]: Mono: %3.7f Stereo: %3.7f\n", mClasses[n].format, mClasses[n].endian, mMonoFeat[n], mStereoFeat[n]);
86  }
87 #endif
88 
89 }
FormatVectorT mClasses
static const size_t cSiglen
int format
Definition: ExportPCM.cpp:56
SpecPowerCalculation mMeter
MultiFormatReader mReader
FormatClassifier::~FormatClassifier ( )

Definition at line 91 of file FormatClassifier.cpp.

92 {
93 }

Member Function Documentation

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

Definition at line 311 of file FormatClassifier.cpp.

Referenced by Run().

312 {
313  for (unsigned int n = 0; n < len; n++)
314  {
315  if (in[n] < 0.0f)
316  {
317  out[n] = -in[n];
318  }
319  else
320  {
321  out[n] = in[n];
322  }
323  }
324 }
void FormatClassifier::Add ( float *  in1,
float *  in2,
size_t  len 
)
private

Definition at line 286 of file FormatClassifier.cpp.

Referenced by ReadSignal().

287 {
288  for (unsigned int n = 0; n < len; n++)
289  {
290  in1[n] += in2[n];
291  }
292 }
void FormatClassifier::ConvertSamples ( void *  in,
float *  out,
FormatClassT  format 
)
private

Definition at line 255 of file FormatClassifier.cpp.

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

Referenced by ReadSignal().

256 {
257  switch(format.format)
258  {
260  ToFloat((int8_t*) in, out, cSiglen);
261  break;
263  ToFloat((int16_t*) in, out, cSiglen);
264  break;
266  ToFloat((int32_t*) in, out, cSiglen);
267  break;
269  ToFloat((uint8_t*) in, out, cSiglen);
270  break;
272  ToFloat((uint16_t*) in, out, cSiglen);
273  break;
275  ToFloat((uint32_t*) in, out, cSiglen);
276  break;
278  ToFloat((float*) in, out, cSiglen);
279  break;
281  ToFloat((double*) in, out, cSiglen);
282  break;
283  }
284 }
static const size_t cSiglen
int format
Definition: ExportPCM.cpp:56
void ToFloat(T *in, float *out, size_t len)
void FormatClassifier::Div ( float *  in,
float  div,
size_t  len 
)
private

Definition at line 302 of file FormatClassifier.cpp.

Referenced by Run().

303 {
304  for (unsigned int n = 0; n < len; n++)
305  {
306  in[n] /= div;
307  }
308 }
unsigned FormatClassifier::GetResultChannels ( )

Definition at line 142 of file FormatClassifier.cpp.

References mResultChannels.

143 {
144  return mResultChannels;
145 }
unsigned mResultChannels
FormatClassifier::FormatClassT FormatClassifier::GetResultFormat ( )

Definition at line 95 of file FormatClassifier.cpp.

References mResultFormat.

96 {
97  return mResultFormat;
98 }
FormatClassT mResultFormat
int FormatClassifier::GetResultFormatLibSndfile ( )

Definition at line 100 of file FormatClassifier.cpp.

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 ImportRaw().

101 {
102  int format = SF_FORMAT_RAW;
103 
104  switch(mResultFormat.format)
105  {
107  format |= SF_FORMAT_PCM_S8;
108  break;
110  format |= SF_FORMAT_PCM_16;
111  break;
113  format |= SF_FORMAT_PCM_32;
114  break;
116  format |= SF_FORMAT_PCM_U8;
117  break;
119  format |= SF_FORMAT_FLOAT;
120  break;
122  format |= SF_FORMAT_DOUBLE;
123  break;
124  default:
125  format |= SF_FORMAT_PCM_16;
126  break;
127  }
128 
129  switch(mResultFormat.endian)
130  {
132  format |= SF_ENDIAN_LITTLE;
133  break;
135  format |= SF_ENDIAN_BIG;
136  break;
137  }
138 
139  return format;
140 }
FormatClassT mResultFormat
int format
Definition: ExportPCM.cpp:56
MultiFormatReader::FormatT format
MachineEndianness::EndiannessT endian
float FormatClassifier::Max ( float *  in,
size_t  len 
)
private

Definition at line 340 of file FormatClassifier.cpp.

Referenced by Run().

341 {
342  size_t dummyidx;
343  return Max(in, len, &dummyidx);
344 }
float Max(float *in, size_t len)
float FormatClassifier::Max ( float *  in,
size_t  len,
size_t *  maxidx 
)
private

Definition at line 346 of file FormatClassifier.cpp.

347 {
348  float max = -FLT_MAX;
349  *maxidx = 0;
350 
351  for (unsigned int n = 0; n < len; n++)
352  {
353  if (in[n] > max)
354  {
355  max = in[n];
356  *maxidx = n;
357  }
358  }
359 
360  return max;
361 }
float FormatClassifier::Mean ( float *  in,
size_t  len 
)
private

Definition at line 326 of file FormatClassifier.cpp.

Referenced by Run().

327 {
328  float mean = 0.0f;
329 
330  for (unsigned int n = 0; n < len; n++)
331  {
332  mean += in[n];
333  }
334 
335  mean /= len;
336 
337  return mean;
338 }
void FormatClassifier::ReadSignal ( FormatClassT  format,
size_t  stride 
)
private

Definition at line 217 of file FormatClassifier.cpp.

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

Referenced by Run().

218 {
219  size_t actRead = 0;
220  unsigned int n = 0;
221 
222  mReader.Reset();
223 
224  // Do a dummy read of 1024 bytes to skip potential header information
226 
227  do
228  {
229  actRead = mReader.ReadSamples(mRawBuffer.get(), cSiglen, stride, format.format, format.endian);
230 
231  if (n == 0)
232  {
234  }
235  else
236  {
237  if (actRead == cSiglen)
238  {
240 
241  // Integrate signals
242  Add(mSigBuffer.get(), mAuxBuffer.get(), cSiglen);
243 
244  // Do some dummy reads to break signal coherence
245  mReader.ReadSamples(mRawBuffer.get(), n + 1, stride, format.format, format.endian);
246  }
247  }
248 
249  n++;
250 
251  } while ((n < cNumInts) && (actRead == cSiglen));
252 
253 }
void Add(float *in1, float *in2, size_t len)
size_t ReadSamples(void *buffer, size_t len, MultiFormatReader::FormatT format, MachineEndianness::EndiannessT end)
static const size_t cSiglen
void ConvertSamples(void *in, float *out, FormatClassT format)
static const size_t cNumInts
int format
Definition: ExportPCM.cpp:56
MultiFormatReader mReader
ArrayOf< uint8_t > mRawBuffer
void FormatClassifier::Run ( )
private

Definition at line 147 of file FormatClassifier.cpp.

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

Referenced by FormatClassifier().

148 {
149  // Calc the mono feature vector
150  for (unsigned int n = 0; n < mClasses.size(); n++)
151  {
152  // Read the signal
153  ReadSignal(mClasses[n], 1);
154 #ifdef FORMATCLASSIFIER_SIGNAL_DEBUG
155  mpWriter->WriteSignal(mSigBuffer, cSiglen);
156 #endif
157 
158  // Do some simple preprocessing
159  // Remove DC offset
160  float smean = Mean(mSigBuffer.get(), cSiglen);
161  Sub(mSigBuffer.get(), smean, cSiglen);
162  // Normalize to +- 1.0
163  Abs(mSigBuffer.get(), mAuxBuffer.get(), cSiglen);
164  float smax = Max(mAuxBuffer.get(), cSiglen);
165  Div(mSigBuffer.get(), smax, cSiglen);
166 
167  // Now actually fill the feature vector
168  // Low to high band power ratio
169  float pLo = mMeter.CalcPower(mSigBuffer.get(), 0.15f, 0.3f);
170  float pHi = mMeter.CalcPower(mSigBuffer.get(), 0.45f, 0.1f);
171  mMonoFeat[n] = pLo / pHi;
172  }
173 
174  // Calc the stereo feature vector
175  for (unsigned int n = 0; n < mClasses.size(); n++)
176  {
177  // Read the signal
178  ReadSignal(mClasses[n], 2);
179 #ifdef FORMATCLASSIFIER_SIGNAL_DEBUG
180  mpWriter->WriteSignal(mSigBuffer, cSiglen);
181 #endif
182 
183  // Do some simple preprocessing
184  // Remove DC offset
185  float smean = Mean(mSigBuffer.get(), cSiglen);
186  Sub(mSigBuffer.get(), smean, cSiglen);
187  // Normalize to +- 1.0
188  Abs(mSigBuffer.get(), mAuxBuffer.get(), cSiglen);
189  float smax = Max(mAuxBuffer.get(), cSiglen);
190  Div(mSigBuffer.get(), smax, cSiglen);
191 
192  // Now actually fill the feature vector
193  // Low to high band power ratio
194  float pLo = mMeter.CalcPower(mSigBuffer.get(), 0.15f, 0.3f);
195  float pHi = mMeter.CalcPower(mSigBuffer.get(), 0.45f, 0.1f);
196  mStereoFeat[n] = pLo / pHi;
197  }
198 
199  // Get the results
200  size_t midx, sidx;
201  float monoMax = Max(mMonoFeat.get(), mClasses.size(), &midx);
202  float stereoMax = Max(mStereoFeat.get(), mClasses.size(), &sidx);
203 
204  if (monoMax > stereoMax)
205  {
206  mResultChannels = 1;
207  mResultFormat = mClasses[midx];
208  }
209  else
210  {
211  mResultChannels = 2;
212  mResultFormat = mClasses[sidx];
213  }
214 
215 }
float Mean(float *in, size_t len)
FormatVectorT mClasses
static const size_t cSiglen
unsigned mResultChannels
void Div(float *in, float div, size_t len)
FormatClassT mResultFormat
float CalcPower(float *sig, float fc, float bw)
float Max(float *in, size_t len)
SpecPowerCalculation mMeter
void Sub(float *in, float subt, size_t len)
void Abs(float *in, float *out, size_t len)
void ReadSignal(FormatClassT format, size_t stride)
void FormatClassifier::Sub ( float *  in,
float  subt,
size_t  len 
)
private

Definition at line 294 of file FormatClassifier.cpp.

Referenced by Run().

295 {
296  for (unsigned int n = 0; n < len; n++)
297  {
298  in[n] -= subt;
299  }
300 }
template<class T >
void FormatClassifier::ToFloat ( T *  in,
float *  out,
size_t  len 
)
private

Definition at line 363 of file FormatClassifier.cpp.

Referenced by ConvertSamples().

364 {
365  for(unsigned int n = 0; n < len; n++)
366  {
367  out[n] = (float) in[n];
368  }
369 }

Member Data Documentation

const size_t FormatClassifier::cNumInts = 32
staticprivate

Definition at line 75 of file FormatClassifier.h.

Referenced by ReadSignal().

const size_t FormatClassifier::cSiglen = 512
staticprivate

Definition at line 74 of file FormatClassifier.h.

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

Floats FormatClassifier::mAuxBuffer { cSiglen }
private

Definition at line 86 of file FormatClassifier.h.

Referenced by ReadSignal(), and Run().

FormatVectorT FormatClassifier::mClasses
private

Definition at line 77 of file FormatClassifier.h.

Referenced by FormatClassifier(), and Run().

SpecPowerCalculation FormatClassifier::mMeter
private

Definition at line 79 of file FormatClassifier.h.

Referenced by Run().

Floats FormatClassifier::mMonoFeat
private

Definition at line 89 of file FormatClassifier.h.

Referenced by FormatClassifier(), and Run().

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

Definition at line 87 of file FormatClassifier.h.

Referenced by ReadSignal().

MultiFormatReader FormatClassifier::mReader
private

Definition at line 78 of file FormatClassifier.h.

Referenced by ReadSignal().

unsigned FormatClassifier::mResultChannels { 0 }
private

Definition at line 93 of file FormatClassifier.h.

Referenced by GetResultChannels(), and Run().

FormatClassT FormatClassifier::mResultFormat
private

Definition at line 92 of file FormatClassifier.h.

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

Floats FormatClassifier::mSigBuffer { cSiglen }
private

Definition at line 85 of file FormatClassifier.h.

Referenced by ReadSignal(), and Run().

Floats FormatClassifier::mStereoFeat
private

Definition at line 90 of file FormatClassifier.h.

Referenced by FormatClassifier(), and Run().


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