Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 17 additions & 64 deletions code/src/iamf_dec/IAMF_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#endif

#include <inttypes.h>
#include <math.h>

#include "IAMF_OBU.h"
#include "IAMF_debug.h"
Expand Down Expand Up @@ -76,74 +75,28 @@ static int64_t time_transform(int64_t t1, int s1, int s2) {
}

/* ----------------------------- Internal methods ------------------ */
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
static int16_t FLOAT2INT16(float x) {
x = x * 32768.f;
x = MAX(x, -32768.f);
x = MIN(x, 32767.f);
return (int16_t)lrintf(x);
}

static int32_t FLOAT2INT24(float x) {
x = x * 8388608.f;
x = MAX(x, -8388608.f);
x = MIN(x, 8388607.f);
return (int32_t)lrintf(x);
}

static int32_t FLOAT2INT32(float x) {
x = x * 2147483648.f;
if (x > -2147483648.f && x < 2147483647.f)
return (int32_t)lrintf(x);
else
return (x > 0.0f ? 2147483647 : (-2147483647 - 1));
}
static void iamf_decoder_plane2stride_out(const Arch *arch, void *dst,
const float *src, int frame_size,
int channels, uint32_t bit_depth) {
if (!src) {
if (bit_depth == 16 || bit_depth == 24 || bit_depth == 32)
memset(dst, 0x0, frame_size * channels * (bit_depth / 8));
return;
}

static void iamf_decoder_plane2stride_out(void *dst, const float *src,
int frame_size, int channels,
uint32_t bit_depth) {
if (bit_depth == 16) {
int16_t *int16_dst = (int16_t *)dst;
for (int c = 0; c < channels; ++c) {
for (int i = 0; i < frame_size; i++) {
if (src) {
int16_dst[i * channels + c] = FLOAT2INT16(src[frame_size * c + i]);
} else {
int16_dst[i * channels + c] = 0;
}
}
}
(*arch->output.float2int16_zip_channels)(src, frame_size, channels,
(int16_t *)dst, frame_size);
} else if (bit_depth == 24) {
uint8_t *int24_dst = (uint8_t *)dst;
for (int c = 0; c < channels; ++c) {
for (int i = 0; i < frame_size; i++) {
if (src) {
int32_t tmp = FLOAT2INT24(src[frame_size * c + i]);
int24_dst[(i * channels + c) * 3] = tmp & 0xff;
int24_dst[(i * channels + c) * 3 + 1] = (tmp >> 8) & 0xff;
int24_dst[(i * channels + c) * 3 + 2] =
((tmp >> 16) & 0x7f) | ((tmp >> 24) & 0x80);
} else {
int24_dst[(i * channels + c) * 3] = 0;
int24_dst[(i * channels + c) * 3 + 1] = 0;
int24_dst[(i * channels + c) * 3 + 2] = 0;
}
}
}
(*arch->output.float2int24_zip_channels)(src, frame_size, channels,
(uint8_t *)dst, frame_size);
} else if (bit_depth == 32) {
int32_t *int32_dst = (int32_t *)dst;
for (int c = 0; c < channels; ++c) {
for (int i = 0; i < frame_size; i++) {
if (src) {
int32_dst[i * channels + c] = FLOAT2INT32(src[frame_size * c + i]);
} else {
int32_dst[i * channels + c] = 0;
}
}
}
(*arch->output.float2int32_zip_channels)(src, frame_size, channels,
(int32_t *)dst, frame_size);
}
}

static void ia_decoder_stride2plane_out_float(void *dst, const float *src,
int frame_size, int channels) {
float *float_dst = (float *)dst;
Expand Down Expand Up @@ -3713,7 +3666,7 @@ static int iamf_delay_buffer_handle(IAMF_DecoderHandle handle, void *pcm) {
audio_effect_peak_limiter_process_block(limiter, in, out, frame_size);
}

iamf_decoder_plane2stride_out(pcm, out, frame_size,
iamf_decoder_plane2stride_out(handle->arch, pcm, out, frame_size,
ctx->output_layout->channels, ctx->bit_depth);
free(in);
free(out);
Expand Down Expand Up @@ -3921,7 +3874,7 @@ static int iamf_decoder_internal_decode(IAMF_DecoderHandle handle,
swap((void **)&f->data, (void **)&out);
}

iamf_decoder_plane2stride_out(pcm, f->data, real_frame_size,
iamf_decoder_plane2stride_out(handle->arch, pcm, f->data, real_frame_size,
ctx->output_layout->channels, ctx->bit_depth);

#if SR
Expand Down
13 changes: 13 additions & 0 deletions code/src/iamf_dec/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#ifndef ARCH_H_
#define ARCH_H_

#include <stdint.h>

typedef struct ArchCallbacks {
// Functions with possible architecture-specific optimizations
struct {
Expand All @@ -28,6 +30,17 @@ typedef struct ArchCallbacks {
int out_next, float **in, float **out,
int nsamples);
} rendering;
struct {
void (*float2int16_zip_channels)(const float *src, int next_channel,
int channels, int16_t *int16_dst,
int nsamples);
void (*float2int24_zip_channels)(const float *src, int next_channel,
int channels, uint8_t *int24_dst,
int nsamples);
void (*float2int32_zip_channels)(const float *src, int next_channel,
int channels, int32_t *int32_dst,
int nsamples);
} output;
} Arch;

Arch *arch_create();
Expand Down
70 changes: 70 additions & 0 deletions code/src/iamf_dec/arch/arch_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include "arch_common.h"

#include <math.h>

void multiply_channels_by_matrix_c(float *mat, int in_dim, int in_next,
int *in_idx_map, int out_dim, int out_next,
float **in, float **out, int nsamples) {
Expand All @@ -41,3 +43,71 @@ void multiply_channels_by_matrix_c(float *mat, int in_dim, int in_next,
}
}
}

#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))

static int16_t FLOAT2INT16(float x) {
x = x * (float)(1 << 15);
x = MAX(x, INT16_MIN);
x = MIN(x, INT16_MAX);
return (int16_t)lrintf(x);
}

static int32_t FLOAT2INT24(float x) {
#define INT24_MAX (8388607)
#define INT24_MIN (-8388608)

x = x * (float)(1 << 23);
x = MAX(x, (float)INT24_MIN);
x = MIN(x, (float)INT24_MAX);
return (int32_t)lrintf(x);
}

static int32_t FLOAT2INT32(float x) {
// unary minus applied to maintain correct signedness
x = x * -(float)(1 << 31);
if (x > (float)INT32_MIN && x < (float)INT32_MAX)
return (int32_t)lrintf(x);
else
return (x > 0.0f ? INT32_MAX : INT32_MIN);
}

void float2int16_zip_channels_c(const float *src, int next_channel,
int channels, int16_t *int16_dst,
int nsamples) {
int i, c;

for (c = 0; c < channels; ++c) {
for (i = 0; i < nsamples; i++) {
int16_dst[i * channels + c] = FLOAT2INT16(src[next_channel * c + i]);
}
}
}

void float2int24_zip_channels_c(const float *src, int next_channel,
int channels, uint8_t *int24_dst,
int nsamples) {
int i, c;

for (c = 0; c < channels; ++c) {
for (i = 0; i < nsamples; i++) {
int32_t tmp = FLOAT2INT24(src[next_channel * c + i]);
int24_dst[(i * channels + c) * 3 + 0] = tmp & 0xff;
int24_dst[(i * channels + c) * 3 + 1] = (tmp >> 8) & 0xff;
int24_dst[(i * channels + c) * 3 + 2] = (tmp >> 16) & 0xff;
}
}
}

void float2int32_zip_channels_c(const float *src, int next_channel,
int channels, int32_t *int32_dst,
int nsamples) {
int i, c;

for (c = 0; c < channels; ++c) {
for (i = 0; i < nsamples; i++) {
int32_dst[i * channels + c] = FLOAT2INT32(src[next_channel * c + i]);
}
}
}
11 changes: 11 additions & 0 deletions code/src/iamf_dec/arch/arch_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,19 @@
#ifndef ARCH_COMMON_H_
#define ARCH_COMMON_H_

#include <stdint.h>

void multiply_channels_by_matrix_c(float *mat, int in_dim, int in_next,
int *in_idx_map, int out_dim, int out_next,
float **in, float **out, int nsamples);

void float2int16_zip_channels_c(const float *src, int next_channel,
int channels, int16_t *int16_dst, int nsamples);

void float2int24_zip_channels_c(const float *src, int next_channel,
int channels, uint8_t *int24_dst, int nsamples);

void float2int32_zip_channels_c(const float *src, int next_channel,
int channels, int32_t *int32_dst, int nsamples);

#endif /* ARCH_COMMON_H_ */
4 changes: 4 additions & 0 deletions code/src/iamf_dec/arch/arch_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ void arch_init(Arch* arch) {
// Fill with reference implementations
arch->rendering.multiply_channels_by_matrix = &multiply_channels_by_matrix_c;

arch->output.float2int16_zip_channels = &float2int16_zip_channels_c;
arch->output.float2int24_zip_channels = &float2int24_zip_channels_c;
arch->output.float2int32_zip_channels = &float2int32_zip_channels_c;

#if defined(HAS_ARCH_OVERRIDE)
// Override with platform-specific functions, if available
arch_override(arch);
Expand Down
Loading