mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #19062 from hrydgard/atrac-fix-mono-output
Fix mono output from Atrac decoders. (sceAtrac*MOut* functions)
This commit is contained in:
commit
c782d54464
9 changed files with 32 additions and 19 deletions
|
@ -831,7 +831,7 @@ void Atrac::SeekToSample(int sample) {
|
|||
const u32 start = off - track_.dataOff < backfill ? track_.dataOff : off - backfill;
|
||||
|
||||
for (u32 pos = start; pos < off; pos += track_.bytesPerFrame) {
|
||||
decoder_->Decode(BufferStart() + pos, track_.bytesPerFrame, nullptr, nullptr, nullptr);
|
||||
decoder_->Decode(BufferStart() + pos, track_.bytesPerFrame, nullptr, 2, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -933,7 +933,7 @@ u32 Atrac::DecodeData(u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, i
|
|||
uint8_t *indata = BufferStart() + off;
|
||||
int bytesConsumed = 0;
|
||||
int outBytes = 0;
|
||||
if (!decoder_->Decode(indata, track_.bytesPerFrame, &bytesConsumed, outbuf, &outBytes)) {
|
||||
if (!decoder_->Decode(indata, track_.bytesPerFrame, &bytesConsumed, outputChannels_, outbuf, &outBytes)) {
|
||||
// Decode failed.
|
||||
*SamplesNum = 0;
|
||||
*finish = 1;
|
||||
|
|
|
@ -948,7 +948,7 @@ static int sceAtracLowLevelDecode(int atracID, u32 sourceAddr, u32 sourceBytesCo
|
|||
|
||||
int bytesConsumed = 0;
|
||||
int bytesWritten = 0;
|
||||
atrac->GetDecoder()->Decode(srcp, atrac->GetTrack().BytesPerFrame(), &bytesConsumed, outp, &bytesWritten);
|
||||
atrac->GetDecoder()->Decode(srcp, atrac->GetTrack().BytesPerFrame(), &bytesConsumed, 2, outp, &bytesWritten);
|
||||
*srcConsumed = bytesConsumed;
|
||||
*outWritten = bytesWritten;
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ static int sceAudiocodecDecode(u32 ctxPtr, int codec) {
|
|||
auto ctx = PSPPointer<AudioCodecContext>::Create(ctxPtr); // On stack, no need to allocate.
|
||||
// Decode audio
|
||||
int inDataConsumed = 0;
|
||||
decoder->Decode(Memory::GetPointer(ctx->inDataPtr), ctx->inDataSize, &inDataConsumed, Memory::GetPointerWrite(ctx->outDataPtr), &outbytes);
|
||||
decoder->Decode(Memory::GetPointer(ctx->inDataPtr), ctx->inDataSize, &inDataConsumed, 2, Memory::GetPointerWrite(ctx->outDataPtr), &outbytes);
|
||||
}
|
||||
DEBUG_LOG(ME, "sceAudiocodecDec(%08x, %i (%s))", ctxPtr, codec, GetCodecName(codec));
|
||||
return 0;
|
||||
|
|
|
@ -744,7 +744,7 @@ static u32 sceMp3LowLevelDecode(u32 mp3, u32 sourceAddr, u32 sourceBytesConsumed
|
|||
|
||||
int outpcmbytes = 0;
|
||||
int inbytesConsumed = 0;
|
||||
ctx->decoder->Decode(inbuff, 4096, &inbytesConsumed, outbuff, &outpcmbytes);
|
||||
ctx->decoder->Decode(inbuff, 4096, &inbytesConsumed, 2, outbuff, &outpcmbytes);
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, samplesAddr, outpcmbytes, "Mp3LowLevelDecode");
|
||||
|
||||
Memory::Write_U32(inbytesConsumed, sourceBytesConsumedAddr);
|
||||
|
|
|
@ -15,7 +15,8 @@ inline int16_t clamp16(float f) {
|
|||
// Test case for ATRAC3: Mega Man Maverick Hunter X, PSP menu sound
|
||||
class Atrac3Audio : public AudioDecoder {
|
||||
public:
|
||||
Atrac3Audio(PSPAudioType audioType, int channels, size_t blockAlign, const uint8_t *extraData, size_t extraDataSize) : audioType_(audioType) {
|
||||
Atrac3Audio(PSPAudioType audioType, int channels, size_t blockAlign, const uint8_t *extraData, size_t extraDataSize)
|
||||
: audioType_(audioType), channels_(channels) {
|
||||
blockAlign_ = (int)blockAlign;
|
||||
if (audioType == PSP_CODEC_AT3PLUS) {
|
||||
at3pCtx_ = atrac3p_alloc(channels, &blockAlign_);
|
||||
|
@ -55,7 +56,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, uint8_t *outbuf, int *outbytes) override {
|
||||
bool Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, int outputChannels, uint8_t *outbuf, int *outbytes) override {
|
||||
if (!codecOpen_) {
|
||||
_dbg_assert_(false);
|
||||
}
|
||||
|
@ -84,12 +85,20 @@ public:
|
|||
*outbytes = nb_samples * 2 * 2;
|
||||
}
|
||||
if (outbuf) {
|
||||
// Convert frame to outbuf. TODO: Very SIMDable, though hardly hot.
|
||||
for (int channel = 0; channel < 2; channel++) {
|
||||
int16_t *output = (int16_t *)outbuf;
|
||||
_dbg_assert_(outputChannels == 1 || outputChannels == 2);
|
||||
int16_t *output = (int16_t *)outbuf;
|
||||
const float *left = buffers_[0];
|
||||
if (outputChannels == 2) {
|
||||
// Stereo output, standard.
|
||||
const float *right = channels_ == 2 ? buffers_[1] : buffers_[0];
|
||||
for (int i = 0; i < nb_samples; i++) {
|
||||
output[i * 2] = clamp16(buffers_[0][i]);
|
||||
output[i * 2 + 1] = clamp16(buffers_[1][i]);
|
||||
output[i * 2] = clamp16(left[i]);
|
||||
output[i * 2 + 1] = clamp16(right[i]);
|
||||
}
|
||||
} else {
|
||||
// Mono output, just take the left channel.
|
||||
for (int i = 0; i < nb_samples; i++) {
|
||||
output[i] = clamp16(left[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +122,7 @@ private:
|
|||
ATRAC3PContext *at3pCtx_ = nullptr;
|
||||
ATRAC3Context *at3Ctx_ = nullptr;
|
||||
|
||||
int channels_ = 0;
|
||||
int blockAlign_ = 0;
|
||||
|
||||
int outSamples_ = 0;
|
||||
|
|
|
@ -1078,7 +1078,7 @@ int MediaEngine::getAudioSamples(u32 bufferPtr) {
|
|||
}
|
||||
|
||||
int inbytesConsumed = 0;
|
||||
if (!m_audioContext->Decode(audioFrame, frameSize, &inbytesConsumed, buffer, &outbytes)) {
|
||||
if (!m_audioContext->Decode(audioFrame, frameSize, &inbytesConsumed, 2, buffer, &outbytes)) {
|
||||
ERROR_LOG(ME, "Audio (%s) decode failed during video playback", GetCodecName(m_audioType));
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,9 @@ public:
|
|||
}
|
||||
~MiniMp3Audio() {}
|
||||
|
||||
bool Decode(const uint8_t* inbuf, int inbytes, int *inbytesConsumed, uint8_t *outbuf, int *outbytes) override {
|
||||
bool Decode(const uint8_t* inbuf, int inbytes, int *inbytesConsumed, int outputChannels, uint8_t *outbuf, int *outbytes) override {
|
||||
_dbg_assert_(outputChannels == 2);
|
||||
|
||||
mp3dec_frame_info_t info{};
|
||||
int samplesWritten = mp3dec_decode_frame(&mp3_, inbuf, inbytes, (mp3d_sample_t *)outbuf, &info);
|
||||
*inbytesConsumed = info.frame_bytes;
|
||||
|
@ -101,7 +103,7 @@ public:
|
|||
FFmpegAudioDecoder(PSPAudioType audioType, int sampleRateHz = 44100, int channels = 2);
|
||||
~FFmpegAudioDecoder();
|
||||
|
||||
bool Decode(const uint8_t* inbuf, int inbytes, int *inbytesConsumed, uint8_t *outbuf, int *outbytes) override;
|
||||
bool Decode(const uint8_t* inbuf, int inbytes, int *inbytesConsumed, int outputChannels, uint8_t *outbuf, int *outbytes) override;
|
||||
bool IsOK() const override {
|
||||
#ifdef USE_FFMPEG
|
||||
return codec_ != 0;
|
||||
|
@ -264,7 +266,7 @@ FFmpegAudioDecoder::~FFmpegAudioDecoder() {
|
|||
}
|
||||
|
||||
// Decodes a single input frame.
|
||||
bool FFmpegAudioDecoder::Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, uint8_t *outbuf, int *outbytes) {
|
||||
bool FFmpegAudioDecoder::Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, int outputChannels, uint8_t *outbuf, int *outbytes) {
|
||||
#ifdef USE_FFMPEG
|
||||
if (!codecOpen_) {
|
||||
OpenCodec(inbytes);
|
||||
|
@ -315,6 +317,7 @@ bool FFmpegAudioDecoder::Decode(const uint8_t *inbuf, int inbytes, int *inbytesC
|
|||
|
||||
if (got_frame) {
|
||||
// Initializing the sample rate convert. We will use it to convert float output into int.
|
||||
_dbg_assert_(outputChannels == 2);
|
||||
int64_t wanted_channel_layout = AV_CH_LAYOUT_STEREO; // we want stereo output layout
|
||||
int64_t dec_channel_layout = frame_->channel_layout; // decoded channel layout
|
||||
|
||||
|
@ -436,7 +439,7 @@ u32 AuCtx::AuDecode(u32 pcmAddr) {
|
|||
nextSync = (int)FindNextMp3Sync();
|
||||
}
|
||||
int inbytesConsumed = 0;
|
||||
decoder->Decode(&sourcebuff[nextSync], (int)sourcebuff.size() - nextSync, &inbytesConsumed, outbuf, &outpcmbufsize);
|
||||
decoder->Decode(&sourcebuff[nextSync], (int)sourcebuff.size() - nextSync, &inbytesConsumed, 2, outbuf, &outpcmbufsize);
|
||||
|
||||
if (outpcmbufsize == 0) {
|
||||
// Nothing was output, hopefully we're at the end of the stream.
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
virtual PSPAudioType GetAudioType() const = 0;
|
||||
|
||||
// inbytesConsumed can include skipping metadata.
|
||||
virtual bool Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, uint8_t *outbuf, int *outbytes) = 0;
|
||||
virtual bool Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, int outputChannels, uint8_t *outbuf, int *outbytes) = 0;
|
||||
virtual bool IsOK() const = 0;
|
||||
|
||||
// These two are only ever called after Decode, so can initialize on first.
|
||||
|
|
|
@ -219,7 +219,7 @@ public:
|
|||
while (bgQueue.size() < (size_t)(len * 2)) {
|
||||
int outBytes = 0;
|
||||
int inbytesConsumed = 0;
|
||||
decoder_->Decode(wave_.raw_data + raw_offset_, wave_.raw_bytes_per_frame, &inbytesConsumed, (uint8_t *)buffer_, &outBytes);
|
||||
decoder_->Decode(wave_.raw_data + raw_offset_, wave_.raw_bytes_per_frame, &inbytesConsumed, 2, (uint8_t *)buffer_, &outBytes);
|
||||
if (!outBytes)
|
||||
return false;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue