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:
parent
435455abc1
commit
2cbce7bb7a
@ -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;
|
||||
|
@ -71,6 +71,7 @@ private:
|
||||
|
||||
int64 fFrameCount;
|
||||
int32 fFrameRate;
|
||||
uint16 fBufferSize;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user