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:
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user