** Copyright 2004, Axel DΓΆrfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the MIT License.
*/
#include <stdio.h>
#include <string.h>
#include "MusePackDecoder.h"
#include "mpc/in_mpc.h"
MusePackDecoder::MusePackDecoder()
:
fDecoder(NULL)
{
}
MusePackDecoder::~MusePackDecoder()
{
delete fDecoder;
}
void
MusePackDecoder::GetCodecInfo(media_codec_info *info)
{
strcpy(info->short_name, "musepack");
strcpy(info->pretty_name, "MusePack audio codec based on mpcdec by Andree Buschmann");
}
status_t
MusePackDecoder::Setup(media_format *ioEncodedFormat, const void *infoBuffer, size_t infoSize)
{
if (infoBuffer == NULL || infoSize != sizeof(MPC_decoder))
return B_BAD_VALUE;
fDecoder = (MPC_decoder *)infoBuffer;
fFrameRate = fDecoder->fInfo->simple.SampleFreq;
fFramePosition = 0;
return B_OK;
}
status_t
MusePackDecoder::NegotiateOutputFormat(media_format *format)
{
format->type = B_MEDIA_RAW_AUDIO;
format->u.raw_audio.frame_rate = fFrameRate;
format->u.raw_audio.channel_count = fDecoder->fInfo->simple.Channels;
format->u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT;
format->u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN;
format->u.raw_audio.buffer_size = sizeof(MPC_SAMPLE_FORMAT) * FRAMELEN * 2;
if (format->u.raw_audio.channel_mask == 0) {
format->u.raw_audio.channel_mask = (format->u.raw_audio.channel_count == 1) ?
B_CHANNEL_LEFT : B_CHANNEL_LEFT | B_CHANNEL_RIGHT;
}
return B_OK;
}
status_t
MusePackDecoder::SeekedTo(int64 frame, bigtime_t time)
{
fFramePosition = 0;
return B_ERROR;
}
status_t
MusePackDecoder::Decode(void *buffer, int64 *_frameCount, media_header *mediaHeader, media_decode_info *info)
{
mediaHeader->start_time = (bigtime_t) ((1000 * fFramePosition) / (fFrameRate / 1000.0));
uint32 ring = fDecoder->Zaehler;
int frameCount = fDecoder->DECODE((MPC_SAMPLE_FORMAT *)buffer);
frameCount /= 2;
fDecoder->UpdateBuffer(ring);
fFramePosition += frameCount;
*_frameCount = frameCount;
return frameCount > 0 ? B_OK : B_LAST_BUFFER_ERROR;
}