stupid linker bug... why?

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6211 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
shatty 2004-01-21 11:21:49 +00:00
parent a2d20d9daa
commit f9df549e6f
4 changed files with 64 additions and 37 deletions

View File

@ -3,7 +3,7 @@
bool SpeexSettings::perceptual_post_filter = true;
speex_mode SpeexSettings::preferred_band = automatic_band;
speex_channels SpeexSettings::preferred_channels = automatic_channels;
float SpeexSettings::sampling_rate = 0;
int SpeexSettings::sampling_rate = 0;
SpeexSettings::SpeexSettings()
{
@ -28,7 +28,7 @@ SpeexSettings::PreferredChannels(void)
}
// if non-zero, specifies a sampling rate in Hertz
/* static */ float
/* static */ int
SpeexSettings::SamplingRate(void)
{
return sampling_rate;

View File

@ -20,11 +20,11 @@ public:
static speex_mode PreferredBand(void);
static speex_channels PreferredChannels(void);
// if non-zero, specifies a sampling rate in Hertz
static float SamplingRate(void);
static int SamplingRate(void);
private:
static bool perceptual_post_filter;
static speex_mode preferred_band;
static speex_channels preferred_channels;
static float sampling_rate;
static int sampling_rate;
};

View File

@ -31,8 +31,9 @@ speexDecoder::speexDecoder()
speex_bits_init(&fBits);
fDecoderState = 0;
fHeader = 0;
fStereoState = 0;
fSpeexFrameSize = 0;
fSpeexBytesRemaining = 0;
fSpeexBuffer = 0;
fStartTime = 0;
fFrameSize = 0;
fOutputBufferSize = 0;
@ -42,6 +43,8 @@ speexDecoder::speexDecoder()
speexDecoder::~speexDecoder()
{
TRACE("speexDecoder::~speexDecoder\n");
delete fStereoState;
delete fSpeexBuffer;
speex_bits_destroy(&fBits);
speex_decoder_destroy(fDecoderState);
}
@ -51,6 +54,7 @@ status_t
speexDecoder::Setup(media_format *inputFormat,
const void *infoBuffer, int32 infoSize)
{
debugger("speexDecoder::Setup");
if (inputFormat->type != B_MEDIA_ENCODED_AUDIO) {
TRACE("speexDecoder::Setup not called with audio stream: not speex\n");
return B_ERROR;
@ -81,37 +85,54 @@ speexDecoder::Setup(media_format *inputFormat,
fHeader = 0;
return B_ERROR;
}
if (fHeader->mode >= SPEEX_NB_MODES) {
TRACE("speexDecoder::Setup failed: unknown speex mode\n");
return B_ERROR;
}
// setup mode
SpeexMode * mode;
// modify header to reflect settings
switch (SpeexSettings::PreferredBand()) {
case narrow_band:
mode = &speex_nb_mode;
fHeader->mode = 0;
break;
case wide_band:
mode = &speex_wb_mode;
fHeader->mode = 1;
break;
case ultra_wide_band:
mode = &speex_uwb_mode;
fHeader->mode = 2;
break;
case automatic_band:
default:
mode = speex_mode_list[fHeader->mode];
break;
}
switch (SpeexSettings::PreferredChannels()) {
case mono_channels:
fHeader->nb_channels = 1;
break;
case stereo_channels:
fHeader->nb_channels = 2;
break;
case automatic_channels:
default:
break;
}
if (SpeexSettings::SamplingRate() != 0) {
fHeader->rate = SpeexSettings::SamplingRate();
}
// sanity checks
#ifdef STRICT_SPEEX
if (header->speex_version_id > 1) {
TRACE("speexDecoder::Setup failed: version id too new");
return B_ERROR;
}
#endif
if (fHeader->mode >= SPEEX_NB_MODES) {
TRACE("speexDecoder::Setup failed: unknown speex mode\n");
return B_ERROR;
}
// setup from header
SpeexMode * mode = speex_mode_list[fHeader->mode];
#ifdef STRICT_SPEEX
if (mode->bitstream_version != fHeader->mode_bitstream_version) {
TRACE("speexDecoder::Setup failed: bitstream version mismatch");
return B_ERROR;
}
#endif // STRICT_SPEEX
#endif
fDecoderState = speex_decoder_init(mode);
if (fDecoderState == NULL) {
TRACE("speexDecoder::Setup failed to initialize the decoder state");
@ -119,11 +140,22 @@ speexDecoder::Setup(media_format *inputFormat,
}
if (SpeexSettings::PerceptualPostFilter()) {
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, &fSpeexFrameSize);
if (fHeader->nb_channels == 2) {
SpeexCallback callback;
SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT;
callback.callback_id = SPEEX_INBAND_STEREO;
callback.func = speex_std_stereo_request_handler;
fStereoState = new SpeexStereoState(stereo);
callback.data = fStereoState;
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);
// fill out the encoding format
CopyInfoToEncodedFormat(inputFormat);
return B_OK;
@ -137,6 +169,9 @@ void speexDecoder::CopyInfoToEncodedFormat(media_format * format) {
= (media_encoded_audio_format::audio_encoding)'Spee';
if (fHeader->bitrate > 0) {
format->u.encoded_audio.bit_rate = fHeader->bitrate;
} else {
speex_decoder_ctl(fDecoderState, SPEEX_GET_BITRATE, &fHeader->bitrate);
format->u.encoded_audio.bit_rate = fHeader->bitrate;
}
if (fHeader->nb_channels == 1) {
format->u.encoded_audio.multi_info.channel_mask = B_CHANNEL_LEFT;
@ -154,6 +189,7 @@ void speexDecoder::CopyInfoToDecodedFormat(media_raw_audio_format * raf) {
raf->byte_order = B_MEDIA_HOST_ENDIAN; // XXX should support other endain, too
if (raf->buffer_size < 512 || raf->buffer_size > 65536) {
raf->buffer_size = AudioBufferSize(raf);
raf->buffer_size = (1 + raf->buffer_size / fSpeexFrameSize) * fSpeexFrameSize;
}
// setup output variables
fFrameSize = (raf->format & 0xf) * raf->channel_count;
@ -205,21 +241,7 @@ speexDecoder::Decode(void *buffer, int64 *frameCount,
//TRACE("speexDecoder: Decoding start time %.6f\n", fStartTime / 1000000.0);
// debugger("speexDecoder::Decode");
while (out_bytes_needed > 0) {
if (fSpeexBytesRemaining > 0) {
if (fSpeexBytesRemaining < out_bytes_needed) {
memcpy(out_buffer,fSpeexBuffer,fSpeexBytesRemaining);
out_buffer += fSpeexBytesRemaining;
out_bytes_needed -= fSpeexBytesRemaining;
} else {
memcpy(out_buffer,fSpeexBuffer,out_bytes_needed);
memcpy(fSpeexBuffer,&fSpeexBuffer[fSpeexBytesRemaining],
fSpeexBytesRemaining-out_bytes_needed);
out_buffer += out_bytes_needed;
out_bytes_needed = 0;
break;
}
}
while (out_bytes_needed >= fSpeexFrameSize) {
// get a new packet
void *chunkBuffer;
int32 chunkSize;
@ -238,8 +260,12 @@ speexDecoder::Decode(void *buffer, int64 *frameCount,
}
ogg_packet * packet = static_cast<ogg_packet*>(chunkBuffer);
speex_bits_read_from(&fBits, (char*)packet->packet, packet->bytes);
speex_decode(fDecoderState, &fBits, fSpeexBuffer);
fSpeexBytesRemaining = fSpeexFrameSize;
speex_decode(fDecoderState, &fBits, (float*)out_buffer);
if (fHeader->nb_channels == 2) {
speex_decode_stereo((float*)out_buffer, fSpeexFrameSize, fStereoState);
}
out_buffer += fSpeexFrameSize;
out_bytes_needed -= fSpeexFrameSize;
}
done:

View File

@ -1,6 +1,7 @@
#include "DecoderPlugin.h"
#include "speex.h"
#include "speex_header.h"
#include "speex_stereo.h"
#include "speex_callbacks.h"
class speexDecoder : public Decoder
@ -29,10 +30,10 @@ private:
SpeexBits fBits;
void * fDecoderState;
SpeexHeader * fHeader;
SpeexStereoState * fStereoState;
int fSpeexFrameSize;
float * fSpeexBuffer;
int fSpeexBytesRemaining;
bigtime_t fStartTime;
int fFrameSize;