Added support for WAV file 'fact' chunk

This commit is contained in:
oparviai 2014-10-05 16:20:24 +00:00
parent 5100cefbb0
commit bfc89b45a9
3 changed files with 133 additions and 71 deletions

View File

@ -507,6 +507,7 @@ and estimates the BPM rate:</p>
<ul> <ul>
<li>Replaced Windows-like 'BOOL' types with native 'bool'</li> <li>Replaced Windows-like 'BOOL' types with native 'bool'</li>
<li>Fixed bug in Android.mk make file</li> <li>Fixed bug in Android.mk make file</li>
<li>Changed documentation token to "dist_doc_DATA" in Makefile.am file</li>
</ul> </ul>
<p><b>1.8.0:</b></p> <p><b>1.8.0:</b></p>
<ul> <ul>
@ -667,6 +668,11 @@ accessing the FIFOSampleBuffer class from external files. </li>
</ul> </ul>
<p>&nbsp;</p> <p>&nbsp;</p>
<h3>5.2. SoundStretch application Change History </h3> <h3>5.2. SoundStretch application Change History </h3>
<p><b>1.8.1:</b></p>
<ul>
<li>Added support for WAV file 'fact' information chunk.</li>
</ul>
<p><b>1.7.0:</b></p> <p><b>1.7.0:</b></p>
<ul> <ul>
<li>Bugfixes in Wavfile: exception string formatting, avoid getLengthMs() integer <li>Bugfixes in Wavfile: exception string formatting, avoid getLengthMs() integer
@ -750,6 +756,7 @@ submitted bugfixes since SoundTouch v1.3.1: </p>
<li> Jason Garland</li> <li> Jason Garland</li>
<li> Masa H.</li> <li> Masa H.</li>
<li> Takashi Iwai</li> <li> Takashi Iwai</li>
<li> Thomas Klausner</li>
<li> Mathias Möhl</li> <li> Mathias Möhl</li>
<li> Yuval Naveh</li> <li> Yuval Naveh</li>
<li> Paulo Pizarro</li> <li> Paulo Pizarro</li>

View File

@ -60,6 +60,7 @@ using namespace std;
static const char riffStr[] = "RIFF"; static const char riffStr[] = "RIFF";
static const char waveStr[] = "WAVE"; static const char waveStr[] = "WAVE";
static const char fmtStr[] = "fmt "; static const char fmtStr[] = "fmt ";
static const char factStr[] = "fact";
static const char dataStr[] = "data"; static const char dataStr[] = "data";
@ -558,6 +559,42 @@ int WavInFile::readHeaderBlock()
return 0; return 0;
} }
else if (strcmp(label, factStr) == 0)
{
int nLen, nDump;
// 'fact' block
memcpy(header.fact.fact_field, factStr, 4);
// read length of the fact field
if (fread(&nLen, sizeof(int), 1, fptr) != 1) return -1;
// swap byte order if necessary
_swap32(nLen); // int fact_len;
header.fact.fact_len = nLen;
// calculate how much length differs from expected
nDump = nLen - ((int)sizeof(header.fact) - 8);
// if format_len is larger than expected, read only as much data as we've space for
if (nDump > 0)
{
nLen = sizeof(header.fact) - 8;
}
// read data
if (fread(&(header.fact.fact_sample_len), nLen, 1, fptr) != 1) return -1;
// swap byte order if necessary
_swap32((int &)header.fact.fact_sample_len); // int sample_length;
// if fact_len is larger than expected, skip the extra data
if (nDump > 0)
{
fseek(fptr, nDump, SEEK_CUR);
}
return 0;
}
else if (strcmp(label, dataStr) == 0) else if (strcmp(label, dataStr) == 0)
{ {
// 'data' block // 'data' block
@ -642,6 +679,7 @@ uint WavInFile::getDataSizeInBytes() const
uint WavInFile::getNumSamples() const uint WavInFile::getNumSamples() const
{ {
if (header.format.byte_per_sample == 0) return 0; if (header.format.byte_per_sample == 0) return 0;
if (header.format.fixed > 1) return header.fact.fact_sample_len;
return header.data.data_len / (unsigned short)header.format.byte_per_sample; return header.data.data_len / (unsigned short)header.format.byte_per_sample;
} }
@ -739,6 +777,11 @@ void WavOutFile::fillInHeader(uint sampleRate, uint bits, uint channels)
header.format.byte_rate = header.format.byte_per_sample * (int)sampleRate; header.format.byte_rate = header.format.byte_per_sample * (int)sampleRate;
header.format.sample_rate = (int)sampleRate; header.format.sample_rate = (int)sampleRate;
// fill in the 'fact' part...
memcpy(&(header.fact.fact_field), factStr, 4);
header.fact.fact_len = 4;
header.fact.fact_sample_len = 0;
// fill in the 'data' part.. // fill in the 'data' part..
// copy string 'data' to data_field // copy string 'data' to data_field
@ -751,8 +794,9 @@ void WavOutFile::fillInHeader(uint sampleRate, uint bits, uint channels)
void WavOutFile::finishHeader() void WavOutFile::finishHeader()
{ {
// supplement the file length into the header structure // supplement the file length into the header structure
header.riff.package_len = bytesWritten + 36; header.riff.package_len = bytesWritten + sizeof(WavHeader) - sizeof(WavRiff) + 4;
header.data.data_len = bytesWritten; header.data.data_len = bytesWritten;
header.fact.fact_sample_len = bytesWritten / header.format.byte_per_sample;
writeHeader(); writeHeader();
} }
@ -775,6 +819,8 @@ void WavOutFile::writeHeader()
_swap16((short &)hdrTemp.format.byte_per_sample); _swap16((short &)hdrTemp.format.byte_per_sample);
_swap16((short &)hdrTemp.format.bits_per_sample); _swap16((short &)hdrTemp.format.bits_per_sample);
_swap32((int &)hdrTemp.data.data_len); _swap32((int &)hdrTemp.data.data_len);
_swap32((int &)hdrTemp.fact.fact_len);
_swap32((int &)hdrTemp.fact.fact_sample_len);
// write the supplemented header in the beginning of the file // write the supplemented header in the beginning of the file
fseek(fptr, 0, SEEK_SET); fseek(fptr, 0, SEEK_SET);

View File

@ -75,6 +75,14 @@ typedef struct
short bits_per_sample; short bits_per_sample;
} WavFormat; } WavFormat;
/// WAV audio file 'fact' section header
typedef struct
{
char fact_field[4];
int fact_len;
uint fact_sample_len;
} WavFact;
/// WAV audio file 'data' section header /// WAV audio file 'data' section header
typedef struct typedef struct
{ {
@ -88,6 +96,7 @@ typedef struct
{ {
WavRiff riff; WavRiff riff;
WavFormat format; WavFormat format;
WavFact fact;
WavData data; WavData data;
} WavHeader; } WavHeader;