mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-03-04 12:17:16 +00:00
Merge pull request #4349 from xsacha/master
sceAudio: ARM optimisation.
This commit is contained in:
commit
8f7356d4f0
@ -63,17 +63,16 @@ bool __gainAudioQueueLock();
|
|||||||
void __releaseAcquiredLock();
|
void __releaseAcquiredLock();
|
||||||
void __blockForAudioQueueLock();
|
void __blockForAudioQueueLock();
|
||||||
|
|
||||||
|
|
||||||
static inline s16 clamp_s16(int i) {
|
|
||||||
if (i > 32767)
|
|
||||||
return 32767;
|
|
||||||
if (i < -32768)
|
|
||||||
return -32768;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline s16 adjustvolume(s16 sample, int vol) {
|
static inline s16 adjustvolume(s16 sample, int vol) {
|
||||||
return clamp_s16((sample * vol) >> 15);
|
#ifdef ARM
|
||||||
|
register int r;
|
||||||
|
asm volatile("smulwb %0, %1, %2\n\t" \
|
||||||
|
"ssat %0, #16, %0" \
|
||||||
|
: "=r"(r) : "r"(vol), "r"(sample));
|
||||||
|
return r;
|
||||||
|
#else
|
||||||
|
return clamp_s16((sample * vol) >> 16);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void hleAudioUpdate(u64 userdata, int cyclesLate) {
|
void hleAudioUpdate(u64 userdata, int cyclesLate) {
|
||||||
@ -205,6 +204,13 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int leftVol = chan.leftVolume;
|
||||||
|
int rightVol = chan.rightVolume;
|
||||||
|
// Possible optimisation: Check if volume is 1<<15 (seems common) in which case volume is ignored
|
||||||
|
// Remember that maximum volume allowed is 0xFFFFF so left shift is no issue
|
||||||
|
leftVol <<=1;
|
||||||
|
rightVol <<=1;
|
||||||
|
|
||||||
if (chan.format == PSP_AUDIO_FORMAT_STEREO) {
|
if (chan.format == PSP_AUDIO_FORMAT_STEREO) {
|
||||||
const u32 totalSamples = chan.sampleCount * 2;
|
const u32 totalSamples = chan.sampleCount * 2;
|
||||||
|
|
||||||
@ -222,10 +228,8 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) {
|
|||||||
s16 *buf1 = 0, *buf2 = 0;
|
s16 *buf1 = 0, *buf2 = 0;
|
||||||
size_t sz1, sz2;
|
size_t sz1, sz2;
|
||||||
chan.sampleQueue.pushPointers(totalSamples, &buf1, &sz1, &buf2, &sz2);
|
chan.sampleQueue.pushPointers(totalSamples, &buf1, &sz1, &buf2, &sz2);
|
||||||
int leftVol = chan.leftVolume;
|
|
||||||
int rightVol = chan.rightVolume;
|
|
||||||
|
|
||||||
// TODO: SSE/NEON implementations
|
// TODO: SSE/NEON (VQDMULH) implementations
|
||||||
for (u32 i = 0; i < sz1; i += 2) {
|
for (u32 i = 0; i < sz1; i += 2) {
|
||||||
buf1[i] = adjustvolume(sampleData[i], leftVol);
|
buf1[i] = adjustvolume(sampleData[i], leftVol);
|
||||||
buf1[i + 1] = adjustvolume(sampleData[i + 1], rightVol);
|
buf1[i + 1] = adjustvolume(sampleData[i + 1], rightVol);
|
||||||
@ -242,11 +246,11 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) {
|
|||||||
} else {
|
} else {
|
||||||
for (u32 i = 0; i < totalSamples; i++) {
|
for (u32 i = 0; i < totalSamples; i++) {
|
||||||
s16 sampleL = (s16)Memory::Read_U16(chan.sampleAddress + sizeof(s16) * i);
|
s16 sampleL = (s16)Memory::Read_U16(chan.sampleAddress + sizeof(s16) * i);
|
||||||
sampleL = adjustvolume(sampleL, chan.leftVolume);
|
sampleL = adjustvolume(sampleL, leftVol);
|
||||||
chan.sampleQueue.push(sampleL);
|
chan.sampleQueue.push(sampleL);
|
||||||
i++;
|
i++;
|
||||||
s16 sampleR = (s16)Memory::Read_U16(chan.sampleAddress + sizeof(s16) * i);
|
s16 sampleR = (s16)Memory::Read_U16(chan.sampleAddress + sizeof(s16) * i);
|
||||||
sampleR = adjustvolume(sampleR, chan.rightVolume);
|
sampleR = adjustvolume(sampleR, rightVol);
|
||||||
chan.sampleQueue.push(sampleR);
|
chan.sampleQueue.push(sampleR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,8 +259,8 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) {
|
|||||||
for (u32 i = 0; i < chan.sampleCount; i++) {
|
for (u32 i = 0; i < chan.sampleCount; i++) {
|
||||||
// Expand to stereo
|
// Expand to stereo
|
||||||
s16 sample = (s16)Memory::Read_U16(chan.sampleAddress + 2 * i);
|
s16 sample = (s16)Memory::Read_U16(chan.sampleAddress + 2 * i);
|
||||||
chan.sampleQueue.push(adjustvolume(sample, chan.leftVolume));
|
chan.sampleQueue.push(adjustvolume(sample, leftVol));
|
||||||
chan.sampleQueue.push(adjustvolume(sample, chan.rightVolume));
|
chan.sampleQueue.push(adjustvolume(sample, rightVol));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -330,14 +330,6 @@ void SasInstance::SetGrainSize(int newGrainSize) {
|
|||||||
resampleBuffer = new s16[grainSize * 4 + 3];
|
resampleBuffer = new s16[grainSize * 4 + 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline s16 clamp_s16(int i) {
|
|
||||||
if (i > 32767)
|
|
||||||
return 32767;
|
|
||||||
if (i < -32768)
|
|
||||||
return -32768;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SasVoice::ReadSamples(s16 *output, int numSamples) {
|
void SasVoice::ReadSamples(s16 *output, int numSamples) {
|
||||||
// Read N samples into the resample buffer. Could do either PCM or VAG here.
|
// Read N samples into the resample buffer. Could do either PCM or VAG here.
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
12
Globals.h
12
Globals.h
@ -48,6 +48,18 @@ inline u8 Convert6To8(u8 v)
|
|||||||
return (v << 2) | (v >> 4);
|
return (v << 2) | (v >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline s16 clamp_s16(int i) {
|
||||||
|
#ifdef ARM
|
||||||
|
asm("ssat %0, #16, %1" : "=r"(i) : "r"(i));
|
||||||
|
#else
|
||||||
|
if (i > 32767)
|
||||||
|
return 32767;
|
||||||
|
if (i < -32768)
|
||||||
|
return -32768;
|
||||||
|
#endif
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef DISALLOW_COPY_AND_ASSIGN
|
#ifndef DISALLOW_COPY_AND_ASSIGN
|
||||||
#define DISALLOW_COPY_AND_ASSIGN(t) \
|
#define DISALLOW_COPY_AND_ASSIGN(t) \
|
||||||
private: \
|
private: \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user