Add non-interleaved PCM output

This commit is contained in:
Vladislav Mikhalin
2024-11-06 18:50:12 +03:00
parent 57d31bb364
commit 3acdcdc78f
4 changed files with 72 additions and 33 deletions

View File

@@ -11,41 +11,41 @@
static At9Status DecodeFrame(Frame* frame, BitReaderCxt* br);
static void ImdctBlock(Block* block);
static void ApplyIntensityStereo(Block* block);
static void PcmFloatToShort(Frame* frame, short* pcmOut);
static void PcmFloatToS32(Frame* frame, int* pcmOut);
static void PcmFloatToF32(Frame* frame, float* pcmOut);
static void PcmFloatToShort(Frame* frame, short* pcmOut, int nointerleave);
static void PcmFloatToS32(Frame* frame, int* pcmOut, int nointerleave);
static void PcmFloatToF32(Frame* frame, float* pcmOut, int nointerleave);
At9Status Decode(Atrac9Handle* handle, const unsigned char* audio, unsigned char* pcm, int* bytesUsed)
At9Status Decode(Atrac9Handle* handle, const unsigned char* audio, unsigned char* pcm, int* bytesUsed, int nointerleave)
{
BitReaderCxt br;
InitBitReaderCxt(&br, audio);
ERROR_CHECK(DecodeFrame(&handle->Frame, &br));
PcmFloatToShort(&handle->Frame, (short*)pcm);
PcmFloatToShort(&handle->Frame, (short*)pcm, nointerleave);
*bytesUsed = br.Position / 8;
return ERR_SUCCESS;
}
At9Status DecodeS32(Atrac9Handle* handle, const unsigned char* audio, int* pcm, int* bytesUsed)
At9Status DecodeS32(Atrac9Handle* handle, const unsigned char* audio, int* pcm, int* bytesUsed, int nointerleave)
{
BitReaderCxt br;
InitBitReaderCxt(&br, audio);
ERROR_CHECK(DecodeFrame(&handle->Frame, &br));
PcmFloatToS32(&handle->Frame, pcm);
PcmFloatToS32(&handle->Frame, pcm, nointerleave);
*bytesUsed = br.Position / 8;
return ERR_SUCCESS;
}
At9Status DecodeF32(Atrac9Handle* handle, const unsigned char* audio, float* pcm, int* bytesUsed)
At9Status DecodeF32(Atrac9Handle* handle, const unsigned char* audio, float* pcm, int* bytesUsed, int nointerleave)
{
BitReaderCxt br;
InitBitReaderCxt(&br, audio);
ERROR_CHECK(DecodeFrame(&handle->Frame, &br));
PcmFloatToF32(&handle->Frame, pcm);
PcmFloatToF32(&handle->Frame, pcm, nointerleave);
*bytesUsed = br.Position / 8;
return ERR_SUCCESS;
@@ -69,50 +69,89 @@ static At9Status DecodeFrame(Frame* frame, BitReaderCxt* br)
return ERR_SUCCESS;
}
void PcmFloatToShort(Frame* frame, short* pcmOut)
void PcmFloatToShort(Frame* frame, short* pcmOut, int nointerleave)
{
const int channelCount = frame->Config->ChannelCount;
const int sampleCount = frame->Config->FrameSamples;
Channel** channels = frame->Channels;
int i = 0;
for (int smpl = 0; smpl < sampleCount; smpl++)
if (nointerleave)
{
for (int ch = 0; ch < channelCount; ch++, i++)
for (int ch = 0; ch < channelCount; ch++)
{
pcmOut[i] = Clamp16(Round(channels[ch]->Pcm[smpl]));
for (int smpl = 0; smpl < sampleCount; smpl++, i++)
{
pcmOut[i] = Clamp16(Round(channels[ch]->Pcm[smpl]));
}
}
}
else
{
for (int smpl = 0; smpl < sampleCount; smpl++)
{
for (int ch = 0; ch < channelCount; ch++, i++)
{
pcmOut[i] = Clamp16(Round(channels[ch]->Pcm[smpl]));
}
}
}
}
void PcmFloatToS32(Frame* frame, int* pcmOut)
void PcmFloatToS32(Frame* frame, int* pcmOut, int nointerleave)
{
const int channelCount = frame->Config->ChannelCount;
const int sampleCount = frame->Config->FrameSamples;
Channel** channels = frame->Channels;
int i = 0;
for (int smpl = 0; smpl < sampleCount; smpl++)
if (nointerleave)
{
for (int ch = 0; ch < channelCount; ch++, i++)
for (int ch = 0; ch < channelCount; ch++)
{
pcmOut[i] = Round(channels[ch]->Pcm[smpl]);
for (int smpl = 0; smpl < sampleCount; smpl++, i++)
{
pcmOut[i] = Round(channels[ch]->Pcm[smpl]);
}
}
}
else
{
for (int smpl = 0; smpl < sampleCount; smpl++)
{
for (int ch = 0; ch < channelCount; ch++, i++)
{
pcmOut[i] = Round(channels[ch]->Pcm[smpl]);
}
}
}
}
void PcmFloatToF32(Frame* frame, float* pcmOut)
void PcmFloatToF32(Frame* frame, float* pcmOut, int nointerleave)
{
const int channelCount = frame->Config->ChannelCount;
const int sampleCount = frame->Config->FrameSamples;
Channel** channels = frame->Channels;
int i = 0;
for (int smpl = 0; smpl < sampleCount; smpl++)
if (nointerleave)
{
for (int ch = 0; ch < channelCount; ch++, i++)
for (int ch = 0; ch < channelCount; ch++)
{
pcmOut[i] = (float)channels[ch]->Pcm[smpl];
for (int smpl = 0; smpl < sampleCount; smpl++, i++)
{
pcmOut[i] = (float)channels[ch]->Pcm[smpl];
}
}
}
else
{
for (int smpl = 0; smpl < sampleCount; smpl++)
{
for (int ch = 0; ch < channelCount; ch++, i++)
{
pcmOut[i] = (float)channels[ch]->Pcm[smpl];
}
}
}
}

