forked from Ports/perfect_dark
port: begin implementing audio
mixer taken from sm64-port and modified to fit PD's naudio thing MP3 playback not supported yet audio buffering sucks
This commit is contained in:
1 parent
866be01860
commit
ffb5ca4b5b
19 files changed
+1403
-15
No files matched your search
@@ -265,6 +265,8 @@ typedef short RESAMPLE_STATE[16];
|
||||
*/
|
||||
typedef short ENVMIX_STATE[40];
|
||||
|
||||
#ifdef PLATFORM_N64
|
||||
|
||||
/*
|
||||
* Macros to assemble the audio command list
|
||||
*/
|
||||
@@ -402,6 +404,12 @@ typedef short ENVMIX_STATE[40];
|
||||
_a->words.w1 = (unsigned int) d; \
|
||||
}
|
||||
|
||||
#else // PLATFORM_N64
|
||||
|
||||
#include "mixer.h"
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _LANGUAGE_C */
|
||||
|
||||
#endif /* !_ABI_H_ */
|
||||
|
||||
@@ -71,7 +71,7 @@ typedef struct {
|
||||
s32 maxAuxBusses;
|
||||
s32 outputRate;
|
||||
s32 maxOutSamples;
|
||||
s32 sv_dramout;
|
||||
uintptr_t sv_dramout;
|
||||
s32 sv_first;
|
||||
} N_ALSynth;
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef _IN_AUDIO_H
|
||||
#define _IN_AUDIO_H
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
|
||||
s32 audioInit(void);
|
||||
s32 audioGetBytesBuffered(void);
|
||||
void audioSetNextBuffer(const s16 *buf, u32 len);
|
||||
void audioEndFrame(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef MIXER_H
|
||||
#define MIXER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ultra64.h>
|
||||
|
||||
#undef aSegment
|
||||
#undef aClearBuffer
|
||||
#undef aSetBuffer
|
||||
#undef aLoadBuffer
|
||||
#undef aSaveBuffer
|
||||
#undef aDMEMMove
|
||||
#undef aMix
|
||||
#undef aEnvMixer
|
||||
#undef aResample
|
||||
#undef aInterleave
|
||||
#undef aSetVolume
|
||||
#undef aSetVolume32
|
||||
#undef aSetLoop
|
||||
#undef aLoadADPCM
|
||||
#undef aADPCMdec
|
||||
|
||||
void aClearBufferImpl(uint16_t addr, int nbytes);
|
||||
void aLoadADPCMImpl(int num_entries_times_16, const int16_t *book_source_addr);
|
||||
void aDMEMMoveImpl(uint16_t in_addr, uint16_t out_addr, int nbytes);
|
||||
void aSetLoopImpl(ADPCM_STATE *adpcm_loop_state);
|
||||
void aADPCMdecImpl(uint8_t flags, ADPCM_STATE state, int nbytes, uint16_t inofs, uint16_t outofs);
|
||||
void aResampleImpl(uint8_t flags, uint16_t pitch, RESAMPLE_STATE state, uint16_t inofs, uint8_t outflag);
|
||||
void aLoadBufferImpl(const void *source_addr, uint16_t dest_addr, uint16_t nbytes);
|
||||
void aSaveBufferImpl(uint16_t source_addr, int16_t *dest_addr, uint16_t nbytes);
|
||||
void aInterleaveImpl(void);
|
||||
void aMixImpl(uint8_t flags, int16_t gain, uint16_t in_addr, uint16_t out_addr);
|
||||
void aEnvMixerImpl(uint8_t flags, ENVMIX_STATE state, int16_t some_vol);
|
||||
void aSetVolumeImpl(uint8_t flags, int16_t v, int16_t t, int16_t r);
|
||||
void aPoleFilterImpl(uint8_t flags, int16_t gain, uint32_t t, uint32_t addr);
|
||||
void aDisableImpl(uint16_t outp, uint32_t b, uint32_t c);
|
||||
void aPlayMP3Impl(uint32_t a, const void *b);
|
||||
|
||||
#define aDisable(pkt, o, b, c) aDisableImpl(o, b, c)
|
||||
#define aClearBuffer(pkt, d, c) aClearBufferImpl(d, c)
|
||||
#define aLoadBuffer(pkt, c, d, s) aLoadBufferImpl(s, d, c)
|
||||
#define aSaveBuffer(pkt, c, s, d) aSaveBufferImpl(s, d, c)
|
||||
#define aLoadADPCM(pkt, c, d) aLoadADPCMImpl(c, d)
|
||||
#define aDMEMMove(pkt, i, o, c) aDMEMMoveImpl(i, o, c)
|
||||
#define aSetLoop(pkt, a) aSetLoopImpl(a)
|
||||
#define aADPCMdec(pkt, s, f, c, i, o) aADPCMdecImpl(f, s, c, i, o)
|
||||
#define aResample(pkt, s, f, p, i, o) aResampleImpl(f, p, s, i, o)
|
||||
#define aInterleave(pkt) aInterleaveImpl()
|
||||
#define aMix(pkt, f, g, i, o) aMixImpl(f, g, i, o)
|
||||
#define aEnvMixer(pkt, f, t, s) aEnvMixerImpl(f, s, t)
|
||||
#define aSetVolume(pkt, f, v, t, r) aSetVolumeImpl(f, v, t, r)
|
||||
#define aPoleFilter(pkt, f, g, t, s) aPoleFilterImpl(f, g, t, s)
|
||||
#define aPlayMP3(pkt, a, b) aPlayMP3Impl(a, b)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <PR/ultratypes.h>
|
||||
#include <stdio.h>
|
||||
#include <SDL.h>
|
||||
#include "audio.h"
|
||||
|
||||
#define SAMPLES_HIGH 736
|
||||
#define SAMPLES_LOW 720
|
||||
|
||||
static SDL_AudioDeviceID dev;
|
||||
static const s16 *nextBuf;
|
||||
static u32 nextSize = 0;
|
||||
|
||||
s32 audioInit(void)
|
||||
{
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0) {
|
||||
fprintf(stderr, "SDL audio init error: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_AudioSpec want, have;
|
||||
SDL_zero(want);
|
||||
want.freq = 22020;
|
||||
want.format = AUDIO_S16SYS;
|
||||
want.channels = 2;
|
||||
want.samples = 512;
|
||||
want.callback = NULL;
|
||||
|
||||
nextBuf = NULL;
|
||||
|
||||
dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
|
||||
if (dev == 0) {
|
||||
fprintf(stderr, "SDL_OpenAudio error: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_PauseAudioDevice(dev, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 audioGetBytesBuffered(void)
|
||||
{
|
||||
return SDL_GetQueuedAudioSize(dev);
|
||||
}
|
||||
|
||||
void audioSetNextBuffer(const s16 *buf, u32 len)
|
||||
{
|
||||
nextBuf = buf;
|
||||
nextSize = len;
|
||||
}
|
||||
|
||||
void audioEndFrame(void)
|
||||
{
|
||||
if (nextBuf && nextSize) {
|
||||
SDL_QueueAudio(dev, nextBuf, nextSize);
|
||||
nextBuf = NULL;
|
||||
nextSize = 0;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -19,8 +19,8 @@ static s32 mouseX, mouseY;
|
||||
static s32 mouseDX, mouseDY;
|
||||
static u32 mouseButtons;
|
||||
|
||||
static f32 mouseSensX = 0.33f;
|
||||
static f32 mouseSensY = 0.33f;
|
||||
static f32 mouseSensX = 0.25f;
|
||||
static f32 mouseSensY = 0.25f;
|
||||
|
||||
void inputSetDefaultKeyBinds(void) {
|
||||
// TODO: make VK constants for all these
|
||||
|
||||
+3
-1
@@ -8,6 +8,7 @@
|
||||
#include "system.h"
|
||||
#include "input.h"
|
||||
#include "video.h"
|
||||
#include "audio.h"
|
||||
|
||||
#define EEPROM_SIZE (EEP16K_MAXBLOCKS * 8)
|
||||
#define EEPROM_FNAME "eeprom.bin"
|
||||
@@ -165,11 +166,12 @@ s32 osAiSetFrequency(u32 frequency)
|
||||
|
||||
u32 osAiGetLength(void)
|
||||
{
|
||||
return 0;
|
||||
return audioGetBytesBuffered();
|
||||
}
|
||||
|
||||
s32 osAiSetNextBuffer(void *bufPtr, u32 size)
|
||||
{
|
||||
audioSetNextBuffer(bufPtr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -55,12 +55,12 @@ int main(int argc, const char **argv)
|
||||
fsInit();
|
||||
videoInit();
|
||||
inputInit();
|
||||
audioInit();
|
||||
romdataInit();
|
||||
|
||||
bootCreateSched();
|
||||
|
||||
g_OsMemSize = osGetMemSize();
|
||||
g_SndDisabled = true; // for now
|
||||
|
||||
g_MempHeapSize = g_OsMemSize;
|
||||
g_MempHeap = calloc(1, g_MempHeapSize);
|
||||
|
||||
@@ -0,0 +1,689 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <ultra64.h>
|
||||
|
||||
#include "mixer.h"
|
||||
#include "platform.h"
|
||||
|
||||
/*
|
||||
#ifdef __SSE4_1__
|
||||
#include <immintrin.h>
|
||||
#define HAS_SSE41 1
|
||||
#define HAS_NEON 0
|
||||
#elif __ARM_NEON
|
||||
#include <arm_neon.h>
|
||||
#define HAS_SSE41 0
|
||||
#define HAS_NEON 1
|
||||
#else
|
||||
#define HAS_SSE41 0
|
||||
#define HAS_NEON 0
|
||||
#endif
|
||||
*/
|
||||
|
||||
#define HAS_SSE41 0
|
||||
#define HAS_NEON 0
|
||||
|
||||
#pragma GCC optimize ("unroll-loops")
|
||||
|
||||
#if HAS_SSE41
|
||||
#define LOADLH(l, h) _mm_castpd_si128(_mm_loadh_pd(_mm_load_sd((const double *)(l)), (const double *)(h)))
|
||||
#endif
|
||||
|
||||
#define ROUND_UP_64(v) (((v) + 63) & ~63)
|
||||
#define ROUND_UP_32(v) (((v) + 31) & ~31)
|
||||
#define ROUND_UP_16(v) (((v) + 15) & ~15)
|
||||
#define ROUND_UP_8(v) (((v) + 7) & ~7)
|
||||
#define ROUND_DOWN_16(v) ((v) & ~0xf)
|
||||
|
||||
#define BUF_SIZE 3072 // 2720 + slack
|
||||
#define BUF_U8(a) (rspa.buf.as_u8 + (a))
|
||||
#define BUF_S16(a) (rspa.buf.as_s16 + (a) / sizeof(int16_t))
|
||||
|
||||
#define NUM_SAMPLES 0xB8
|
||||
#define NUM_BYTES 0x170
|
||||
|
||||
#define OFS_BASE 0
|
||||
#define OFS_TEMP1 0x170
|
||||
#define OFS_MAIN_L 0x4E0
|
||||
#define OFS_MAIN_R 0x650
|
||||
#define OFS_AUX_L 0x7C0
|
||||
#define OFS_AUX_R 0x930
|
||||
|
||||
static struct {
|
||||
int16_t vol[2];
|
||||
|
||||
int16_t target[2];
|
||||
int32_t rate[2];
|
||||
|
||||
int16_t vol_dry;
|
||||
int16_t vol_wet;
|
||||
|
||||
ADPCM_STATE *adpcm_loop_state;
|
||||
|
||||
int16_t adpcm_table[8][2][8];
|
||||
|
||||
union {
|
||||
int16_t as_s16[BUF_SIZE / sizeof(int16_t)];
|
||||
uint8_t as_u8[BUF_SIZE];
|
||||
} buf;
|
||||
} rspa;
|
||||
|
||||
static int16_t resample_table[64][4] = {
|
||||
{0x0c39, 0x66ad, 0x0d46, 0xffdf}, {0x0b39, 0x6696, 0x0e5f, 0xffd8},
|
||||
{0x0a44, 0x6669, 0x0f83, 0xffd0}, {0x095a, 0x6626, 0x10b4, 0xffc8},
|
||||
{0x087d, 0x65cd, 0x11f0, 0xffbf}, {0x07ab, 0x655e, 0x1338, 0xffb6},
|
||||
{0x06e4, 0x64d9, 0x148c, 0xffac}, {0x0628, 0x643f, 0x15eb, 0xffa1},
|
||||
{0x0577, 0x638f, 0x1756, 0xff96}, {0x04d1, 0x62cb, 0x18cb, 0xff8a},
|
||||
{0x0435, 0x61f3, 0x1a4c, 0xff7e}, {0x03a4, 0x6106, 0x1bd7, 0xff71},
|
||||
{0x031c, 0x6007, 0x1d6c, 0xff64}, {0x029f, 0x5ef5, 0x1f0b, 0xff56},
|
||||
{0x022a, 0x5dd0, 0x20b3, 0xff48}, {0x01be, 0x5c9a, 0x2264, 0xff3a},
|
||||
{0x015b, 0x5b53, 0x241e, 0xff2c}, {0x0101, 0x59fc, 0x25e0, 0xff1e},
|
||||
{0x00ae, 0x5896, 0x27a9, 0xff10}, {0x0063, 0x5720, 0x297a, 0xff02},
|
||||
{0x001f, 0x559d, 0x2b50, 0xfef4}, {0xffe2, 0x540d, 0x2d2c, 0xfee8},
|
||||
{0xffac, 0x5270, 0x2f0d, 0xfedb}, {0xff7c, 0x50c7, 0x30f3, 0xfed0},
|
||||
{0xff53, 0x4f14, 0x32dc, 0xfec6}, {0xff2e, 0x4d57, 0x34c8, 0xfebd},
|
||||
{0xff0f, 0x4b91, 0x36b6, 0xfeb6}, {0xfef5, 0x49c2, 0x38a5, 0xfeb0},
|
||||
{0xfedf, 0x47ed, 0x3a95, 0xfeac}, {0xfece, 0x4611, 0x3c85, 0xfeab},
|
||||
{0xfec0, 0x4430, 0x3e74, 0xfeac}, {0xfeb6, 0x424a, 0x4060, 0xfeaf},
|
||||
{0xfeaf, 0x4060, 0x424a, 0xfeb6}, {0xfeac, 0x3e74, 0x4430, 0xfec0},
|
||||
{0xfeab, 0x3c85, 0x4611, 0xfece}, {0xfeac, 0x3a95, 0x47ed, 0xfedf},
|
||||
{0xfeb0, 0x38a5, 0x49c2, 0xfef5}, {0xfeb6, 0x36b6, 0x4b91, 0xff0f},
|
||||
{0xfebd, 0x34c8, 0x4d57, 0xff2e}, {0xfec6, 0x32dc, 0x4f14, 0xff53},
|
||||
{0xfed0, 0x30f3, 0x50c7, 0xff7c}, {0xfedb, 0x2f0d, 0x5270, 0xffac},
|
||||
{0xfee8, 0x2d2c, 0x540d, 0xffe2}, {0xfef4, 0x2b50, 0x559d, 0x001f},
|
||||
{0xff02, 0x297a, 0x5720, 0x0063}, {0xff10, 0x27a9, 0x5896, 0x00ae},
|
||||
{0xff1e, 0x25e0, 0x59fc, 0x0101}, {0xff2c, 0x241e, 0x5b53, 0x015b},
|
||||
{0xff3a, 0x2264, 0x5c9a, 0x01be}, {0xff48, 0x20b3, 0x5dd0, 0x022a},
|
||||
{0xff56, 0x1f0b, 0x5ef5, 0x029f}, {0xff64, 0x1d6c, 0x6007, 0x031c},
|
||||
{0xff71, 0x1bd7, 0x6106, 0x03a4}, {0xff7e, 0x1a4c, 0x61f3, 0x0435},
|
||||
{0xff8a, 0x18cb, 0x62cb, 0x04d1}, {0xff96, 0x1756, 0x638f, 0x0577},
|
||||
{0xffa1, 0x15eb, 0x643f, 0x0628}, {0xffac, 0x148c, 0x64d9, 0x06e4},
|
||||
{0xffb6, 0x1338, 0x655e, 0x07ab}, {0xffbf, 0x11f0, 0x65cd, 0x087d},
|
||||
{0xffc8, 0x10b4, 0x6626, 0x095a}, {0xffd0, 0x0f83, 0x6669, 0x0a44},
|
||||
{0xffd8, 0x0e5f, 0x6696, 0x0b39}, {0xffdf, 0x0d46, 0x66ad, 0x0c39}
|
||||
};
|
||||
|
||||
static inline int16_t clamp16(int32_t v) {
|
||||
if (v < -0x8000) {
|
||||
return -0x8000;
|
||||
} else if (v > 0x7fff) {
|
||||
return 0x7fff;
|
||||
}
|
||||
return (int16_t)v;
|
||||
}
|
||||
|
||||
static inline int32_t clamp32(int64_t v) {
|
||||
if (v < -0x7fffffff - 1) {
|
||||
return -0x7fffffff - 1;
|
||||
} else if (v > 0x7fffffff) {
|
||||
return 0x7fffffff;
|
||||
}
|
||||
return (int32_t)v;
|
||||
}
|
||||
|
||||
void aClearBufferImpl(uint16_t addr, int nbytes) {
|
||||
nbytes = ROUND_UP_16(nbytes);
|
||||
memset(BUF_U8(addr), 0, nbytes);
|
||||
}
|
||||
|
||||
void aLoadBufferImpl(const void *source_addr, uint16_t dest_addr, uint16_t nbytes) {
|
||||
memcpy(BUF_U8(dest_addr), source_addr, ROUND_UP_8(nbytes));
|
||||
}
|
||||
|
||||
void aSaveBufferImpl(uint16_t source_addr, int16_t *dest_addr, uint16_t nbytes) {
|
||||
memcpy(dest_addr, BUF_S16(source_addr), ROUND_UP_8(nbytes));
|
||||
}
|
||||
|
||||
void aLoadADPCMImpl(int num_entries_times_16, const int16_t *book_source_addr) {
|
||||
memcpy(rspa.adpcm_table, book_source_addr, num_entries_times_16);
|
||||
}
|
||||
|
||||
void aInterleaveImpl(void) {
|
||||
const int16_t *l = BUF_S16(OFS_MAIN_L);
|
||||
const int16_t *r = BUF_S16(OFS_MAIN_R);
|
||||
int count = ROUND_UP_16(NUM_SAMPLES) / 8;
|
||||
int16_t *d = BUF_S16(OFS_BASE);
|
||||
while (count > 0) {
|
||||
int16_t l0 = *l++;
|
||||
int16_t l1 = *l++;
|
||||
int16_t l2 = *l++;
|
||||
int16_t l3 = *l++;
|
||||
int16_t l4 = *l++;
|
||||
int16_t l5 = *l++;
|
||||
int16_t l6 = *l++;
|
||||
int16_t l7 = *l++;
|
||||
int16_t r0 = *r++;
|
||||
int16_t r1 = *r++;
|
||||
int16_t r2 = *r++;
|
||||
int16_t r3 = *r++;
|
||||
int16_t r4 = *r++;
|
||||
int16_t r5 = *r++;
|
||||
int16_t r6 = *r++;
|
||||
int16_t r7 = *r++;
|
||||
*d++ = l0;
|
||||
*d++ = r0;
|
||||
*d++ = l1;
|
||||
*d++ = r1;
|
||||
*d++ = l2;
|
||||
*d++ = r2;
|
||||
*d++ = l3;
|
||||
*d++ = r3;
|
||||
*d++ = l4;
|
||||
*d++ = r4;
|
||||
*d++ = l5;
|
||||
*d++ = r5;
|
||||
*d++ = l6;
|
||||
*d++ = r6;
|
||||
*d++ = l7;
|
||||
*d++ = r7;
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
void aDMEMMoveImpl(uint16_t in_addr, uint16_t out_addr, int nbytes) {
|
||||
memmove(BUF_U8(out_addr), BUF_U8(in_addr), ROUND_UP_16(nbytes));
|
||||
}
|
||||
|
||||
void aSetLoopImpl(ADPCM_STATE *adpcm_loop_state) {
|
||||
rspa.adpcm_loop_state = adpcm_loop_state;
|
||||
}
|
||||
|
||||
void aADPCMdecImpl(uint8_t flags, ADPCM_STATE state, int nbytes, uint16_t inofs, uint16_t outofs) {
|
||||
#if HAS_SSE41
|
||||
const __m128i tblrev = _mm_setr_epi8(12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1, -1, -1);
|
||||
const __m128i pos0 = _mm_set_epi8(3, -1, 3, -1, 2, -1, 2, -1, 1, -1, 1, -1, 0, -1, 0, -1);
|
||||
const __m128i pos1 = _mm_set_epi8(7, -1, 7, -1, 6, -1, 6, -1, 5, -1, 5, -1, 4, -1, 4, -1);
|
||||
const __m128i mult = _mm_set_epi16(0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01);
|
||||
const __m128i mask = _mm_set1_epi16((int16_t)0xf000);
|
||||
#elif HAS_NEON
|
||||
static const int8_t pos0_data[] = {-1, 0, -1, 0, -1, 1, -1, 1, -1, 2, -1, 2, -1, 3, -1, 3};
|
||||
static const int8_t pos1_data[] = {-1, 4, -1, 4, -1, 5, -1, 5, -1, 6, -1, 6, -1, 7, -1, 7};
|
||||
static const int16_t mult_data[] = {0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10};
|
||||
static const int16_t table_prefix_data[] = {0, 0, 0, 0, 0, 0, 0, 1 << 11};
|
||||
const int8x16_t pos0 = vld1q_s8(pos0_data);
|
||||
const int8x16_t pos1 = vld1q_s8(pos1_data);
|
||||
const int16x8_t mult = vld1q_s16(mult_data);
|
||||
const int16x8_t mask = vdupq_n_s16((int16_t)0xf000);
|
||||
const int16x8_t table_prefix = vld1q_s16(table_prefix_data);
|
||||
#endif
|
||||
uint8_t *in = BUF_U8(inofs);
|
||||
int16_t *out = BUF_S16(outofs);
|
||||
nbytes = ROUND_UP_32(nbytes);
|
||||
if (flags & A_INIT) {
|
||||
memset(out, 0, 16 * sizeof(int16_t));
|
||||
} else if (flags & A_LOOP) {
|
||||
memcpy(out, rspa.adpcm_loop_state, 16 * sizeof(int16_t));
|
||||
} else {
|
||||
memcpy(out, state, 16 * sizeof(int16_t));
|
||||
}
|
||||
out += 16;
|
||||
#if HAS_SSE41
|
||||
__m128i prev_interleaved = _mm_set1_epi32((uint16_t)out[-2] | ((uint16_t)out[-1] << 16));
|
||||
//__m128i prev_interleaved = _mm_shuffle_epi32(_mm_loadu_si32(out - 2), 0); // GCC misses this?
|
||||
#elif HAS_NEON
|
||||
int16x8_t result = vld1q_s16(out - 8);
|
||||
#endif
|
||||
while (nbytes > 0) {
|
||||
int shift = *in >> 4; // should be in 0..12
|
||||
int table_index = *in++ & 0xf; // should be in 0..7
|
||||
int16_t (*tbl)[8] = rspa.adpcm_table[table_index];
|
||||
int i;
|
||||
#if HAS_SSE41
|
||||
// The _mm_loadu_si64 instruction was added in GCC 9, and results in the same
|
||||
// asm as the following instructions, so better be compatible with old GCC.
|
||||
//__m128i inv = _mm_loadu_si64(in);
|
||||
uint64_t v; memcpy(&v, in, 8);
|
||||
__m128i inv = _mm_set_epi64x(0, v);
|
||||
__m128i invec[2] = {_mm_shuffle_epi8(inv, pos0), _mm_shuffle_epi8(inv, pos1)};
|
||||
__m128i tblvec0 = _mm_loadu_si128((const __m128i *)tbl[0]);
|
||||
__m128i tblvec1 = _mm_loadu_si128((const __m128i *)(tbl[1]));
|
||||
__m128i tbllo = _mm_unpacklo_epi16(tblvec0, tblvec1);
|
||||
__m128i tblhi = _mm_unpackhi_epi16(tblvec0, tblvec1);
|
||||
__m128i shiftcount = _mm_set_epi64x(0, 12 - shift); // _mm_cvtsi64_si128 does not exist on 32-bit x86
|
||||
__m128i tblvec1_rev[8];
|
||||
|
||||
tblvec1_rev[0] = _mm_insert_epi16(_mm_shuffle_epi8(tblvec1, tblrev), 1 << 11, 7);
|
||||
tblvec1_rev[1] = _mm_bsrli_si128(tblvec1_rev[0], 2);
|
||||
tblvec1_rev[2] = _mm_bsrli_si128(tblvec1_rev[0], 4);
|
||||
tblvec1_rev[3] = _mm_bsrli_si128(tblvec1_rev[0], 6);
|
||||
tblvec1_rev[4] = _mm_bsrli_si128(tblvec1_rev[0], 8);
|
||||
tblvec1_rev[5] = _mm_bsrli_si128(tblvec1_rev[0], 10);
|
||||
tblvec1_rev[6] = _mm_bsrli_si128(tblvec1_rev[0], 12);
|
||||
tblvec1_rev[7] = _mm_bsrli_si128(tblvec1_rev[0], 14);
|
||||
in += 8;
|
||||
for (i = 0; i < 2; i++) {
|
||||
__m128i acc0 = _mm_madd_epi16(prev_interleaved, tbllo);
|
||||
__m128i acc1 = _mm_madd_epi16(prev_interleaved, tblhi);
|
||||
__m128i muls[8];
|
||||
__m128i result;
|
||||
invec[i] = _mm_sra_epi16(_mm_and_si128(_mm_mullo_epi16(invec[i], mult), mask), shiftcount);
|
||||
|
||||
muls[7] = _mm_madd_epi16(tblvec1_rev[0], invec[i]);
|
||||
muls[6] = _mm_madd_epi16(tblvec1_rev[1], invec[i]);
|
||||
muls[5] = _mm_madd_epi16(tblvec1_rev[2], invec[i]);
|
||||
muls[4] = _mm_madd_epi16(tblvec1_rev[3], invec[i]);
|
||||
muls[3] = _mm_madd_epi16(tblvec1_rev[4], invec[i]);
|
||||
muls[2] = _mm_madd_epi16(tblvec1_rev[5], invec[i]);
|
||||
muls[1] = _mm_madd_epi16(tblvec1_rev[6], invec[i]);
|
||||
muls[0] = _mm_madd_epi16(tblvec1_rev[7], invec[i]);
|
||||
|
||||
acc0 = _mm_add_epi32(acc0, _mm_hadd_epi32(_mm_hadd_epi32(muls[0], muls[1]), _mm_hadd_epi32(muls[2], muls[3])));
|
||||
acc1 = _mm_add_epi32(acc1, _mm_hadd_epi32(_mm_hadd_epi32(muls[4], muls[5]), _mm_hadd_epi32(muls[6], muls[7])));
|
||||
|
||||
acc0 = _mm_srai_epi32(acc0, 11);
|
||||
acc1 = _mm_srai_epi32(acc1, 11);
|
||||
|
||||
result = _mm_packs_epi32(acc0, acc1);
|
||||
_mm_storeu_si128((__m128i *)out, result);
|
||||
out += 8;
|
||||
|
||||
prev_interleaved = _mm_shuffle_epi32(result, _MM_SHUFFLE(3, 3, 3, 3));
|
||||
}
|
||||
#elif HAS_NEON
|
||||
int8x8_t inv = vld1_s8((int8_t *)in);
|
||||
int16x8_t tblvec[2] = {vld1q_s16(tbl[0]), vld1q_s16(tbl[1])};
|
||||
int16x8_t invec[2] = {vreinterpretq_s16_s8(vcombine_s8(vtbl1_s8(inv, vget_low_s8(pos0)),
|
||||
vtbl1_s8(inv, vget_high_s8(pos0)))),
|
||||
vreinterpretq_s16_s8(vcombine_s8(vtbl1_s8(inv, vget_low_s8(pos1)),
|
||||
vtbl1_s8(inv, vget_high_s8(pos1))))};
|
||||
int16x8_t shiftcount = vdupq_n_s16(shift - 12); // negative means right shift
|
||||
int16x8_t tblvec1[8];
|
||||
|
||||
in += 8;
|
||||
tblvec1[0] = vextq_s16(table_prefix, tblvec[1], 7);
|
||||
invec[0] = vmulq_s16(invec[0], mult);
|
||||
tblvec1[1] = vextq_s16(table_prefix, tblvec[1], 6);
|
||||
invec[1] = vmulq_s16(invec[1], mult);
|
||||
tblvec1[2] = vextq_s16(table_prefix, tblvec[1], 5);
|
||||
tblvec1[3] = vextq_s16(table_prefix, tblvec[1], 4);
|
||||
invec[0] = vandq_s16(invec[0], mask);
|
||||
tblvec1[4] = vextq_s16(table_prefix, tblvec[1], 3);
|
||||
invec[1] = vandq_s16(invec[1], mask);
|
||||
tblvec1[5] = vextq_s16(table_prefix, tblvec[1], 2);
|
||||
tblvec1[6] = vextq_s16(table_prefix, tblvec[1], 1);
|
||||
invec[0] = vqshlq_s16(invec[0], shiftcount);
|
||||
invec[1] = vqshlq_s16(invec[1], shiftcount);
|
||||
tblvec1[7] = table_prefix;
|
||||
for (i = 0; i < 2; i++) {
|
||||
int32x4_t acc0;
|
||||
int32x4_t acc1;
|
||||
|
||||
acc1 = vmull_lane_s16(vget_high_s16(tblvec[0]), vget_high_s16(result), 2);
|
||||
acc1 = vmlal_lane_s16(acc1, vget_high_s16(tblvec[1]), vget_high_s16(result), 3);
|
||||
acc0 = vmull_lane_s16(vget_low_s16(tblvec[0]), vget_high_s16(result), 2);
|
||||
acc0 = vmlal_lane_s16(acc0, vget_low_s16(tblvec[1]), vget_high_s16(result), 3);
|
||||
|
||||
acc0 = vmlal_lane_s16(acc0, vget_low_s16(tblvec1[0]), vget_low_s16(invec[i]), 0);
|
||||
acc0 = vmlal_lane_s16(acc0, vget_low_s16(tblvec1[1]), vget_low_s16(invec[i]), 1);
|
||||
acc0 = vmlal_lane_s16(acc0, vget_low_s16(tblvec1[2]), vget_low_s16(invec[i]), 2);
|
||||
acc0 = vmlal_lane_s16(acc0, vget_low_s16(tblvec1[3]), vget_low_s16(invec[i]), 3);
|
||||
|
||||
acc1 = vmlal_lane_s16(acc1, vget_high_s16(tblvec1[0]), vget_low_s16(invec[i]), 0);
|
||||
acc1 = vmlal_lane_s16(acc1, vget_high_s16(tblvec1[1]), vget_low_s16(invec[i]), 1);
|
||||
acc1 = vmlal_lane_s16(acc1, vget_high_s16(tblvec1[2]), vget_low_s16(invec[i]), 2);
|
||||
acc1 = vmlal_lane_s16(acc1, vget_high_s16(tblvec1[3]), vget_low_s16(invec[i]), 3);
|
||||
acc1 = vmlal_lane_s16(acc1, vget_high_s16(tblvec1[4]), vget_high_s16(invec[i]), 0);
|
||||
acc1 = vmlal_lane_s16(acc1, vget_high_s16(tblvec1[5]), vget_high_s16(invec[i]), 1);
|
||||
acc1 = vmlal_lane_s16(acc1, vget_high_s16(tblvec1[6]), vget_high_s16(invec[i]), 2);
|
||||
acc1 = vmlal_lane_s16(acc1, vget_high_s16(tblvec1[7]), vget_high_s16(invec[i]), 3);
|
||||
|
||||
result = vcombine_s16(vqshrn_n_s32(acc0, 11), vqshrn_n_s32(acc1, 11));
|
||||
vst1q_s16(out, result);
|
||||
out += 8;
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < 2; i++) {
|
||||
int16_t ins[8];
|
||||
int16_t prev1 = out[-1];
|
||||
int16_t prev2 = out[-2];
|
||||
int j, k;
|
||||
for (j = 0; j < 4; j++) {
|
||||
ins[j * 2] = (((*in >> 4) << 28) >> 28) << shift;
|
||||
ins[j * 2 + 1] = (((*in++ & 0xf) << 28) >> 28) << shift;
|
||||
}
|
||||
for (j = 0; j < 8; j++) {
|
||||
int32_t acc = tbl[0][j] * prev2 + tbl[1][j] * prev1 + (ins[j] << 11);
|
||||
for (k = 0; k < j; k++) {
|
||||
acc += tbl[1][((j - k) - 1)] * ins[k];
|
||||
}
|
||||
acc >>= 11;
|
||||
*out++ = clamp16(acc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
nbytes -= 16 * sizeof(int16_t);
|
||||
}
|
||||
memcpy(state, out - 16, 16 * sizeof(int16_t));
|
||||
}
|
||||
|
||||
void aResampleImpl(uint8_t flags, uint16_t pitch, RESAMPLE_STATE state, uint16_t inofs, uint8_t outflag) {
|
||||
int16_t tmp[16];
|
||||
int16_t *in_initial = BUF_S16(inofs);
|
||||
int16_t *in = in_initial;
|
||||
int16_t *out = BUF_S16(OFS_BASE + ((outflag & 3) != 0) * NUM_BYTES);
|
||||
int nbytes = ROUND_UP_16(NUM_BYTES);
|
||||
uint32_t pitch_accumulator;
|
||||
int i;
|
||||
#if !HAS_SSE41 && !HAS_NEON
|
||||
int16_t *tbl;
|
||||
int32_t sample;
|
||||
#endif
|
||||
if (flags & A_INIT) {
|
||||
memset(tmp, 0, 5 * sizeof(int16_t));
|
||||
} else {
|
||||
memcpy(tmp, state, 16 * sizeof(int16_t));
|
||||
}
|
||||
if (flags & 2) {
|
||||
memcpy(in - 8, tmp + 8, 8 * sizeof(int16_t));
|
||||
in -= tmp[5] / sizeof(int16_t);
|
||||
}
|
||||
in -= 4;
|
||||
pitch_accumulator = (uint16_t)tmp[4];
|
||||
memcpy(in, tmp, 4 * sizeof(int16_t));
|
||||
|
||||
#if HAS_SSE41
|
||||
__m128i multiples = _mm_setr_epi16(0, 2, 4, 6, 8, 10, 12, 14);
|
||||
__m128i pitchvec = _mm_set1_epi16((int16_t)pitch);
|
||||
__m128i pitchvec_8_steps = _mm_set1_epi32((pitch << 1) * 8);
|
||||
__m128i pitchacclo_vec = _mm_set1_epi32((uint16_t)pitch_accumulator);
|
||||
__m128i pl = _mm_mullo_epi16(multiples, pitchvec);
|
||||
__m128i ph = _mm_mulhi_epu16(multiples, pitchvec);
|
||||
__m128i acc_a = _mm_add_epi32(_mm_unpacklo_epi16(pl, ph), pitchacclo_vec);
|
||||
__m128i acc_b = _mm_add_epi32(_mm_unpackhi_epi16(pl, ph), pitchacclo_vec);
|
||||
|
||||
do {
|
||||
__m128i tbl_positions = _mm_srli_epi16(_mm_packus_epi32(
|
||||
_mm_and_si128(acc_a, _mm_set1_epi32(0xffff)),
|
||||
_mm_and_si128(acc_b, _mm_set1_epi32(0xffff))), 10);
|
||||
|
||||
__m128i in_positions = _mm_packus_epi32(_mm_srli_epi32(acc_a, 16), _mm_srli_epi32(acc_b, 16));
|
||||
__m128i tbl_entries[4];
|
||||
__m128i samples[4];
|
||||
|
||||
/*for (i = 0; i < 4; i++) {
|
||||
tbl_entries[i] = _mm_castpd_si128(_mm_loadh_pd(_mm_load_sd(
|
||||
(const double *)resample_table[_mm_extract_epi16(tbl_positions, 2 * i)]),
|
||||
(const double *)resample_table[_mm_extract_epi16(tbl_positions, 2 * i + 1)]));
|
||||
samples[i] = _mm_castpd_si128(_mm_loadh_pd(_mm_load_sd(
|
||||
(const double *)&in[_mm_extract_epi16(in_positions, 2 * i)]),
|
||||
(const double *)&in[_mm_extract_epi16(in_positions, 2 * i + 1)]));
|
||||
samples[i] = _mm_mulhrs_epi16(samples[i], tbl_entries[i]);
|
||||
}*/
|
||||
tbl_entries[0] = LOADLH(resample_table[_mm_extract_epi16(tbl_positions, 0)], resample_table[_mm_extract_epi16(tbl_positions, 1)]);
|
||||
tbl_entries[1] = LOADLH(resample_table[_mm_extract_epi16(tbl_positions, 2)], resample_table[_mm_extract_epi16(tbl_positions, 3)]);
|
||||
tbl_entries[2] = LOADLH(resample_table[_mm_extract_epi16(tbl_positions, 4)], resample_table[_mm_extract_epi16(tbl_positions, 5)]);
|
||||
tbl_entries[3] = LOADLH(resample_table[_mm_extract_epi16(tbl_positions, 6)], resample_table[_mm_extract_epi16(tbl_positions, 7)]);
|
||||
samples[0] = LOADLH(&in[_mm_extract_epi16(in_positions, 0)], &in[_mm_extract_epi16(in_positions, 1)]);
|
||||
samples[1] = LOADLH(&in[_mm_extract_epi16(in_positions, 2)], &in[_mm_extract_epi16(in_positions, 3)]);
|
||||
samples[2] = LOADLH(&in[_mm_extract_epi16(in_positions, 4)], &in[_mm_extract_epi16(in_positions, 5)]);
|
||||
samples[3] = LOADLH(&in[_mm_extract_epi16(in_positions, 6)], &in[_mm_extract_epi16(in_positions, 7)]);
|
||||
samples[0] = _mm_mulhrs_epi16(samples[0], tbl_entries[0]);
|
||||
samples[1] = _mm_mulhrs_epi16(samples[1], tbl_entries[1]);
|
||||
samples[2] = _mm_mulhrs_epi16(samples[2], tbl_entries[2]);
|
||||
samples[3] = _mm_mulhrs_epi16(samples[3], tbl_entries[3]);
|
||||
|
||||
_mm_storeu_si128((__m128i *)out, _mm_hadds_epi16(_mm_hadds_epi16(samples[0], samples[1]), _mm_hadds_epi16(samples[2], samples[3])));
|
||||
|
||||
acc_a = _mm_add_epi32(acc_a, pitchvec_8_steps);
|
||||
acc_b = _mm_add_epi32(acc_b, pitchvec_8_steps);
|
||||
out += 8;
|
||||
nbytes -= 8 * sizeof(int16_t);
|
||||
} while (nbytes > 0);
|
||||
in += (uint16_t)_mm_extract_epi16(acc_a, 1);
|
||||
pitch_accumulator = (uint16_t)_mm_extract_epi16(acc_a, 0);
|
||||
#elif HAS_NEON
|
||||
static const uint16_t multiples_data[8] = {0, 2, 4, 6, 8, 10, 12, 14};
|
||||
uint16x8_t multiples = vld1q_u16(multiples_data);
|
||||
uint32x4_t pitchvec_8_steps = vdupq_n_u32((pitch << 1) * 8);
|
||||
uint32x4_t pitchacclo_vec = vdupq_n_u32((uint16_t)pitch_accumulator);
|
||||
uint32x4_t acc_a = vmlal_n_u16(pitchacclo_vec, vget_low_u16(multiples), pitch);
|
||||
uint32x4_t acc_b = vmlal_n_u16(pitchacclo_vec, vget_high_u16(multiples), pitch);
|
||||
|
||||
do {
|
||||
uint16x8x2_t unzipped = vuzpq_u16(vreinterpretq_u16_u32(acc_a), vreinterpretq_u16_u32(acc_b));
|
||||
uint16x8_t tbl_positions = vshrq_n_u16(unzipped.val[0], 10);
|
||||
uint16x8_t in_positions = unzipped.val[1];
|
||||
int16x8_t tbl_entries[4];
|
||||
int16x8_t samples[4];
|
||||
int16x8x2_t unzipped1;
|
||||
int16x8x2_t unzipped2;
|
||||
|
||||
tbl_entries[0] = vcombine_s16(vld1_s16(resample_table[vgetq_lane_u16(tbl_positions, 0)]), vld1_s16(resample_table[vgetq_lane_u16(tbl_positions, 1)]));
|
||||
tbl_entries[1] = vcombine_s16(vld1_s16(resample_table[vgetq_lane_u16(tbl_positions, 2)]), vld1_s16(resample_table[vgetq_lane_u16(tbl_positions, 3)]));
|
||||
tbl_entries[2] = vcombine_s16(vld1_s16(resample_table[vgetq_lane_u16(tbl_positions, 4)]), vld1_s16(resample_table[vgetq_lane_u16(tbl_positions, 5)]));
|
||||
tbl_entries[3] = vcombine_s16(vld1_s16(resample_table[vgetq_lane_u16(tbl_positions, 6)]), vld1_s16(resample_table[vgetq_lane_u16(tbl_positions, 7)]));
|
||||
samples[0] = vcombine_s16(vld1_s16(&in[vgetq_lane_u16(in_positions, 0)]), vld1_s16(&in[vgetq_lane_u16(in_positions, 1)]));
|
||||
samples[1] = vcombine_s16(vld1_s16(&in[vgetq_lane_u16(in_positions, 2)]), vld1_s16(&in[vgetq_lane_u16(in_positions, 3)]));
|
||||
samples[2] = vcombine_s16(vld1_s16(&in[vgetq_lane_u16(in_positions, 4)]), vld1_s16(&in[vgetq_lane_u16(in_positions, 5)]));
|
||||
samples[3] = vcombine_s16(vld1_s16(&in[vgetq_lane_u16(in_positions, 6)]), vld1_s16(&in[vgetq_lane_u16(in_positions, 7)]));
|
||||
samples[0] = vqrdmulhq_s16(samples[0], tbl_entries[0]);
|
||||
samples[1] = vqrdmulhq_s16(samples[1], tbl_entries[1]);
|
||||
samples[2] = vqrdmulhq_s16(samples[2], tbl_entries[2]);
|
||||
samples[3] = vqrdmulhq_s16(samples[3], tbl_entries[3]);
|
||||
|
||||
unzipped1 = vuzpq_s16(samples[0], samples[1]);
|
||||
unzipped2 = vuzpq_s16(samples[2], samples[3]);
|
||||
samples[0] = vqaddq_s16(unzipped1.val[0], unzipped1.val[1]);
|
||||
samples[1] = vqaddq_s16(unzipped2.val[0], unzipped2.val[1]);
|
||||
unzipped1 = vuzpq_s16(samples[0], samples[1]);
|
||||
samples[0] = vqaddq_s16(unzipped1.val[0], unzipped1.val[1]);
|
||||
|
||||
vst1q_s16(out, samples[0]);
|
||||
|
||||
acc_a = vaddq_u32(acc_a, pitchvec_8_steps);
|
||||
acc_b = vaddq_u32(acc_b, pitchvec_8_steps);
|
||||
out += 8;
|
||||
nbytes -= 8 * sizeof(int16_t);
|
||||
} while (nbytes > 0);
|
||||
in += vgetq_lane_u16(vreinterpretq_u16_u32(acc_a), 1);
|
||||
pitch_accumulator = vgetq_lane_u16(vreinterpretq_u16_u32(acc_a), 0);
|
||||
#else
|
||||
do {
|
||||
for (i = 0; i < 8; i++) {
|
||||
tbl = resample_table[pitch_accumulator * 64 >> 16];
|
||||
sample = ((in[0] * tbl[0] + 0x4000) >> 15) +
|
||||
((in[1] * tbl[1] + 0x4000) >> 15) +
|
||||
((in[2] * tbl[2] + 0x4000) >> 15) +
|
||||
((in[3] * tbl[3] + 0x4000) >> 15);
|
||||
*out++ = clamp16(sample);
|
||||
|
||||
pitch_accumulator += (pitch << 1);
|
||||
in += pitch_accumulator >> 16;
|
||||
pitch_accumulator %= 0x10000;
|
||||
}
|
||||
nbytes -= 8 * sizeof(int16_t);
|
||||
} while (nbytes > 0);
|
||||
#endif
|
||||
|
||||
state[4] = (int16_t)pitch_accumulator;
|
||||
memcpy(state, in, 4 * sizeof(int16_t));
|
||||
i = (in - in_initial + 4) & 7;
|
||||
in -= i;
|
||||
if (i != 0) {
|
||||
i = -8 - i;
|
||||
}
|
||||
state[5] = i;
|
||||
memcpy(state + 8, in, 8 * sizeof(int16_t));
|
||||
}
|
||||
|
||||
void aEnvMixerImpl(uint8_t flags, ENVMIX_STATE state, int16_t rvol) {
|
||||
int16_t *in = BUF_S16(OFS_BASE);
|
||||
int16_t *dry[2] = {BUF_S16(OFS_MAIN_L), BUF_S16(OFS_MAIN_R)};
|
||||
int16_t *wet[2] = {BUF_S16(OFS_AUX_L), BUF_S16(OFS_AUX_R)};
|
||||
int nsamples = NUM_SAMPLES;
|
||||
|
||||
rspa.vol[1] = rvol; // why the fuck is this here?
|
||||
|
||||
// naudio uses a linear envelope
|
||||
// TODO: sse/neon
|
||||
|
||||
int32_t t[2], tgt[2], rate[2];
|
||||
int16_t voldry, volwet;
|
||||
|
||||
if (flags & A_INIT) {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
t[i] = rspa.vol[i] << 16;
|
||||
tgt[i] = rspa.target[i] << 16;
|
||||
rate[i] = rspa.rate[i] >> 3;
|
||||
}
|
||||
voldry = rspa.vol_dry;
|
||||
volwet = rspa.vol_wet;
|
||||
} else {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
int16_t *base = state + i * 4;
|
||||
t[i] = base[0];
|
||||
tgt[i] = base[1] << 16;
|
||||
rate[i] = *(int32_t *)&base[2];
|
||||
}
|
||||
voldry = state[8];
|
||||
volwet = state[9];
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_BIG_ENDIAN
|
||||
#define XOR 0
|
||||
#else
|
||||
#define XOR 1
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < nsamples; ++i) {
|
||||
int16_t gain[4];
|
||||
int16_t vol[2];
|
||||
int16_t *outptr[4];
|
||||
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
t[j] += rate[j];
|
||||
if ((rate[j] <= 0 && t[j] <= tgt[j]) || (rate[j] > 0 && t[j] >= tgt[j])) {
|
||||
t[j] = tgt[j];
|
||||
rate[j] = 0;
|
||||
}
|
||||
vol[j] = t[j] >> 16;
|
||||
}
|
||||
|
||||
outptr[0] = dry[0] + (i^XOR);
|
||||
outptr[1] = dry[1] + (i^XOR);
|
||||
outptr[2] = wet[0] + (i^XOR);
|
||||
outptr[3] = wet[1] + (i^XOR);
|
||||
|
||||
gain[0] = clamp16((vol[0] * voldry + 0x4000) >> 15);
|
||||
gain[1] = clamp16((vol[1] * voldry + 0x4000) >> 15);
|
||||
gain[2] = clamp16((vol[0] * volwet + 0x4000) >> 15);
|
||||
gain[3] = clamp16((vol[1] * volwet + 0x4000) >> 15);
|
||||
|
||||
const int16_t insamp = in[i^XOR];
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
*outptr[j] = clamp16(*outptr[j] + ((insamp * gain[j]) >> 15));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
int16_t *base = state + i * 4;
|
||||
base[0] = t[i];
|
||||
base[1] = tgt[i] >> 16;
|
||||
*(int32_t *)&base[2] = rate[i];
|
||||
}
|
||||
state[8] = voldry;
|
||||
state[9] = volwet;
|
||||
|
||||
#undef XOR
|
||||
}
|
||||
|
||||
// flags is always 0 in PD
|
||||
void aMixImpl(uint8_t flags, int16_t gain, uint16_t in_addr, uint16_t out_addr) {
|
||||
int nbytes = ROUND_UP_16(NUM_BYTES); // can't round up to 32 here because 0x170 ain't gonna do that
|
||||
int16_t *in = BUF_S16(in_addr);
|
||||
int16_t *out = BUF_S16(out_addr);
|
||||
#if HAS_SSE41
|
||||
__m128i gain_vec = _mm_set1_epi16(gain);
|
||||
#elif !HAS_NEON
|
||||
int i;
|
||||
int32_t sample;
|
||||
#endif
|
||||
|
||||
#if !HAS_NEON
|
||||
if (gain == -0x8000) {
|
||||
while (nbytes > 0) {
|
||||
#if HAS_SSE41
|
||||
__m128i out1, in1;
|
||||
out1 = _mm_loadu_si128((const __m128i *)out);
|
||||
in1 = _mm_loadu_si128((const __m128i *)in);
|
||||
|
||||
out1 = _mm_subs_epi16(out1, in1);
|
||||
|
||||
_mm_storeu_si128((__m128i *)out, out1);
|
||||
|
||||
out += 8;
|
||||
in += 8;
|
||||
#else
|
||||
for (i = 0; i < 8; i++) {
|
||||
sample = *out - *in++;
|
||||
*out++ = clamp16(sample);
|
||||
}
|
||||
#endif
|
||||
|
||||
nbytes -= 8 * sizeof(int16_t);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while (nbytes > 0) {
|
||||
#if HAS_SSE41
|
||||
__m128i out1, in1;
|
||||
out1 = _mm_loadu_si128((const __m128i *)out);
|
||||
in1 = _mm_loadu_si128((const __m128i *)in);
|
||||
|
||||
out1 = _mm_adds_epi16(out1, _mm_mulhrs_epi16(in1, gain_vec));
|
||||
|
||||
_mm_storeu_si128((__m128i *)out, out1);
|
||||
|
||||
out += 8;
|
||||
in += 8;
|
||||
#elif HAS_NEON
|
||||
int16x8_t out1, in1;
|
||||
out1 = vld1q_s16(out);
|
||||
in1 = vld1q_s16(in);
|
||||
|
||||
out1 = vqaddq_s16(out1, vqrdmulhq_n_s16(in1, gain));
|
||||
|
||||
vst1q_s16(out, out1);
|
||||
|
||||
out += 8;
|
||||
in += 8;
|
||||
#else
|
||||
for (i = 0; i < 8; i++) {
|
||||
sample = ((*out * 0x7fff + *in++ * gain) + 0x4000) >> 15;
|
||||
*out++ = clamp16(sample);
|
||||
}
|
||||
#endif
|
||||
|
||||
nbytes -= 8 * sizeof(int16_t);
|
||||
}
|
||||
}
|
||||
|
||||
void aSetVolumeImpl(uint8_t flags, int16_t v, int16_t t, int16_t r) {
|
||||
// the flags are not really very intuitive here
|
||||
if (flags & A_VOL) {
|
||||
if (flags & A_LEFT) {
|
||||
rspa.vol[0] = v;
|
||||
rspa.vol_dry = t;
|
||||
rspa.vol_wet = r;
|
||||
} else {
|
||||
rspa.target[1] = v;
|
||||
rspa.rate[1] = (int32_t)((uint16_t)t << 16 | ((uint16_t)r));
|
||||
}
|
||||
} else /* A_RATE */ {
|
||||
rspa.target[0] = v;
|
||||
rspa.rate[0] = (int32_t)((uint16_t)t << 16 | ((uint16_t)r));
|
||||
}
|
||||
}
|
||||
|
||||
void aPlayMP3Impl(uint32_t a, const void *b) {
|
||||
// TODO: maybe just hook this up to libmpg123 or something
|
||||
}
|
||||
|
||||
void aPoleFilterImpl(uint8_t flags, int16_t gain, uint32_t t, uint32_t addr) {
|
||||
// this never gets called?
|
||||
}
|
||||
|
||||
void aDisableImpl(uint16_t outp, uint32_t b, uint32_t c) {
|
||||
// this never gets called?
|
||||
}
|
||||
+13
-1
@@ -22,7 +22,9 @@
|
||||
#include "types.h"
|
||||
|
||||
#include "video.h"
|
||||
#include "audio.h"
|
||||
#include "input.h"
|
||||
#include "mixer.h"
|
||||
|
||||
/*
|
||||
* private typedefs and defines
|
||||
@@ -220,7 +222,7 @@ void __scUpdateViMode(void)
|
||||
void schedSubmitTask(OSSched *sc, OSScTask *t)
|
||||
{
|
||||
if (sc->doAudio && t->list.t.type == M_AUDTASK) {
|
||||
// TODO: audio frame
|
||||
// send this into the mixer
|
||||
} else if (t->list.t.type == M_GFXTASK) {
|
||||
videoSubmitCommands((Gfx *)t->list.t.data_ptr);
|
||||
}
|
||||
@@ -231,6 +233,15 @@ void schedStartFrame(OSSched *sc)
|
||||
videoStartFrame();
|
||||
}
|
||||
|
||||
void schedAudioFrame(OSSched *sc)
|
||||
{
|
||||
if (!g_SndDisabled)
|
||||
{
|
||||
amgrFrame();
|
||||
audioEndFrame();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a retrace (vsync) event.
|
||||
*
|
||||
@@ -272,6 +283,7 @@ void schedEndFrame(OSSched *sc)
|
||||
joy00014238();
|
||||
|
||||
sndHandleRetrace();
|
||||
schedAudioFrame(sc);
|
||||
schedRenderCrashPeriodically(sc->frameCount);
|
||||
videoEndFrame();
|
||||
|
||||
|
||||
@@ -9839,11 +9839,7 @@ bool aiIfMusicEventQueueIsEmpty(void)
|
||||
{
|
||||
f32 value = (u64)osGetCount() * 64 / 3000;
|
||||
|
||||
#ifdef PLATFORM_N64
|
||||
if (g_MusicEventQueueLength) {
|
||||
#else // don't hang when sound is disabled
|
||||
if (g_MusicEventQueueLength && !g_SndDisabled) {
|
||||
#endif
|
||||
g_Vars.aioffset += 4;
|
||||
} else {
|
||||
u8 *cmd = g_Vars.ailist + g_Vars.aioffset;
|
||||
|
||||
@@ -16,4 +16,8 @@ void amgrStartThread(void);
|
||||
OSMesgQueue *amgrGetFrameMesgQueue(void);
|
||||
void amgrStopThread(void);
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
void amgrFrame(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+13
-1
@@ -3436,17 +3436,29 @@ struct surfacetype {
|
||||
union soundnumhack {
|
||||
s16 packed;
|
||||
|
||||
#ifdef PLATFORM_BIG_ENDIAN
|
||||
struct {
|
||||
u16 hasconfig : 1;
|
||||
u16 confignum : 15;
|
||||
};
|
||||
|
||||
struct {
|
||||
u16 hasconfig2 : 1;
|
||||
u16 unk02 : 2;
|
||||
u16 mp3priority : 2;
|
||||
u16 id : 11;
|
||||
};
|
||||
#else
|
||||
struct {
|
||||
u16 confignum : 15;
|
||||
u16 hasconfig : 1;
|
||||
};
|
||||
struct {
|
||||
u16 id : 11;
|
||||
u16 mp3priority : 2;
|
||||
u16 unk02 : 2;
|
||||
u16 hasconfig2 : 1;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
struct audiorussmapping {
|
||||
|
||||
@@ -254,7 +254,11 @@ void amgrHandleFrameMsg(AudioInfo *info, AudioInfo *previnfo)
|
||||
|
||||
admaBeginFrame();
|
||||
|
||||
#ifdef PLATFORM_N64
|
||||
somevalue = IO_READ(OS_PHYSICAL_TO_K1(AI_LEN_REG)) / 4;
|
||||
#else
|
||||
somevalue = osAiGetLength() / 4;
|
||||
#endif
|
||||
datastart = g_AudioManager.ACMDList[var8005cf90];
|
||||
outbuffer = (s16 *) osVirtualToPhysical(info->data);
|
||||
|
||||
@@ -307,3 +311,35 @@ void amgrHandleDoneMsg(AudioInfo *info)
|
||||
firsttime = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
void amgrFrame(void)
|
||||
{
|
||||
static AudioInfo *prevInfo = NULL;
|
||||
static s32 count = 0;
|
||||
|
||||
var80091588 = osGetTime();
|
||||
|
||||
AudioInfo *next = g_AudioManager.audioInfo[g_AdmaCurFrame % 3];
|
||||
amgrHandleFrameMsg(next, prevInfo);
|
||||
admaReceiveAll();
|
||||
|
||||
prevInfo = next;
|
||||
|
||||
count++;
|
||||
|
||||
var80091590 = osGetTime();
|
||||
var80091570 = var80091590 - var80091588;
|
||||
|
||||
if (count % 240 == 0) {
|
||||
var80091578 = var80091580 / 240;
|
||||
var80091580 = 0; var80091568 = 0;
|
||||
} else {
|
||||
var80091580 = (var80091580 + var80091590) - var80091588;
|
||||
}
|
||||
|
||||
if (var80091568 < var80091590 - var80091588) {
|
||||
var80091568 = var80091590 - var80091588;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -9,6 +9,8 @@
|
||||
* These two ABI commands are used in this file, but the format of the data
|
||||
* doesn't match the format used by n_audio's ABI.
|
||||
*/
|
||||
#ifdef PLATFORM_N64
|
||||
|
||||
#define acmd07(pkt, a, b) \
|
||||
{ \
|
||||
Acmd *_a = (Acmd *)pkt; \
|
||||
@@ -23,6 +25,15 @@
|
||||
_a->words.w1 = a; \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "mixer.h"
|
||||
|
||||
#define acmd07(pkt, a, b) aPlayMP3(pkt, a, b)
|
||||
#define acmd08(pkt, a) do { } while(0)
|
||||
|
||||
#endif
|
||||
|
||||
struct mp3vars g_Mp3Vars;
|
||||
struct asistream *g_AsiStream;
|
||||
|
||||
|
||||
+474
-3
@@ -1,28 +1,499 @@
|
||||
#include <ultra64.h>
|
||||
#include "internal.h"
|
||||
#include "mp3.h"
|
||||
#include "data.h"
|
||||
#include "platform.h"
|
||||
|
||||
extern struct mp3decfourbytes *var8009c650[];
|
||||
|
||||
s32 mp3util000461c0(u8 *buffer, s32 *a2, s32 a3, struct mp3decfourbytes *v8, s32 t0)
|
||||
{
|
||||
s32 v4 = t0;
|
||||
s32 v5 = *buffer;
|
||||
s32 v6 = (a3 << 8) + (u8)(((v5 << 8) | (u32)buffer[1]) >> (8 - (v4 & 7)));
|
||||
if (*(u8 *)(var8005f6fc + v6)) {
|
||||
return *(u8 *)(var8005f6f8 + v6) & 0xF;
|
||||
}
|
||||
u32 v9 = 0x80u >> (v4 & 7);
|
||||
|
||||
do {
|
||||
s32 v10;
|
||||
if ((v5 & v9) != 0) {
|
||||
v10 = v8->bytes[1];
|
||||
} else {
|
||||
v10 = v8->bytes[0];
|
||||
}
|
||||
v9 >>= 1;
|
||||
v8 += v10;
|
||||
if (!v9) {
|
||||
v9 = 128;
|
||||
v5 = *++buffer;
|
||||
}
|
||||
++v4;
|
||||
} while (v8->unk02 == -1);
|
||||
|
||||
return v8->unk02;
|
||||
}
|
||||
|
||||
s32 mp3util00046290(u32 *ptr, u8 s1, u8 t0)
|
||||
{
|
||||
return *ptr << (t0 & 7) >> (32 - s1);
|
||||
}
|
||||
|
||||
s32 mp3utilGetBits(u8 *buffer, s32 *count, s32 numbits)
|
||||
{
|
||||
return 0;
|
||||
const s32 result = PD_BE32(*(u32 *)(buffer + (*count >> 3))) << (*count & 7) >> (32 - numbits);
|
||||
*count += numbits;
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 mp3util000462f8(u8 *arg0, s32 *arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s16 **arg6, u8 **arg7)
|
||||
{
|
||||
return 0;
|
||||
s8 cVar1;
|
||||
u32 uVar2;
|
||||
u32 uVar3;
|
||||
s32 *piVar4;
|
||||
u32 uVar5;
|
||||
s16 *puVar6;
|
||||
u8 *puVar7;
|
||||
s32 iVar8;
|
||||
|
||||
struct mp3decfourbytes *s0 = var8009c650[arg2];
|
||||
|
||||
uVar5 = *arg1;
|
||||
puVar6 = (s16 *)*arg6;
|
||||
puVar7 = (u8 *)*arg7;
|
||||
piVar4 = (s32 *)(arg0 + (uVar5 >> 3));
|
||||
iVar8 = -arg3;
|
||||
|
||||
while (iVar8 = arg5 + iVar8, iVar8 > 0) {
|
||||
uVar2 = mp3util000461c0((u8 *)piVar4, arg1, arg2, s0, uVar5);
|
||||
if ((arg4 != 0) && (uVar2 == 0xf)) {
|
||||
uVar2 = mp3util00046290(piVar4, arg4, uVar5);
|
||||
uVar2 = uVar2 + 0xf;
|
||||
}
|
||||
if (uVar2 == 0) {
|
||||
*puVar7 = 0;
|
||||
} else {
|
||||
cVar1 = *(s8 *)piVar4;
|
||||
uVar3 = uVar5 & 7;
|
||||
piVar4 = (s32 *)((u8 *)piVar4 + (uVar3 + 1 >> 3));
|
||||
uVar5 = uVar5 + 1;
|
||||
if (((u32)cVar1 >> (7 - uVar3 & 0x1f) & 1) == 0) {
|
||||
*puVar7 = 0;
|
||||
} else {
|
||||
*puVar7 = 1;
|
||||
}
|
||||
}
|
||||
if ((arg4 != 0) && (iVar8 == 0xf)) {
|
||||
uVar3 = mp3util00046290(piVar4, arg4, uVar5);
|
||||
iVar8 = uVar3 + 0xf;
|
||||
}
|
||||
*puVar6 = (s16)uVar2;
|
||||
puVar6[1] = (s16)iVar8;
|
||||
puVar6 = puVar6 + 2;
|
||||
if (iVar8 == 0) {
|
||||
puVar7[1] = 0;
|
||||
} else {
|
||||
cVar1 = *(s8 *)piVar4;
|
||||
uVar2 = uVar5 & 7;
|
||||
piVar4 = (s32 *)((u8 *)piVar4 + (uVar2 + 1 >> 3));
|
||||
uVar5 = uVar5 + 1;
|
||||
if (((u32)cVar1 >> (7 - uVar2 & 0x1f) & 1) == 0) {
|
||||
puVar7[1] = 0;
|
||||
} else {
|
||||
puVar7[1] = 1;
|
||||
}
|
||||
}
|
||||
arg3 = arg3 + 2;
|
||||
puVar7 = puVar7 + 2;
|
||||
iVar8 = -arg3;
|
||||
}
|
||||
|
||||
*arg1 = uVar5;
|
||||
*arg6 = puVar6;
|
||||
*arg7 = puVar7;
|
||||
|
||||
return arg3;
|
||||
}
|
||||
|
||||
s32 mp3util000464a8(u8 *arg0, s32 *arg1, s32 arg2, s32 arg3, s32 arg4, s16 **arg5, u8 **arg6)
|
||||
{
|
||||
return 0;
|
||||
u32 uVar1;
|
||||
u32 uVar2;
|
||||
s32 *piVar3;
|
||||
s32 iVar4;
|
||||
u32 uVar5;
|
||||
u32 uVar6;
|
||||
u32 uVar7;
|
||||
u32 uVar8;
|
||||
u32 uVar9;
|
||||
s16 *puVar10;
|
||||
u8 *puVar11;
|
||||
|
||||
struct mp3decfourbytes *s0 = var8009c650[arg2];
|
||||
|
||||
uVar5 = *arg1;
|
||||
puVar10 = *arg5;
|
||||
puVar11 = *arg6;
|
||||
piVar3 = (s32 *)(arg0 + (uVar5 >> 3));
|
||||
|
||||
if (((s32)(arg4 - uVar5) > 0) && (iVar4 = arg3, arg3 + -0x240 < 0)) {
|
||||
do {
|
||||
uVar1 = mp3util000461c0((u8 *)piVar3, arg1, arg2, s0, uVar5);
|
||||
uVar6 = uVar1 >> 3 & 1;
|
||||
uVar7 = uVar1 >> 2 & 1;
|
||||
uVar8 = uVar1 >> 1 & 1;
|
||||
uVar1 = uVar1 & 1;
|
||||
*puVar10 = (s16)uVar6;
|
||||
puVar10[1] = (s16)uVar7;
|
||||
puVar10[2] = (s16)uVar8;
|
||||
puVar10[3] = (s16)uVar1;
|
||||
uVar2 = mp3util00046290(piVar3, 4, uVar5);
|
||||
uVar9 = 3;
|
||||
*puVar11 = (u8)uVar2;
|
||||
if (uVar6 != 0) {
|
||||
uVar6 = uVar6 & uVar2 >> 3;
|
||||
uVar9 = 2;
|
||||
}
|
||||
*puVar11 = (u8)uVar6;
|
||||
if (uVar7 != 0) {
|
||||
uVar7 = uVar7 & uVar2 >> uVar9;
|
||||
uVar9 = uVar9 - 1;
|
||||
}
|
||||
puVar11[1] = (u8)uVar7;
|
||||
if (uVar8 != 0) {
|
||||
uVar8 = uVar8 & uVar2 >> (uVar9 & 0x1f);
|
||||
uVar9 = uVar9 - 1;
|
||||
}
|
||||
puVar11[2] = (u8)uVar8;
|
||||
if (uVar1 != 0) {
|
||||
uVar1 = uVar1 & uVar2 >> (uVar9 & 0x1f);
|
||||
uVar9 = uVar9 - 1;
|
||||
}
|
||||
puVar11[3] = (u8)uVar1;
|
||||
uVar1 = uVar5 & 7;
|
||||
uVar5 = uVar5 - (uVar9 + 1);
|
||||
if ((s32)(uVar1 - (uVar9 + 1)) < 0) {
|
||||
piVar3 = (s32 *)((u8 *)piVar3 - 1);
|
||||
}
|
||||
puVar10 = puVar10 + 4;
|
||||
puVar11 = puVar11 + 4;
|
||||
arg3 = iVar4 + 4;
|
||||
} while ((iVar4 + -0x23c < 0) && (iVar4 = arg3, (s32)(arg4 - uVar5) > 0));
|
||||
}
|
||||
|
||||
*arg1 = uVar5;
|
||||
*arg5 = puVar10;
|
||||
*arg6 = puVar11;
|
||||
|
||||
return arg4;
|
||||
}
|
||||
|
||||
void func00046650(struct asistream_4f64 *arg0, s32 arg1, struct asistream_4f64 *arg2, struct asistream_4f64 *arg3, void *arg4)
|
||||
{
|
||||
f32 fVar1;
|
||||
f32 fVar2;
|
||||
f32 fVar3;
|
||||
f32 fVar4;
|
||||
f32 fVar5;
|
||||
f32 fVar6;
|
||||
f32 fVar7;
|
||||
f32 fVar8;
|
||||
f32 fVar9;
|
||||
f32 fVar10;
|
||||
f32 fVar11;
|
||||
f32 fVar12;
|
||||
f32 fVar13;
|
||||
f32 fVar14;
|
||||
f32 fVar15;
|
||||
f32 fVar16;
|
||||
f32 fVar17;
|
||||
f32 fVar18;
|
||||
f32 fVar19;
|
||||
f32 fVar20;
|
||||
f32 fVar21;
|
||||
f32 fVar22;
|
||||
f32 fVar23;
|
||||
f32 fVar24;
|
||||
f32 fVar25;
|
||||
f32 fVar26;
|
||||
f32 fVar27;
|
||||
|
||||
// TODO: can't be arsed to figure out proper types for now
|
||||
|
||||
f32 *param1 = (f32 *)arg0;
|
||||
f32 *param3 = (f32 *)arg2;
|
||||
f32 *param4 = (f32 *)arg3;
|
||||
f32 *param5 = (f32 *)arg4;
|
||||
|
||||
fVar17 = param1[0x10];
|
||||
param1[0x10] = param1[0xf] + fVar17;
|
||||
param1[0x11] = fVar17 + param1[0x11];
|
||||
fVar17 = param1[0xe];
|
||||
param1[0xe] = param1[0xd] + fVar17;
|
||||
param1[0xf] = fVar17 + param1[0xf];
|
||||
fVar17 = param1[0xc];
|
||||
param1[0xc] = param1[0xb] + fVar17;
|
||||
param1[0xd] = fVar17 + param1[0xd];
|
||||
fVar17 = param1[10];
|
||||
param1[10] = param1[9] + fVar17;
|
||||
param1[0xb] = fVar17 + param1[0xb];
|
||||
fVar17 = param1[8];
|
||||
param1[8] = param1[7] + fVar17;
|
||||
param1[9] = fVar17 + param1[9];
|
||||
fVar17 = param1[6];
|
||||
param1[6] = param1[5] + fVar17;
|
||||
param1[7] = fVar17 + param1[7];
|
||||
fVar17 = param1[4];
|
||||
param1[4] = param1[3] + fVar17;
|
||||
param1[5] = fVar17 + param1[5];
|
||||
fVar17 = param1[2];
|
||||
param1[2] = param1[1] + fVar17;
|
||||
param1[3] = fVar17 + param1[3];
|
||||
param1[1] = *param1 + param1[1];
|
||||
fVar17 = param1[0xf];
|
||||
param1[0xf] = param1[0xd] + fVar17;
|
||||
param1[0x11] = fVar17 + param1[0x11];
|
||||
fVar17 = param1[0xb];
|
||||
param1[0xb] = param1[9] + fVar17;
|
||||
param1[0xd] = fVar17 + param1[0xd];
|
||||
fVar17 = param1[7];
|
||||
param1[7] = param1[5] + fVar17;
|
||||
param1[9] = fVar17 + param1[9];
|
||||
fVar17 = param1[3];
|
||||
param1[3] = param1[1] + fVar17;
|
||||
param1[5] = fVar17 + param1[5];
|
||||
fVar1 = *param1 + *param1;
|
||||
fVar17 = fVar1 + param1[0xc];
|
||||
fVar6 = param1[4] * 1.879385 + param1[8] * 1.532089 + param1[0x10] * 0.3472964 + fVar17;
|
||||
fVar7 = param1[4] * -0.3472964 + param1[8] * -1.879385 + param1[0x10] * 1.532089 + fVar17;
|
||||
fVar17 = param1[4] * -1.532089 + param1[8] * 0.3472964 + param1[0x10] * -1.879385 + fVar17;
|
||||
fVar18 = param1[0xc];
|
||||
fVar2 = ((((fVar1 + param1[4]) - param1[8]) - fVar18) - fVar18) - param1[0x10];
|
||||
fVar3 = (((*param1 - param1[4]) + param1[8]) - fVar18) + param1[0x10];
|
||||
fVar8 = param1[2] * 1.969615 + param1[10] * 1.285575 + param1[0xe] * 0.6840403 +
|
||||
param1[6] * 1.732051;
|
||||
fVar1 = -(param1[6] * 1.732051);
|
||||
fVar9 = param1[2] * 1.285575 + param1[10] * -0.6840403 + param1[0xe] * 1.969615 + fVar1;
|
||||
fVar1 = param1[2] * 0.6840403 + param1[10] * 1.969615 + param1[0xe] * -1.285575 + fVar1;
|
||||
fVar10 = ((param1[2] - param1[10]) - param1[0xe]) * 1.732051;
|
||||
fVar4 = param1[1] + param1[1];
|
||||
fVar18 = fVar4 + param1[0xd];
|
||||
fVar11 = param1[5] * 1.879385 + param1[9] * 1.532089 + param1[0x11] * 0.3472964 + fVar18;
|
||||
fVar12 = param1[5] * -0.3472964 + param1[9] * -1.879385 + param1[0x11] * 1.532089 + fVar18;
|
||||
fVar18 = param1[5] * -1.532089 + param1[9] * 0.3472964 + param1[0x11] * -1.879385 + fVar18;
|
||||
fVar19 = param1[0xd];
|
||||
fVar5 = ((((fVar4 + param1[5]) - param1[9]) - fVar19) - fVar19) - param1[0x11];
|
||||
fVar13 = param1[3] * 1.969615 + param1[0xb] * 1.285575 + param1[0xf] * 0.6840403 +
|
||||
param1[7] * 1.732051;
|
||||
fVar4 = -(param1[7] * 1.732051);
|
||||
fVar14 = param1[3] * 1.285575 + param1[0xb] * -0.6840403 + param1[0xf] * 1.969615 + fVar4;
|
||||
fVar4 = param1[3] * 0.6840403 + param1[0xb] * 1.969615 + param1[0xf] * -1.285575 + fVar4;
|
||||
fVar15 = ((param1[3] - param1[0xb]) - param1[0xf]) * 1.732051;
|
||||
fVar16 = fVar6 + fVar8;
|
||||
fVar20 = (fVar11 + fVar13) * 0.5019099;
|
||||
fVar24 = (fVar16 + fVar20) * -0.2502382;
|
||||
fVar16 = (fVar16 - fVar20) * -5.731396;
|
||||
fVar20 = fVar2 + fVar10;
|
||||
fVar21 = (fVar5 + fVar15) * 0.5176381;
|
||||
fVar25 = (fVar20 + fVar21) * -0.2521572;
|
||||
fVar20 = (fVar20 - fVar21) * -1.915324;
|
||||
fVar21 = fVar7 + fVar9;
|
||||
fVar22 = (fVar12 + fVar14) * 0.551689;
|
||||
fVar26 = (fVar21 + fVar22) * -0.2560699;
|
||||
fVar21 = (fVar21 - fVar22) * -1.155057;
|
||||
fVar22 = fVar17 + fVar1;
|
||||
fVar23 = (fVar18 + fVar4) * 0.6103873;
|
||||
fVar27 = (fVar22 + fVar23) * -0.2621323;
|
||||
fVar22 = (fVar22 - fVar23) * -0.8313774;
|
||||
fVar17 = fVar17 - fVar1;
|
||||
fVar1 = (fVar18 - fVar4) * 0.8717234;
|
||||
fVar23 = (fVar17 + fVar1) * -0.2818455;
|
||||
fVar17 = (fVar17 - fVar1) * -0.5414202;
|
||||
fVar7 = fVar7 - fVar9;
|
||||
fVar1 = (fVar12 - fVar14) * 1.183101;
|
||||
fVar9 = (fVar7 + fVar1) * -0.2964223;
|
||||
fVar1 = (fVar7 - fVar1) * -0.4652897;
|
||||
fVar2 = fVar2 - fVar10;
|
||||
fVar18 = (fVar5 - fVar15) * 1.931852;
|
||||
fVar10 = (fVar2 + fVar18) * -0.3151181;
|
||||
fVar18 = (fVar2 - fVar18) * -0.4106699;
|
||||
fVar6 = fVar6 - fVar8;
|
||||
fVar4 = (fVar11 - fVar13) * 5.736856;
|
||||
fVar8 = (fVar6 + fVar4) * -0.3390854;
|
||||
fVar4 = (fVar6 - fVar4) * -0.3700468;
|
||||
fVar2 = ((((param1[1] - param1[5]) + param1[9]) - fVar19) + param1[0x11]) * 0.7071068;
|
||||
fVar5 = (fVar3 + fVar2) * -0.5411961;
|
||||
fVar2 = (fVar3 - fVar2) * -1.306563;
|
||||
if ((arg1 & 1) == 0) {
|
||||
*param3 = -fVar4 * *param5 + *param4;
|
||||
param3[1] = -fVar18 * param5[1] + param4[1];
|
||||
param3[2] = -fVar1 * param5[2] + param4[2];
|
||||
param3[3] = -fVar17 * param5[3] + param4[3];
|
||||
param3[4] = -fVar2 * param5[4] + param4[4];
|
||||
param3[5] = -fVar22 * param5[5] + param4[5];
|
||||
param3[6] = -fVar21 * param5[6] + param4[6];
|
||||
param3[7] = -fVar20 * param5[7] + param4[7];
|
||||
param3[8] = -fVar16 * param5[8] + param4[8];
|
||||
param3[9] = fVar16 * param5[9] + param4[9];
|
||||
param3[10] = fVar20 * param5[10] + param4[10];
|
||||
param3[0xb] = fVar21 * param5[0xb] + param4[0xb];
|
||||
param3[0xc] = fVar22 * param5[0xc] + param4[0xc];
|
||||
param3[0xd] = fVar2 * param5[0xd] + param4[0xd];
|
||||
param3[0xe] = fVar17 * param5[0xe] + param4[0xe];
|
||||
param3[0xf] = fVar1 * param5[0xf] + param4[0xf];
|
||||
param3[0x10] = fVar18 * param5[0x10] + param4[0x10];
|
||||
param3[0x11] = fVar4 * param5[0x11] + param4[0x11];
|
||||
} else {
|
||||
*param3 = -fVar4 * *param5 + *param4;
|
||||
param3[1] = fVar18 * param5[1] - param4[1];
|
||||
param3[2] = -fVar1 * param5[2] + param4[2];
|
||||
param3[3] = fVar17 * param5[3] - param4[3];
|
||||
param3[4] = -fVar2 * param5[4] + param4[4];
|
||||
param3[5] = fVar22 * param5[5] - param4[5];
|
||||
param3[6] = -fVar21 * param5[6] + param4[6];
|
||||
param3[7] = fVar20 * param5[7] - param4[7];
|
||||
param3[8] = -fVar16 * param5[8] + param4[8];
|
||||
param3[9] = -fVar16 * param5[9] - param4[9];
|
||||
param3[10] = fVar20 * param5[10] + param4[10];
|
||||
param3[0xb] = -fVar21 * param5[0xb] - param4[0xb];
|
||||
param3[0xc] = fVar22 * param5[0xc] + param4[0xc];
|
||||
param3[0xd] = -fVar2 * param5[0xd] - param4[0xd];
|
||||
param3[0xe] = fVar17 * param5[0xe] + param4[0xe];
|
||||
param3[0xf] = -fVar1 * param5[0xf] - param4[0xf];
|
||||
param3[0x10] = fVar18 * param5[0x10] + param4[0x10];
|
||||
param3[0x11] = -fVar4 * param5[0x11] - param4[0x11];
|
||||
}
|
||||
fVar17 = param5[0x13];
|
||||
*param4 = fVar8 * param5[0x12];
|
||||
param4[1] = fVar10 * fVar17;
|
||||
fVar17 = param5[0x15];
|
||||
param4[2] = fVar9 * param5[0x14];
|
||||
param4[3] = fVar23 * fVar17;
|
||||
fVar17 = param5[0x17];
|
||||
param4[4] = fVar5 * param5[0x16];
|
||||
param4[5] = fVar27 * fVar17;
|
||||
fVar17 = param5[0x19];
|
||||
param4[6] = fVar26 * param5[0x18];
|
||||
param4[7] = fVar25 * fVar17;
|
||||
fVar17 = param5[0x1b];
|
||||
param4[8] = fVar24 * param5[0x1a];
|
||||
param4[9] = fVar24 * fVar17;
|
||||
fVar17 = param5[0x1d];
|
||||
param4[10] = fVar25 * param5[0x1c];
|
||||
param4[0xb] = fVar26 * fVar17;
|
||||
fVar17 = param5[0x1f];
|
||||
param4[0xc] = fVar27 * param5[0x1e];
|
||||
param4[0xd] = fVar5 * fVar17;
|
||||
fVar17 = param5[0x21];
|
||||
param4[0xe] = fVar23 * param5[0x20];
|
||||
param4[0xf] = fVar9 * fVar17;
|
||||
fVar17 = param5[0x23];
|
||||
param4[0x10] = fVar10 * param5[0x22];
|
||||
param4[0x11] = fVar8 * fVar17;
|
||||
}
|
||||
|
||||
void func00047550(struct asistream_4f64 *arg0, s32 arg1, struct asistream_4f64 *arg2, struct asistream_4f64 *arg3)
|
||||
{
|
||||
f32 *pfVar1;
|
||||
f32 *pfVar2;
|
||||
s32 iVar3;
|
||||
f32 fVar4;
|
||||
f32 fVar5;
|
||||
f32 fVar6;
|
||||
f32 fVar7;
|
||||
f32 fVar8;
|
||||
f32 fVar9;
|
||||
f32 fVar10;
|
||||
f32 fVar11;
|
||||
f32 fVar12;
|
||||
f32 locald0[52];
|
||||
|
||||
// TODO: can't be arsed to figure out proper types
|
||||
f32 *param1 = (f32 *)arg0;
|
||||
f32 *param3 = (f32 *)arg2;
|
||||
f32 *param4 = (f32 *)arg3;
|
||||
|
||||
pfVar1 = locald0;
|
||||
for (s32 i = 0; i < ARRAYCOUNT(locald0); i += 4) {
|
||||
pfVar1[0] = 0.0;
|
||||
pfVar1[1] = 0.0;
|
||||
pfVar1[2] = 0.0;
|
||||
pfVar1[3] = 0.0;
|
||||
pfVar1 = pfVar1 + 4;
|
||||
}
|
||||
pfVar2 = locald0 + 0x10;
|
||||
iVar3 = 3;
|
||||
pfVar1 = pfVar2;
|
||||
do {
|
||||
param1[5] = param1[5] + param1[4];
|
||||
param1[4] = param1[4] + param1[3];
|
||||
param1[3] = param1[3] + param1[2];
|
||||
param1[2] = param1[2] + param1[1];
|
||||
param1[1] = param1[1] + *param1;
|
||||
param1[5] = param1[5] + param1[3];
|
||||
param1[3] = param1[3] + param1[1];
|
||||
fVar11 = *param1 + param1[4] * 0.5;
|
||||
fVar4 = *param1 - param1[4];
|
||||
fVar5 = fVar11 + param1[2] * 0.8660254;
|
||||
fVar11 = fVar11 - param1[2] * 0.8660254;
|
||||
fVar12 = param1[1] + param1[5] * 0.5;
|
||||
fVar6 = (fVar12 - param1[3] * 0.8660254) * 1.931852;
|
||||
fVar9 = (param1[1] - param1[5]) * 0.7071068;
|
||||
fVar12 = (fVar12 + param1[3] * 0.8660254) * 0.5176381;
|
||||
fVar7 = (fVar5 + fVar12) * 0.5043145;
|
||||
fVar10 = (fVar4 + fVar9) * 0.5411961;
|
||||
fVar8 = (fVar11 + fVar6) * 0.6302362;
|
||||
fVar4 = (fVar4 - fVar9) * 1.306563;
|
||||
fVar12 = (fVar5 - fVar12) * 3.830649;
|
||||
fVar5 = (fVar11 - fVar6) * 0.8213398 * 1.0;
|
||||
pfVar1[6] = pfVar1[6] + fVar5 * 0.1305262;
|
||||
pfVar1[7] = pfVar1[7] + fVar4 * 0.3826834;
|
||||
pfVar1[8] = pfVar1[8] + fVar12 * 0.6087614;
|
||||
pfVar1[9] = pfVar1[9] + fVar12 * -0.7933533;
|
||||
pfVar1[10] = pfVar1[10] + fVar4 * -0.9238795;
|
||||
pfVar1[0xb] = pfVar1[0xb] + fVar5 * -0.9914449;
|
||||
pfVar1[0xc] = pfVar1[0xc] + fVar8 * -0.9914449;
|
||||
pfVar1[0xd] = pfVar1[0xd] + fVar10 * -0.9238795;
|
||||
pfVar1[0xe] = pfVar1[0xe] + fVar7 * -0.7933533;
|
||||
pfVar1[0xf] = pfVar1[0xf] + fVar7 * -0.6087614;
|
||||
pfVar1[0x10] = pfVar1[0x10] + fVar10 * -0.3826834;
|
||||
pfVar1[0x11] = pfVar1[0x11] + fVar8 * -0.1305262;
|
||||
param1 = param1 + 6;
|
||||
pfVar1 = pfVar1 + 6;
|
||||
iVar3 = iVar3 + -1;
|
||||
} while (iVar3 != 0);
|
||||
if ((arg1 & 1) == 0) {
|
||||
iVar3 = 0x12;
|
||||
pfVar1 = param4;
|
||||
do {
|
||||
*param3 = *pfVar2 + *pfVar1;
|
||||
param3 = param3 + 1;
|
||||
pfVar1 = pfVar1 + 1;
|
||||
pfVar2 = pfVar2 + 1;
|
||||
iVar3 = iVar3 + -1;
|
||||
} while (iVar3 != 0);
|
||||
} else {
|
||||
iVar3 = 9;
|
||||
pfVar1 = param4;
|
||||
do {
|
||||
fVar4 = pfVar2[1];
|
||||
fVar5 = pfVar1[1];
|
||||
*param3 = *pfVar2 + *pfVar1;
|
||||
param3[1] = -fVar4 - fVar5;
|
||||
param3 = param3 + 2;
|
||||
pfVar1 = pfVar1 + 2;
|
||||
pfVar2 = pfVar2 + 2;
|
||||
iVar3 = iVar3 + -1;
|
||||
} while (iVar3 != 0);
|
||||
}
|
||||
pfVar1 = locald0 + 0x22;
|
||||
iVar3 = 0x12;
|
||||
do {
|
||||
*param4 = *pfVar1;
|
||||
param4 = param4 + 1;
|
||||
pfVar1 = pfVar1 + 1;
|
||||
iVar3 = iVar3 + -1;
|
||||
} while (iVar3 != 0);
|
||||
}
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
|
||||
|
||||
#ifdef PLATFORM_N64
|
||||
|
||||
/*
|
||||
* Macros to assemble the audio command list
|
||||
@@ -122,6 +123,23 @@
|
||||
_a->words.w1 = (unsigned int) d; \
|
||||
}
|
||||
|
||||
#else // PLATFORM_N64
|
||||
|
||||
#include <mixer.h>
|
||||
|
||||
#define n_aNoop(pkt, outp, b, c) aDisable(pkt, outp, b, c);
|
||||
#define n_aADPCMdec(pkt, s, f, c, a, d) aADPCMdec(pkt, s, f, c, a, d);
|
||||
#define n_aPoleFilter(pkt, f, g, t, s) aPoleFilter(pkt, f, g, t, s);
|
||||
#define n_aEnvMixer(pkt, f, t, s) aEnvMixer(pkt, f, t, s);
|
||||
#define n_aInterleave(pkt) aInterleave(pkt);
|
||||
#define n_aLoadBuffer(pkt, c, d, s) aLoadBuffer(pkt, c, d, s);
|
||||
#define n_aResample(pkt, s, f, p, i, o) aResample(pkt, s, f, p, i, o);
|
||||
#define n_aSaveBuffer(pkt, c, s, d) aSaveBuffer(pkt, c, s, d);
|
||||
#define n_aSetVolume(pkt, f, v, t, r) aSetVolume(pkt, f, v, t, r);
|
||||
#define n_aLoadADPCM(pkt, c, d) aLoadADPCM(pkt, c, d);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _LANGUAGE_C */
|
||||
|
||||
#endif /* __N_ABI__ */
|
||||
|
||||
@@ -143,7 +143,7 @@ Acmd *n_alAudioFrame(Acmd *cmdList, s32 *cmdLen, s16 *outBuf, s32 outLen)
|
||||
nOut = MIN(n_syn->maxOutSamples, outLen);
|
||||
|
||||
cmdPtr = cmdlEnd;
|
||||
n_syn->sv_dramout = (intptr_t) lOutBuf;
|
||||
n_syn->sv_dramout = (uintptr_t) lOutBuf;
|
||||
|
||||
cmdlEnd = n_alSavePull(n_syn->curSamples, cmdPtr);
|
||||
|
||||
|
||||
@@ -1445,7 +1445,11 @@ void sndInit(void)
|
||||
|
||||
g_SndMp3Enabled = false;
|
||||
} else {
|
||||
#ifdef PLATFORM_N64
|
||||
g_SndMp3Enabled = true;
|
||||
#else
|
||||
g_SndMp3Enabled = false; // TODO
|
||||
#endif
|
||||
g_SndMaxFxBusses = 2;
|
||||
|
||||
if (argFindByPrefix(1, "-nomp3")) {
|
||||
|
||||
Reference in new issue
Block a user