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
@@ -137,7 +137,11 @@ WavReader::Sniff(int32 *streamCount)
} }
format_struct format; format_struct format;
wave_format_ex wav_format;
format_struct_extensible format_ext; format_struct_extensible format_ext;
mpeg1_wav_format mpeg1_format;
mpeg3_wav_format mpeg3_format;
fact_struct fact; fact_struct fact;
// read all chunks and search for "fact", "fmt" (normal or extensible) and "data" // 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 foundFmt = false;
bool foundFmtExt = false; bool foundFmtExt = false;
bool foundData = false; bool foundData = false;
bool foundMPEG1 = false;
bool foundMPEG3 = false;
while (pos + sizeof(chunk_struct) <= fFileSize) { while (pos + sizeof(chunk_struct) <= fFileSize) {
chunk_struct chunk; chunk_struct chunk;
if (sizeof(chunk) != Source()->ReadAt(pos, &chunk, sizeof(chunk))) { if (sizeof(chunk) != Source()->ReadAt(pos, &chunk, sizeof(chunk))) {
@@ -159,12 +166,43 @@ WavReader::Sniff(int32 *streamCount)
} }
switch (UINT32(chunk.fourcc)) { switch (UINT32(chunk.fourcc)) {
case FOURCC('f','m','t',' '): 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))) { if (sizeof(format) != Source()->ReadAt(pos, &format, sizeof(format))) {
ERROR("WavReader::Sniff: format chunk reading failed\n"); ERROR("WavReader::Sniff: format chunk reading failed\n");
break; break;
} }
foundFmt = true; foundFmt = true;
if (UINT32(chunk.len) >= sizeof(format_ext) && UINT16(format.format_tag) == 0xfffe) { if (UINT32(chunk.len) >= sizeof(format_ext) && UINT16(format.format_tag) == 0xfffe) {
if (sizeof(format_ext) != Source()->ReadAt(pos, &format_ext, sizeof(format_ext))) { if (sizeof(format_ext) != Source()->ReadAt(pos, &format_ext, sizeof(format_ext))) {
ERROR("WavReader::Sniff: format extensible chunk reading failed\n"); ERROR("WavReader::Sniff: format extensible chunk reading failed\n");
@@ -231,6 +269,28 @@ WavReader::Sniff(int32 *streamCount)
if (foundFact) { if (foundFact) {
TRACE(" sample_length %ld\n", UINT32(fact.sample_length)); 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.extra_size = 0;
fMetaData.channels = UINT16(format.channels); fMetaData.channels = UINT16(format.channels);
@@ -298,7 +358,7 @@ WavReader::AllocateCookie(int32 streamNumber, void **cookie)
data->position = 0; data->position = 0;
data->datasize = fDataSize; data->datasize = fDataSize;
data->fps = fMetaData.samples_per_sec; 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->buffer = malloc(data->buffersize);
data->framecount = fFrameCount ? fFrameCount : (8 * fDataSize) / (fMetaData.channels * fMetaData.bits_per_sample); data->framecount = fFrameCount ? fFrameCount : (8 * fDataSize) / (fMetaData.channels * fMetaData.bits_per_sample);
data->raw = fMetaData.format_tag == 0x0001; data->raw = fMetaData.format_tag == 0x0001;
@@ -71,6 +71,7 @@ private:
int64 fFrameCount; int64 fFrameCount;
int32 fFrameRate; int32 fFrameRate;
uint16 fBufferSize;
}; };
+34 -1
View File
@@ -56,7 +56,40 @@ struct wave_format_ex {
uint16 block_align; uint16 block_align;
uint16 bits_per_sample; uint16 bits_per_sample;
uint16 extra_size; 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 struct format_struct_extensible
{ {