View File

@@ -3,7 +3,7 @@
#include "error_codes.h"
#include "structures.h"
At9Status Decode(Atrac9Handle* handle, const unsigned char* audio, unsigned char* pcm, int* bytesUsed);
At9Status DecodeS32(Atrac9Handle* handle, const unsigned char* audio, int* pcm, int* bytesUsed);
At9Status DecodeF32(Atrac9Handle* handle, const unsigned char* audio, float* pcm, int* bytesUsed);
At9Status Decode(Atrac9Handle* handle, const unsigned char* audio, unsigned char* pcm, int* bytesUsed, int nointerleave);
At9Status DecodeS32(Atrac9Handle* handle, const unsigned char* audio, int* pcm, int* bytesUsed, int nointerleave);
At9Status DecodeF32(Atrac9Handle* handle, const unsigned char* audio, float* pcm, int* bytesUsed, int nointerleave);
int GetCodecInfo(Atrac9Handle* handle, CodecInfo* pCodecInfo);

View File

@@ -20,19 +20,19 @@ int Atrac9InitDecoder(void* handle, unsigned char * pConfigData)
return InitDecoder(handle, pConfigData, 16);
}
int Atrac9Decode(void* handle, const unsigned char *pAtrac9Buffer, short *pPcmBuffer, int *pNBytesUsed)
int Atrac9Decode(void* handle, const unsigned char *pAtrac9Buffer, short *pPcmBuffer, int *pNBytesUsed, int nointerleave)
{
return Decode(handle, pAtrac9Buffer, (unsigned char*)pPcmBuffer, pNBytesUsed);
return Decode(handle, pAtrac9Buffer, (unsigned char*)pPcmBuffer, pNBytesUsed, nointerleave);
}
int Atrac9DecodeS32(void* handle, const unsigned char *pAtrac9Buffer, int *pPcmBuffer, int *pNBytesUsed)
int Atrac9DecodeS32(void* handle, const unsigned char *pAtrac9Buffer, int *pPcmBuffer, int *pNBytesUsed, int nointerleave)
{
return DecodeS32(handle, pAtrac9Buffer, pPcmBuffer, pNBytesUsed);
return DecodeS32(handle, pAtrac9Buffer, pPcmBuffer, pNBytesUsed, nointerleave);
}
int Atrac9DecodeF32(void* handle, const unsigned char *pAtrac9Buffer, float *pPcmBuffer, int *pNBytesUsed)
int Atrac9DecodeF32(void* handle, const unsigned char *pAtrac9Buffer, float *pPcmBuffer, int *pNBytesUsed, int nointerleave)
{
return DecodeF32(handle, pAtrac9Buffer, pPcmBuffer, pNBytesUsed);
return DecodeF32(handle, pAtrac9Buffer, pPcmBuffer, pNBytesUsed, nointerleave);
}
int Atrac9GetCodecInfo(void* handle, Atrac9CodecInfo * pCodecInfo)

View File

@@ -20,9 +20,9 @@ void* Atrac9GetHandle(void);
void Atrac9ReleaseHandle(void* handle);
int Atrac9InitDecoder(void* handle, unsigned char *pConfigData);
int Atrac9Decode(void* handle, const unsigned char *pAtrac9Buffer, short *pPcmBuffer, int *pNBytesUsed);
int Atrac9DecodeS32(void* handle, const unsigned char *pAtrac9Buffer, int *pPcmBuffer, int *pNBytesUsed);
int Atrac9DecodeF32(void* handle, const unsigned char *pAtrac9Buffer, float *pPcmBuffer, int *pNBytesUsed);
int Atrac9Decode(void* handle, const unsigned char *pAtrac9Buffer, short *pPcmBuffer, int *pNBytesUsed, int nointerleave);
int Atrac9DecodeS32(void* handle, const unsigned char *pAtrac9Buffer, int *pPcmBuffer, int *pNBytesUsed, int nointerleave);
int Atrac9DecodeF32(void* handle, const unsigned char *pAtrac9Buffer, float *pPcmBuffer, int *pNBytesUsed, int nointerleave);
int Atrac9GetCodecInfo(void* handle, Atrac9CodecInfo *pCodecInfo);