fixes for compressed audio

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13234 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
David McPaul
2005-06-23 13:12:41 +00:00
parent 557dfeeb12
commit 85c8a11cff
2 changed files with 89 additions and 76 deletions
@@ -401,6 +401,7 @@ const AudioMetaData *MOVFileReader::AudioFormat(uint32 stream_index, size_t *
// Hmm 16bit format 32 bit FourCC. // Hmm 16bit format 32 bit FourCC.
theAudio.compression = aSoundDescription.basefields.DataFormat; theAudio.compression = aSoundDescription.basefields.DataFormat;
// theAudio.compression = aSoundDescription.desc.CompressionID;
theAudio.NoOfChannels = aSoundDescription.desc.NoOfChannels; theAudio.NoOfChannels = aSoundDescription.desc.NoOfChannels;
theAudio.SampleSize = aSoundDescription.desc.SampleSize; theAudio.SampleSize = aSoundDescription.desc.SampleSize;
@@ -126,7 +126,7 @@ movReader::GetFileFormatInfo(media_file_format *mff)
| media_file_format::B_IMPERFECTLY_SEEKABLE; | media_file_format::B_IMPERFECTLY_SEEKABLE;
mff->family = B_QUICKTIME_FORMAT_FAMILY; mff->family = B_QUICKTIME_FORMAT_FAMILY;
mff->version = 100; mff->version = 100;
strcpy(mff->mime_type, "audio/x-mov"); strcpy(mff->mime_type, "video/quicktime");
strcpy(mff->file_extension, "mov"); strcpy(mff->file_extension, "mov");
strcpy(mff->short_name, "MOV"); strcpy(mff->short_name, "MOV");
strcpy(mff->pretty_name, "Quicktime (MOV) file format"); strcpy(mff->pretty_name, "Quicktime (MOV) file format");
@@ -168,104 +168,116 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
cookie->frame_count = theFileReader->getAudioFrameCount(); cookie->frame_count = theFileReader->getAudioFrameCount();
cookie->duration = theFileReader->getAudioDuration(); cookie->duration = theFileReader->getAudioDuration();
/* if (audio_format->compression == 0x0001) {// PCM
cookie->frame_count = stream_header->length / ((stream_header->sample_size + 7) / 8);
TRACE("frame_count %Ld (is PCM)\n", cookie->frame_count);
} else if (stream_header->rate) { // not PCM
cookie->frame_count = (stream_header->length * (int64)audio_format->SampleRate) / stream_header->rate;
TRACE("frame_count %Ld (using rate)\n", cookie->frame_count);
} else { // not PCM
cookie->frame_count = (stream_header->length * (int64)audio_format->SampleRate) / (stream_header->sample_size * audio_format->PacketSize);
TRACE("frame_count %Ld (using fallback)\n", cookie->frame_count);
}
if (stream_header->rate && stream_header->scale) {
cookie->duration = (1000000LL * (int64)stream_header->length * (int64)stream_header->scale) / stream_header->rate;
TRACE("duration %.6f (%Ld) (using scale & rate)\n", cookie->duration / 1E6, cookie->duration);
} else if (stream_header->rate) {
cookie->duration = (1000000LL * (int64)stream_header->length) / stream_header->rate;
TRACE("duration %.6f (%Ld) (using rate)\n", cookie->duration / 1E6, cookie->duration);
} else {
cookie->duration = theFileReader->Duration();
TRACE("duration %.6f (%Ld) (using fallback)\n", cookie->duration / 1E6, cookie->duration);
}
*/
cookie->audio = true; cookie->audio = true;
cookie->byte_pos = 0; cookie->byte_pos = 0;
cookie->chunk_pos = 1; cookie->chunk_pos = 1;
if (stream_header->scale && stream_header->rate && stream_header->sample_size) { if (stream_header->scale && stream_header->rate) {
cookie->bytes_per_sec_rate = stream_header->rate * stream_header->sample_size * audio_format->NoOfChannels / 8; cookie->bytes_per_sec_rate = stream_header->rate * audio_format->SampleSize * audio_format->NoOfChannels / 8;
cookie->bytes_per_sec_scale = stream_header->scale; cookie->bytes_per_sec_scale = stream_header->scale;
cookie->frames_per_sec_rate = stream_header->rate; cookie->frames_per_sec_rate = stream_header->rate;
cookie->frames_per_sec_scale = stream_header->scale; cookie->frames_per_sec_scale = stream_header->scale;
TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using both)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale); TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using both)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
} else if (stream_header->rate) {
cookie->bytes_per_sec_rate = stream_header->rate * audio_format->SampleSize * audio_format->NoOfChannels / 8;
cookie->bytes_per_sec_scale = 1;
cookie->frames_per_sec_rate = stream_header->rate;
cookie->frames_per_sec_scale = 1;
TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using rate)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
} else if (audio_format->PacketSize) { } else if (audio_format->PacketSize) {
cookie->bytes_per_sec_rate = audio_format->PacketSize; cookie->bytes_per_sec_rate = audio_format->PacketSize;
cookie->bytes_per_sec_scale = 1; cookie->bytes_per_sec_scale = 1;
cookie->frames_per_sec_rate = audio_format->SampleSize; cookie->frames_per_sec_rate = audio_format->PacketSize * 8 / audio_format->SampleSize / audio_format->NoOfChannels;
cookie->frames_per_sec_scale = 1; cookie->frames_per_sec_scale = 1;
TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using avg_bytes_per_sec)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale); TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using PacketSize)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
} else if (stream_header->rate && stream_header->sample_size) {
cookie->bytes_per_sec_rate = stream_header->rate * stream_header->sample_size * audio_format->NoOfChannels / 8;
cookie->bytes_per_sec_scale = 1;
cookie->frames_per_sec_rate = stream_header->sample_size;
cookie->frames_per_sec_scale = 1;
TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using rate)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
} else { } else {
cookie->frames_per_sec_rate = 16000;
cookie->frames_per_sec_scale = 1;
cookie->bytes_per_sec_rate = 128000; cookie->bytes_per_sec_rate = 128000;
cookie->bytes_per_sec_scale = 8; cookie->bytes_per_sec_scale = 8;
cookie->frames_per_sec_rate = 16000;
cookie->frames_per_sec_scale = 1;
TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using fallback)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale); TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using fallback)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
} }
description.family = B_BEOS_FORMAT_FAMILY; if ((audio_format->compression == AUDIO_NONE) ||
description.u.beos.format = B_BEOS_FORMAT_RAW_AUDIO; (audio_format->compression == AUDIO_RAW) ||
if (B_OK != formats.GetFormatFor(description, format)) { (audio_format->compression == AUDIO_TWOS1) ||
format->type = B_MEDIA_RAW_AUDIO; (audio_format->compression == AUDIO_TWOS2)) {
} description.family = B_BEOS_FORMAT_FAMILY;
description.u.beos.format = B_BEOS_FORMAT_RAW_AUDIO;
if (B_OK != formats.GetFormatFor(description, format)) {
format->type = B_MEDIA_RAW_AUDIO;
}
format->u.raw_audio.frame_rate = audio_format->SampleRate; format->u.raw_audio.frame_rate = cookie->frames_per_sec_rate / cookie->frames_per_sec_scale;
format->u.raw_audio.channel_count = audio_format->NoOfChannels; format->u.raw_audio.channel_count = audio_format->NoOfChannels;
format->u.raw_audio.byte_order = B_MEDIA_BIG_ENDIAN; format->u.raw_audio.byte_order = B_MEDIA_BIG_ENDIAN;
if (audio_format->SampleSize <= 8) if (audio_format->SampleSize <= 8)
format->u.raw_audio.format = B_AUDIO_FORMAT_UINT8; format->u.raw_audio.format = B_AUDIO_FORMAT_UINT8;
else if (audio_format->SampleSize <= 16) else if (audio_format->SampleSize <= 16)
format->u.raw_audio.format = B_AUDIO_FORMAT_INT16; format->u.raw_audio.format = B_AUDIO_FORMAT_INT16;
else if (audio_format->SampleSize <= 24) else if (audio_format->SampleSize <= 24)
format->u.raw_audio.format = B_AUDIO_FORMAT_INT24; format->u.raw_audio.format = B_AUDIO_FORMAT_INT24;
else if (audio_format->SampleSize <= 32) else if (audio_format->SampleSize <= 32)
format->u.raw_audio.format = B_AUDIO_FORMAT_INT32; format->u.raw_audio.format = B_AUDIO_FORMAT_INT32;
else { else {
ERROR("movReader::AllocateCookie: unhandled bits per sample %d\n", audio_format->SampleSize); ERROR("movReader::AllocateCookie: unhandled bits per sample %d\n", audio_format->SampleSize);
return B_ERROR; return B_ERROR;
} }
format->u.raw_audio.buffer_size = stream_header->suggested_buffer_size; if (audio_format->compression == AUDIO_TWOS1) {
if (audio_format->SampleSize <= 8) {
format->u.raw_audio.format = B_AUDIO_FORMAT_INT8;
} else if (audio_format->SampleSize <= 16) {
format->u.raw_audio.format = B_AUDIO_FORMAT_INT16;
format->u.raw_audio.byte_order = B_MEDIA_BIG_ENDIAN;
}
}
if (audio_format->compression == AUDIO_TWOS2) {
if (audio_format->SampleSize <= 8) {
format->u.raw_audio.format = B_AUDIO_FORMAT_INT8;
} else if (audio_format->SampleSize <= 16) {
format->u.raw_audio.format = B_AUDIO_FORMAT_INT16;
format->u.raw_audio.byte_order = B_MEDIA_LITTLE_ENDIAN;
}
}
switch (audio_format->compression) { format->u.raw_audio.buffer_size = stream_header->suggested_buffer_size;
case AUDIO_NONE: } else {
case AUDIO_RAW: description.family = B_QUICKTIME_FORMAT_FAMILY;
case AUDIO_TWOS1: description.u.quicktime.codec = audio_format->compression;
break; if (B_OK != formats.GetFormatFor(description, format)) {
case AUDIO_TWOS2: format->type = B_MEDIA_ENCODED_AUDIO;
format->u.raw_audio.byte_order = B_MEDIA_LITTLE_ENDIAN; }
break;
case AUDIO_IMA4: switch (audio_format->compression) {
break; case AUDIO_MS_PCM02:
case AUDIO_MS_PCM02: TRACE("MS PCM02\n");
format->u.raw_audio.format |= B_AUDIO_FORMAT_CHANNEL_ORDER_WAVE; format->u.raw_audio.format |= B_AUDIO_FORMAT_CHANNEL_ORDER_WAVE;
format->u.encoded_audio.bit_rate = 8 * audio_format->PacketSize; format->u.encoded_audio.bit_rate = 8 * cookie->frames_per_sec_rate / cookie->frames_per_sec_scale;
format->u.encoded_audio.output.frame_rate = audio_format->SampleRate; format->u.encoded_audio.output.frame_rate = cookie->frames_per_sec_rate / cookie->frames_per_sec_scale;
format->u.encoded_audio.output.channel_count = audio_format->NoOfChannels; format->u.encoded_audio.output.channel_count = audio_format->NoOfChannels;
break; break;
case AUDIO_INTEL_PCM17: case AUDIO_INTEL_PCM17:
break; TRACE("INTEL PCM\n");
case AUDIO_MPEG3_CBR: format->u.encoded_audio.bit_rate = 8 * cookie->frames_per_sec_rate / cookie->frames_per_sec_scale;
break; format->u.encoded_audio.output.frame_rate = cookie->frames_per_sec_rate / cookie->frames_per_sec_scale;
format->u.encoded_audio.output.channel_count = audio_format->NoOfChannels;
break;
case AUDIO_MPEG3_CBR:
TRACE("MP3\n");
format->u.encoded_audio.bit_rate = 8 * cookie->frames_per_sec_rate / cookie->frames_per_sec_scale;
format->u.encoded_audio.output.frame_rate = cookie->frames_per_sec_rate / cookie->frames_per_sec_scale;
format->u.encoded_audio.output.channel_count = audio_format->NoOfChannels;
break;
default:
TRACE("OTHER\n");
format->u.encoded_audio.bit_rate = 8 * cookie->frames_per_sec_rate / cookie->frames_per_sec_scale;
format->u.encoded_audio.output.frame_rate = cookie->frames_per_sec_rate / cookie->frames_per_sec_scale;
format->u.encoded_audio.output.channel_count = audio_format->NoOfChannels;
break;
}
} }
/* if (audio_format->compression == 0x0001) { /* if (audio_format->compression == 0x0001) {