Skip to content

Commit

Permalink
- Optimize audio mixing.
Browse files Browse the repository at this point in the history
  • Loading branch information
Extrems committed Apr 7, 2024
1 parent 96bf27c commit 2936e0d
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 19 deletions.
20 changes: 10 additions & 10 deletions cube/patches/base/audio.c
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Extrems <extrems@extremscorner.org>
* Copyright (c) 2020-2024, Extrems <extrems@extremscorner.org>
*
* This file is part of Swiss.
*
Expand Down Expand Up @@ -50,8 +50,8 @@ static int_fast16_t decode_sample(uint8_t header, int sample, int32_t prev[2])
int index = (header & 0x30) >> 4;
int shift = header & 0xF;

int32_t curr = prev[0] * table[0][index] -
prev[1] * table[1][index];
int32_t curr = prev[0] * table[0][index]
- prev[1] * table[1][index];

curr = clamp_s22((curr + 32) >> 6) + ((int16_t)(sample << 12) >> shift << 6);

Expand Down Expand Up @@ -89,38 +89,38 @@ void adpcm_reset(adpcm_t *adpcm)
adpcm->r[0] = adpcm->r[1] = 0;
}

void adpcm_decode(adpcm_t *adpcm, fifo_t *out, uint8_t *in, int count)
void adpcm_decode(adpcm_t *adpcm, fifo_t *fifo, const uint8_t *in, int count)
{
for (int j = 0; j < count; j += 28, in += 32) {
for (int i = 0; i < 28; i++) {
sample_t sample;
sample.l = decode_sample(in[0], in[4 + i] & 0xF, adpcm->l);
sample.r = decode_sample(in[1], in[4 + i] >> 4, adpcm->r);
push_sample(out, sample);
push_sample(fifo, sample);
}
}
}

void mix_samples(volatile sample_t *out, fifo_t *in, int count, bool _3to2, uint8_t volume_l, uint8_t volume_r)
void mix_samples(volatile sample_t *out, volatile sample_t *in, fifo_t *fifo, int count, bool _3to2, uint8_t volume_l, uint8_t volume_r)
{
for (int i = 0; i < count; i++) {
sample_t sample = {0};
pop_sample(in, &sample);
pop_sample(fifo, &sample);
int_fast16_t r = sample.r;
int_fast16_t l = sample.l;

if (i & _3to2) {
pop_sample(in, &sample);
pop_sample(fifo, &sample);
r = (r + sample.r) >> 1;
l = (l + sample.l) >> 1;
}

sample = *out;
sample = in[i];
r = (r * volume_r >> 8) + sample.r;
l = (l * volume_l >> 8) + sample.l;

sample.r = clamp_s16(r);
sample.l = clamp_s16(l);
*out++ = sample;
out[i] = sample;
}
}
6 changes: 3 additions & 3 deletions cube/patches/base/audio.h
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Extrems <extrems@extremscorner.org>
* Copyright (c) 2020-2024, Extrems <extrems@extremscorner.org>
*
* This file is part of Swiss.
*
Expand Down Expand Up @@ -35,8 +35,8 @@ typedef struct {
} sample_t;

void adpcm_reset(adpcm_t *adpcm);
void adpcm_decode(adpcm_t *adpcm, fifo_t *out, uint8_t *in, int count);
void adpcm_decode(adpcm_t *adpcm, fifo_t *fifo, const uint8_t *in, int count);

void mix_samples(volatile sample_t *out, fifo_t *in, int count, bool _3to2, uint8_t volume_l, uint8_t volume_r);
void mix_samples(volatile sample_t *out, volatile sample_t *in, fifo_t *fifo, int count, bool _3to2, uint8_t volume_l, uint8_t volume_r);

#endif /* AUDIO_H */
13 changes: 7 additions & 6 deletions cube/patches/base/emulator.c
Expand Up @@ -927,23 +927,24 @@ static void dsp_write(unsigned index, uint16_t value)
dsp.regs[index - 24] = value;

if ((value & 0x8000) && dsp.req.aima >= 0) {
void *buffer = OSPhysicalToUncached(dsp.reg.aima);
void *in = OSPhysicalToUncached(dsp.reg.aima);
int length = (dsp.reg.aibl & 0x7FFF) << 5;
int count = length / sizeof(sample_t);
void *out = in;

if (length <= sizeof(**dsp.buffer)) {
void *buffer2 = dsp.buffer[0];
out = dsp.buffer[0];
dsp.buffer[0] = dsp.buffer[1];
dsp.buffer[1] = buffer2;
buffer = memcpy(buffer2, buffer, length);
dsp.buffer[1] = out;
}

uint32_t aicr = AI[0];
uint32_t aivr = AI[1];

if (aicr & 0b0000001) mix_samples(buffer, &dtk.fifo, count, aicr & 0b1000000, aivr, aivr >> 8);
if (aicr & 0b0000001) mix_samples(out, in, &dtk.fifo, count, aicr & 0b1000000, aivr, aivr >> 8);
else if (out != in) out = memcpy(out, in, length);

DSP[12] = (intptr_t)buffer;
DSP[12] = (intptr_t)out;
DSP[13] = ((length >> 5) & 0x7FFF) | 0x8000;

dtk_fill_buffer();
Expand Down

0 comments on commit 2936e0d

Please sign in to comment.