diff --git a/Core/HLE/sceAudio.cpp b/Core/HLE/sceAudio.cpp index 5cfa240ed2..99eed5884d 100644 --- a/Core/HLE/sceAudio.cpp +++ b/Core/HLE/sceAudio.cpp @@ -56,7 +56,7 @@ void AudioChannel::clear() // There's a second Audio api called Audio2 that only has one channel, I guess the 8 channel api was overkill. // We simply map it to an extra channel after the 8 channels, since they can be used concurrently. -// The extra channel is for SRC/Output2. +// The extra channel is for SRC/Output2/Vaudio. AudioChannel chans[PSP_AUDIO_CHANNEL_MAX + 1]; // Enqueues the buffer pointer on the channel. If channel buffer queue is full (2 items?) will block until it isn't. diff --git a/Core/HLE/sceAudio.h b/Core/HLE/sceAudio.h index 69821cf001..7f10d37767 100644 --- a/Core/HLE/sceAudio.h +++ b/Core/HLE/sceAudio.h @@ -46,6 +46,7 @@ const int PSP_AUDIO_CHANNEL_MAX = 8; const int PSP_AUDIO_CHANNEL_SRC = 8; const int PSP_AUDIO_CHANNEL_OUTPUT2 = 8; +const int PSP_AUDIO_CHANNEL_VAUDIO = 8; struct AudioChannelWaitInfo { @@ -83,7 +84,7 @@ struct AudioChannel void clear(); }; -// The extra channel is for SRC/Output2. +// The extra channel is for SRC/Output2/Vaudio (who all share, apparently.) extern AudioChannel chans[PSP_AUDIO_CHANNEL_MAX + 1]; void Register_sceAudio(); diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index b29f964133..477d4885f7 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -64,6 +64,7 @@ #include "sceImpose.h" #include "sceUsb.h" #include "scePspNpDrm_user.h" +#include "sceVaudio.h" #include "../Util/PPGeDraw.h" @@ -115,6 +116,7 @@ void __KernelInit() __UsbInit(); __FontInit(); __NetInit(); + __VaudioInit(); SaveState::Init(); // Must be after IO, as it may create a directory @@ -209,6 +211,7 @@ void __KernelDoState(PointerWrap &p) __UmdDoState(p); __UtilityDoState(p); __UsbDoState(p); + __VaudioDoState(p); __PPGeDoState(p); diff --git a/Core/HLE/sceVaudio.cpp b/Core/HLE/sceVaudio.cpp index 59cb5be303..6583eb7bc2 100644 --- a/Core/HLE/sceVaudio.cpp +++ b/Core/HLE/sceVaudio.cpp @@ -15,36 +15,64 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "HLE.h" -#include "FunctionWrappers.h" -#include "sceVaudio.h" -#include "sceAudio.h" -#include "__sceAudio.h" +#include "Common/ChunkFile.h" +#include "Core/HLE/HLE.h" +#include "Core/HLE/sceVaudio.h" +#include "Core/HLE/sceAudio.h" +#include "Core/HLE/__sceAudio.h" // Ultra hacky Vaudio implementation. Not sure what the point of this API is. +bool vaudioReserved = false; + +void __VaudioInit() { + vaudioReserved = false; +} + +void __VaudioDoState(PointerWrap &p) { + p.Do(vaudioReserved); + p.DoMarker("sceVaudio"); +} + u32 sceVaudioChReserve(int sampleCount, int freq, int format) { - WARN_LOG(HLE, "HACK sceVaudioChReserve(%i, %i, %i)", sampleCount, freq, format); - chans[0].reserved = true; - chans[0].sampleCount = sampleCount; - chans[0].format = format; + if (vaudioReserved) { + ERROR_LOG(HLE, "sceVaudioChReserve(%i, %i, %i) - already reserved", sampleCount, freq, format); + return SCE_KERNEL_ERROR_BUSY; + } + // We still have to check the channel also, which gives a different error. + if (chans[PSP_AUDIO_CHANNEL_VAUDIO].reserved) { + ERROR_LOG(HLE, "sceVaudioChReserve(%i, %i, %i) - channel already reserved", sampleCount, freq, format); + return SCE_ERROR_AUDIO_CHANNEL_ALREADY_RESERVED; + } + DEBUG_LOG(HLE, "sceVaudioChReserve(%i, %i, %i)", sampleCount, freq, format); + chans[PSP_AUDIO_CHANNEL_VAUDIO].reserved = true; + chans[PSP_AUDIO_CHANNEL_VAUDIO].sampleCount = sampleCount; + chans[PSP_AUDIO_CHANNEL_VAUDIO].format = format; + chans[PSP_AUDIO_CHANNEL_VAUDIO].leftVolume = 0; + chans[PSP_AUDIO_CHANNEL_VAUDIO].rightVolume = 0; + vaudioReserved = true; __AudioSetOutputFrequency(freq); return 0; } u32 sceVaudioChRelease() { - WARN_LOG(HLE, "HACK sceVaudioChRelease(...)"); - if (!chans[0].reserved) { + DEBUG_LOG(HLE, "sceVaudioChRelease(...)"); + if (!chans[PSP_AUDIO_CHANNEL_VAUDIO].reserved) { return SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED; } else { - chans[0].reserved = false; + chans[PSP_AUDIO_CHANNEL_VAUDIO].reserved = false; + vaudioReserved = false; return 0; } } u32 sceVaudioOutputBlocking(int vol, u32 buffer) { - WARN_LOG(HLE, "HACK sceVaudioOutputBlocking(%i, %08x)", vol, buffer); - return __AudioEnqueue(chans[0], 0, true); + DEBUG_LOG(HLE, "sceVaudioOutputBlocking(%i, %08x)", vol, buffer); + chans[PSP_AUDIO_CHANNEL_OUTPUT2].leftVolume = vol; + chans[PSP_AUDIO_CHANNEL_OUTPUT2].rightVolume = vol; + // TODO: This may be wrong, not sure if's in a different format? + chans[PSP_AUDIO_CHANNEL_OUTPUT2].sampleAddress = buffer; + return __AudioEnqueue(chans[PSP_AUDIO_CHANNEL_VAUDIO], 0, true); } u32 sceVaudioSetEffectType(int effectType, int vol) { @@ -58,9 +86,9 @@ u32 sceVaudioSetAlcMode(int alcMode) { } const HLEFunction sceVaudio[] = { - {0x03b6807d, WrapU_IU, "sceVaudioOutputBlockingFunction"}, - {0x67585dfd, WrapU_III, "sceVaudioChReserveFunction"}, - {0x8986295e, WrapU_V, "sceVaudioChReleaseFunction"}, + {0x8986295e, WrapU_IU, "sceVaudioOutputBlocking"}, + {0x03b6807d, WrapU_III, "sceVaudioChReserve"}, + {0x67585dfd, WrapU_V, "sceVaudioChRelease"}, {0x346FBE94, WrapU_II, "sceVaudioSetEffectType"}, {0xCBD4AC51, WrapU_I, "sceVaudioSetAlcMode"}, }; diff --git a/Core/HLE/sceVaudio.h b/Core/HLE/sceVaudio.h index ef5d7c951a..d0fce8685f 100644 --- a/Core/HLE/sceVaudio.h +++ b/Core/HLE/sceVaudio.h @@ -17,5 +17,10 @@ #pragma once +class PointerWrap; + void Register_sceVaudio(); +void __VaudioInit(); +void __VaudioDoState(PointerWrap &p); +