Add support for mpeg audio in wav format files

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30520 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
David McPaul 2009-04-30 22:36:22 +00:00
parent 435455abc1
commit 2cbce7bb7a
3 changed files with 97 additions and 3 deletions

View File

@ -137,7 +137,11 @@ WavReader::Sniff(int32 *streamCount)
}
format_struct format;
wave_format_ex wav_format;
format_struct_extensible format_ext;
mpeg1_wav_format mpeg1_format;
mpeg3_wav_format mpeg3_format;
fact_struct fact;
// read all chunks and search for "fact", "fmt" (normal or extensible) and "data"
@ -146,6 +150,9 @@ WavReader::Sniff(int32 *streamCount)
bool foundFmt = false;
bool foundFmtExt = false;
bool foundData = false;
bool foundMPEG1 = false;
bool foundMPEG3 = false;
while (pos + sizeof(chunk_struct) <= fFileSize) {
chunk_struct chunk;
if (sizeof(chunk) != Source()->ReadAt(pos, &chunk, sizeof(chunk))) {
@ -159,12 +166,43 @@ WavReader::Sniff(int32 *streamCount)
}
switch (UINT32(chunk.fourcc)) {
case FOURCC('f','m','t',' '):
if (UINT32(chunk.len) >= sizeof(format)) {
// So what do we have a std format structure, a wav_format structure or a extended structure
if (UINT32(chunk.len) >= sizeof(wav_format)) {
// Read both format and wav format
if (sizeof(format) != Source()->ReadAt(pos, &format, sizeof(format))) {
ERROR("WavReader::Sniff: format chunk reading failed\n");
break;
}
if (sizeof(wav_format) != Source()->ReadAt(pos, &wav_format, sizeof(wav_format))) {
ERROR("WavReader::Sniff: format chunk reading failed\n");
break;
}
foundFmt = true;
if (UINT16(wav_format.extra_size) == 12) {
// MPEG3 WAV FORMAT Structure
if (sizeof(mpeg3_format) != Source()->ReadAt(pos, &mpeg3_format, sizeof(mpeg3_format))) {
ERROR("WavReader::Sniff: format chunk reading failed\n");
break;
}
foundMPEG3 = true;
}
if (UINT16(wav_format.extra_size) == 22) {
// MPEG1 WAV FORMAT Structure
if (sizeof(mpeg1_format) != Source()->ReadAt(pos, &mpeg1_format, sizeof(mpeg1_format))) {
ERROR("WavReader::Sniff: format chunk reading failed\n");
break;
}
foundMPEG1 = true;
}
} else if (UINT32(chunk.len) >= sizeof(format)) {
if (sizeof(format) != Source()->ReadAt(pos, &format, sizeof(format))) {
ERROR("WavReader::Sniff: format chunk reading failed\n");
break;
}
foundFmt = true;
if (UINT32(chunk.len) >= sizeof(format_ext) && UINT16(format.format_tag) == 0xfffe) {
if (sizeof(format_ext) != Source()->ReadAt(pos, &format_ext, sizeof(format_ext))) {
ERROR("WavReader::Sniff: format extensible chunk reading failed\n");
@ -231,6 +269,28 @@ WavReader::Sniff(int32 *streamCount)
if (foundFact) {
TRACE(" sample_length %ld\n", UINT32(fact.sample_length));
}
if (foundMPEG1) {
TRACE(" layer %d\n", UINT16(mpeg1_format.head_layer));
TRACE(" bitrate %ld\n", UINT32(mpeg1_format.head_bitrate));
TRACE(" mode %d\n", UINT16(mpeg1_format.head_mode));
TRACE(" mode ext %d\n", UINT16(mpeg1_format.head_mode_ext));
TRACE(" emphisis %d\n", UINT16(mpeg1_format.head_emphasis));
TRACE(" flags %d\n", UINT16(mpeg1_format.head_flags));
TRACE(" pts low %ld\n", UINT32(mpeg1_format.pts_low));
TRACE(" pts high %ld\n", UINT32(mpeg1_format.pts_high));
}
if (foundMPEG3) {
TRACE(" id %d\n", UINT16(mpeg3_format.id));
TRACE(" flags %ld\n", UINT32(mpeg3_format.flags));
TRACE(" block size %d\n", UINT16(mpeg3_format.block_size));
TRACE(" frames per block %d\n", UINT16(mpeg3_format.frames_per_block));
TRACE(" codec delay %d\n", UINT16(mpeg3_format.codec_delay));
fBufferSize = mpeg3_format.block_size;
} else {
fBufferSize = BUFFER_SIZE;
}
fMetaData.extra_size = 0;
fMetaData.channels = UINT16(format.channels);
@ -298,7 +358,7 @@ WavReader::AllocateCookie(int32 streamNumber, void **cookie)
data->position = 0;
data->datasize = fDataSize;
data->fps = fMetaData.samples_per_sec;
data->buffersize = (BUFFER_SIZE / fMetaData.block_align) * fMetaData.block_align;
data->buffersize = (fBufferSize / fMetaData.block_align) * fMetaData.block_align;
data->buffer = malloc(data->buffersize);
data->framecount = fFrameCount ? fFrameCount : (8 * fDataSize) / (fMetaData.channels * fMetaData.bits_per_sample);
data->raw = fMetaData.format_tag == 0x0001;

View File

@ -71,6 +71,7 @@ private:
int64 fFrameCount;
int32 fFrameRate;
uint16 fBufferSize;
};

View File

@ -56,7 +56,40 @@ struct wave_format_ex {
uint16 block_align;
uint16 bits_per_sample;
uint16 extra_size;
} _PACKED;
};
struct mpeg3_wav_format {
uint16 format_tag;
uint16 channels;
uint32 samples_per_sec;
uint32 avg_bytes_per_sec;
uint16 block_align;
uint16 bits_per_sample;
uint16 extra_size;
uint16 id;
uint32 flags;
uint16 block_size;
uint16 frames_per_block;
uint16 codec_delay;
};
struct mpeg1_wav_format {
uint16 format_tag;
uint16 channels;
uint32 samples_per_sec;
uint32 avg_bytes_per_sec;
uint16 block_align;
uint16 bits_per_sample;
uint16 extra_size;
uint16 head_layer;
uint32 head_bitrate;
uint16 head_mode;
uint16 head_mode_ext;
uint16 head_emphasis;
uint16 head_flags;
uint32 pts_low;
uint32 pts_high;
};
struct format_struct_extensible
{