sound production.. somewhat mangled
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6218 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
b84e6d90eb
commit
43ffdb6608
@ -18,13 +18,6 @@
|
|||||||
|
|
||||||
#define DECODE_BUFFER_SIZE (32 * 1024)
|
#define DECODE_BUFFER_SIZE (32 * 1024)
|
||||||
|
|
||||||
inline size_t
|
|
||||||
AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */)
|
|
||||||
{
|
|
||||||
return (raf->format & 0xf) * (raf->channel_count)
|
|
||||||
* (size_t)((raf->frame_rate * buffer_duration) / 1000000.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
speexDecoder::speexDecoder()
|
speexDecoder::speexDecoder()
|
||||||
{
|
{
|
||||||
TRACE("speexDecoder::speexDecoder\n");
|
TRACE("speexDecoder::speexDecoder\n");
|
||||||
@ -32,8 +25,7 @@ speexDecoder::speexDecoder()
|
|||||||
fDecoderState = 0;
|
fDecoderState = 0;
|
||||||
fHeader = 0;
|
fHeader = 0;
|
||||||
fStereoState = 0;
|
fStereoState = 0;
|
||||||
fSpeexFrameSize = 0;
|
fSpeexOutputLength = 0;
|
||||||
fSpeexBuffer = 0;
|
|
||||||
fStartTime = 0;
|
fStartTime = 0;
|
||||||
fFrameSize = 0;
|
fFrameSize = 0;
|
||||||
fOutputBufferSize = 0;
|
fOutputBufferSize = 0;
|
||||||
@ -43,8 +35,8 @@ speexDecoder::speexDecoder()
|
|||||||
speexDecoder::~speexDecoder()
|
speexDecoder::~speexDecoder()
|
||||||
{
|
{
|
||||||
TRACE("speexDecoder::~speexDecoder\n");
|
TRACE("speexDecoder::~speexDecoder\n");
|
||||||
delete fStereoState;
|
// the fStereoState is destroyed by fDecoderState
|
||||||
delete fSpeexBuffer;
|
// delete fStereoState;
|
||||||
speex_bits_destroy(&fBits);
|
speex_bits_destroy(&fBits);
|
||||||
speex_decoder_destroy(fDecoderState);
|
speex_decoder_destroy(fDecoderState);
|
||||||
}
|
}
|
||||||
@ -54,7 +46,6 @@ status_t
|
|||||||
speexDecoder::Setup(media_format *inputFormat,
|
speexDecoder::Setup(media_format *inputFormat,
|
||||||
const void *infoBuffer, int32 infoSize)
|
const void *infoBuffer, int32 infoSize)
|
||||||
{
|
{
|
||||||
debugger("speexDecoder::Setup");
|
|
||||||
if (inputFormat->type != B_MEDIA_ENCODED_AUDIO) {
|
if (inputFormat->type != B_MEDIA_ENCODED_AUDIO) {
|
||||||
TRACE("speexDecoder::Setup not called with audio stream: not speex\n");
|
TRACE("speexDecoder::Setup not called with audio stream: not speex\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@ -111,6 +102,12 @@ speexDecoder::Setup(media_format *inputFormat,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (fHeader->nb_channels == 0) {
|
||||||
|
fHeader->nb_channels = 1;
|
||||||
|
}
|
||||||
|
if (fHeader->frames_per_packet == 0) {
|
||||||
|
fHeader->frames_per_packet = 1;
|
||||||
|
}
|
||||||
if (SpeexSettings::SamplingRate() != 0) {
|
if (SpeexSettings::SamplingRate() != 0) {
|
||||||
fHeader->rate = SpeexSettings::SamplingRate();
|
fHeader->rate = SpeexSettings::SamplingRate();
|
||||||
}
|
}
|
||||||
@ -142,7 +139,8 @@ speexDecoder::Setup(media_format *inputFormat,
|
|||||||
int enabled = 1;
|
int enabled = 1;
|
||||||
speex_decoder_ctl(fDecoderState, SPEEX_SET_ENH, &enabled);
|
speex_decoder_ctl(fDecoderState, SPEEX_SET_ENH, &enabled);
|
||||||
}
|
}
|
||||||
speex_decoder_ctl(fDecoderState, SPEEX_GET_FRAME_SIZE, &fSpeexFrameSize);
|
speex_decoder_ctl(fDecoderState, SPEEX_GET_FRAME_SIZE, &fHeader->frame_size);
|
||||||
|
fSpeexOutputLength = fHeader->frame_size * sizeof(float);
|
||||||
if (fHeader->nb_channels == 2) {
|
if (fHeader->nb_channels == 2) {
|
||||||
SpeexCallback callback;
|
SpeexCallback callback;
|
||||||
SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT;
|
SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT;
|
||||||
@ -151,10 +149,7 @@ speexDecoder::Setup(media_format *inputFormat,
|
|||||||
fStereoState = new SpeexStereoState(stereo);
|
fStereoState = new SpeexStereoState(stereo);
|
||||||
callback.data = fStereoState;
|
callback.data = fStereoState;
|
||||||
speex_decoder_ctl(fDecoderState, SPEEX_SET_HANDLER, &callback);
|
speex_decoder_ctl(fDecoderState, SPEEX_SET_HANDLER, &callback);
|
||||||
fSpeexFrameSize *= 2;
|
|
||||||
}
|
}
|
||||||
delete fSpeexBuffer;
|
|
||||||
fSpeexBuffer = new float[fSpeexFrameSize];
|
|
||||||
speex_decoder_ctl(fDecoderState, SPEEX_SET_SAMPLING_RATE, &fHeader->rate);
|
speex_decoder_ctl(fDecoderState, SPEEX_SET_SAMPLING_RATE, &fHeader->rate);
|
||||||
// fill out the encoding format
|
// fill out the encoding format
|
||||||
CopyInfoToEncodedFormat(inputFormat);
|
CopyInfoToEncodedFormat(inputFormat);
|
||||||
@ -182,6 +177,13 @@ void speexDecoder::CopyInfoToEncodedFormat(media_format * format) {
|
|||||||
format->u.encoded_audio.frame_size = sizeof(ogg_packet);
|
format->u.encoded_audio.frame_size = sizeof(ogg_packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline size_t
|
||||||
|
AudioBufferSize(media_raw_audio_format * raf, bigtime_t buffer_duration = 50000 /* 50 ms */)
|
||||||
|
{
|
||||||
|
return (raf->format & 0xf) * (raf->channel_count)
|
||||||
|
* (size_t)((raf->frame_rate * buffer_duration) / 1000000.0);
|
||||||
|
}
|
||||||
|
|
||||||
void speexDecoder::CopyInfoToDecodedFormat(media_raw_audio_format * raf) {
|
void speexDecoder::CopyInfoToDecodedFormat(media_raw_audio_format * raf) {
|
||||||
raf->frame_rate = (float)fHeader->rate; // XXX int32->float ??
|
raf->frame_rate = (float)fHeader->rate; // XXX int32->float ??
|
||||||
raf->channel_count = fHeader->nb_channels;
|
raf->channel_count = fHeader->nb_channels;
|
||||||
@ -189,8 +191,8 @@ void speexDecoder::CopyInfoToDecodedFormat(media_raw_audio_format * raf) {
|
|||||||
raf->byte_order = B_MEDIA_HOST_ENDIAN; // XXX should support other endain, too
|
raf->byte_order = B_MEDIA_HOST_ENDIAN; // XXX should support other endain, too
|
||||||
if (raf->buffer_size < 512 || raf->buffer_size > 65536) {
|
if (raf->buffer_size < 512 || raf->buffer_size > 65536) {
|
||||||
raf->buffer_size = AudioBufferSize(raf);
|
raf->buffer_size = AudioBufferSize(raf);
|
||||||
raf->buffer_size = (1 + raf->buffer_size / fSpeexFrameSize) * fSpeexFrameSize;
|
|
||||||
}
|
}
|
||||||
|
raf->buffer_size = ((raf->buffer_size - 1) / fSpeexOutputLength + 1) * fSpeexOutputLength;
|
||||||
// setup output variables
|
// setup output variables
|
||||||
fFrameSize = (raf->format & 0xf) * raf->channel_count;
|
fFrameSize = (raf->format & 0xf) * raf->channel_count;
|
||||||
fOutputBufferSize = raf->buffer_size;
|
fOutputBufferSize = raf->buffer_size;
|
||||||
@ -224,7 +226,7 @@ speexDecoder::Seek(uint32 seekTo,
|
|||||||
{
|
{
|
||||||
TRACE("speexDecoder::Seek\n");
|
TRACE("speexDecoder::Seek\n");
|
||||||
int ignore = 0;
|
int ignore = 0;
|
||||||
speex_decoder_ctl(fDecoderState,SPEEX_RESET_STATE,&ignore);
|
// speex_decoder_ctl(fDecoderState, SPEEX_RESET_STATE, &ignore);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,7 +243,7 @@ speexDecoder::Decode(void *buffer, int64 *frameCount,
|
|||||||
//TRACE("speexDecoder: Decoding start time %.6f\n", fStartTime / 1000000.0);
|
//TRACE("speexDecoder: Decoding start time %.6f\n", fStartTime / 1000000.0);
|
||||||
|
|
||||||
// debugger("speexDecoder::Decode");
|
// debugger("speexDecoder::Decode");
|
||||||
while (out_bytes_needed >= fSpeexFrameSize) {
|
while (out_bytes_needed >= fSpeexOutputLength) {
|
||||||
// get a new packet
|
// get a new packet
|
||||||
void *chunkBuffer;
|
void *chunkBuffer;
|
||||||
int32 chunkSize;
|
int32 chunkSize;
|
||||||
@ -260,12 +262,25 @@ speexDecoder::Decode(void *buffer, int64 *frameCount,
|
|||||||
}
|
}
|
||||||
ogg_packet * packet = static_cast<ogg_packet*>(chunkBuffer);
|
ogg_packet * packet = static_cast<ogg_packet*>(chunkBuffer);
|
||||||
speex_bits_read_from(&fBits, (char*)packet->packet, packet->bytes);
|
speex_bits_read_from(&fBits, (char*)packet->packet, packet->bytes);
|
||||||
speex_decode(fDecoderState, &fBits, (float*)out_buffer);
|
for (int frame = 0 ; frame < fHeader->frames_per_packet ; frame++) {
|
||||||
if (fHeader->nb_channels == 2) {
|
int ret = speex_decode(fDecoderState, &fBits, (float*)out_buffer);
|
||||||
speex_decode_stereo((float*)out_buffer, fSpeexFrameSize, fStereoState);
|
if (ret == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret == -2) {
|
||||||
|
TRACE("speexDecoder::Decode: corrupted stream?\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (speex_bits_remaining(&fBits) < 0) {
|
||||||
|
TRACE("speexDecoder::Decode: decoding overflow: corrupted stream?\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (fHeader->nb_channels == 2) {
|
||||||
|
speex_decode_stereo((float*)out_buffer, fSpeexOutputLength, fStereoState);
|
||||||
|
}
|
||||||
|
out_buffer += fSpeexOutputLength;
|
||||||
|
out_bytes_needed -= fSpeexOutputLength;
|
||||||
}
|
}
|
||||||
out_buffer += fSpeexFrameSize;
|
|
||||||
out_bytes_needed -= fSpeexFrameSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -32,8 +32,7 @@ private:
|
|||||||
SpeexHeader * fHeader;
|
SpeexHeader * fHeader;
|
||||||
SpeexStereoState * fStereoState;
|
SpeexStereoState * fStereoState;
|
||||||
|
|
||||||
int fSpeexFrameSize;
|
int fSpeexOutputLength;
|
||||||
float * fSpeexBuffer;
|
|
||||||
|
|
||||||
bigtime_t fStartTime;
|
bigtime_t fStartTime;
|
||||||
int fFrameSize;
|
int fFrameSize;
|
||||||
|
Loading…
Reference in New Issue
Block a user