Support SFX

This commit is contained in:
jaby 2024-09-23 19:59:52 +02:00
parent acef4b8d68
commit f2800aaf1e
6 changed files with 44 additions and 24 deletions

View File

@ -59,10 +59,12 @@ namespace Assets {
} }
namespace Main { namespace Main {
using SPU::operator""_vol;
static const CDFile Files[] = { static const CDFile Files[] = {
CDFileBuilder::simple_tim(LBA::PACO, PacoTIM), CDFileBuilder::simple_tim(LBA::PACO, PacoTIM),
CDFileBuilder::simple_tim(LBA::DFISH, DoenerFishInfo.tim), CDFileBuilder::simple_tim(LBA::DFISH, DoenerFishInfo.tim),
CDFileBuilder::sony_vag(LBA::APPLE_SFX, VAG::create(0)), CDFileBuilder::sony_vag(LBA::APPLE_SFX, VAG::create(0, 1.0_vol)),
CustomCDFileBuilder::jingle(32), CustomCDFileBuilder::jingle(32),
}; };

View File

@ -2,6 +2,7 @@
#include "../Auxiliary/bits.hpp" #include "../Auxiliary/bits.hpp"
#include "../GPU/gpu_types.hpp" #include "../GPU/gpu_types.hpp"
#include "../jabyengine_defines.hpp" #include "../jabyengine_defines.hpp"
#include "../SPU/spu.hpp"
namespace JabyEngine { namespace JabyEngine {
#pragma pack(push, 1) #pragma pack(push, 1)
@ -68,10 +69,11 @@ namespace JabyEngine {
}; };
struct VAG { struct VAG {
uint8_t voice_number; uint8_t voice_number;
SPU::SimpleVolume inital_stereo_vol;
static constexpr VAG create(uint8_t voice_num) { static constexpr VAG create(uint8_t voice_num, SPU::SimpleVolume volume) {
return VAG{.voice_number = voice_num}; return VAG{.voice_number = voice_num, .inital_stereo_vol = volume};
} }
}; };

View File

@ -3,31 +3,41 @@
namespace JabyEngine { namespace JabyEngine {
namespace SPU { namespace SPU {
using SRAMAdr = SPU_IO::SRAMAdr; using SPU_IO::operator""_vol;
using SRAMAdr = SPU_IO::SRAMAdr;
using SimpleVolume = SPU_IO::SimpleVolume;
using SweepVolume = SPU_IO::SweepVolume;
// TODO: Rename to sample...? // TODO: Rename to sample...?
struct Voice { struct Voice {
size_t get_id() const { size_t get_id() {
return reinterpret_cast<size_t>(this); return reinterpret_cast<size_t>(this);
} }
SRAMAdr allocate(size_t size) const; SRAMAdr allocate(size_t size);
SRAMAdr allocate(SPU_IO::SampleRate frequency, size_t size) const; SRAMAdr allocate(SPU_IO::SampleRate frequency, size_t size);
void deallocate() const; void deallocate();
void set_sample_rate(SPU_IO::SampleRate frequency) const { void set_sample_rate(SPU_IO::SampleRate frequency) {
SPU_IO::Voice[Voice::get_id()].sampleRate.write(frequency); SPU_IO::Voice[Voice::get_id()].sampleRate.write(frequency);
} }
void play() const { void set_volume(SimpleVolume left, SimpleVolume right) {
// TODO: Verify that assembly code is super simple
SPU_IO::Voice[Voice::get_id()].volumeLeft.write(SweepVolume::create(left));
SPU_IO::Voice[Voice::get_id()].volumeRight.write(SweepVolume::create(right));
}
void play() {
SPU_IO::Key::On.write(SPU_IO::KeyOn::for_specific(Voice::get_id())); SPU_IO::Key::On.write(SPU_IO::KeyOn::for_specific(Voice::get_id()));
} }
void stop() const { void stop() {
SPU_IO::Key::Off.write(SPU_IO::KeyOff::for_specific(Voice::get_id())); SPU_IO::Key::Off.write(SPU_IO::KeyOff::for_specific(Voice::get_id()));
} }
}; };
extern const Voice voice[SPU_IO::VoiceCount]; extern Voice voice[SPU_IO::VoiceCount];
} }
} }

View File

@ -219,6 +219,10 @@ namespace JabyEngine {
static constexpr auto Step = BitRange::from_to(0, 1); static constexpr auto Step = BitRange::from_to(0, 1);
}; };
static constexpr SweepVolume create(SimpleVolume volume) {
return from(VolumeMode::Enable, VolumeMode::Volume.with(volume.raw >> 1));
}
static constexpr SweepVolume mute() { static constexpr SweepVolume mute() {
return SweepVolume{0}; return SweepVolume{0};
} }

View File

@ -31,12 +31,12 @@ namespace JabyEngine {
}; };
struct VAGState { struct VAGState {
uint32_t voice_id; uint32_t voice_id;
size_t words_left; size_t words_left;
SPU::SRAMAdr adr; SPU::SimpleVolume inital_vol;
static constexpr VAGState create(uint32_t voice_id) { static constexpr VAGState create(uint32_t voice_id, SPU::SimpleVolume inital_vol) {
return VAGState{.voice_id = voice_id, .words_left = 0, .adr = 0}; return VAGState{.voice_id = voice_id, .words_left = 0, .inital_vol = inital_vol};
} }
}; };
@ -55,11 +55,13 @@ namespace JabyEngine {
const auto bytes = header.get_sample_size(); const auto bytes = header.get_sample_size();
state.words_left = bytes_to_words(bytes); state.words_left = bytes_to_words(bytes);
state.adr = SPU::voice[state.voice_id].allocate(SPU_IO::SampleRate::from_HZ(header.get_sample_frequency()), words_to_bytes(state.words_left));
auto sram_adr = SPU::voice[state.voice_id].allocate(SPU_IO::SampleRate::from_HZ(header.get_sample_frequency()), words_to_bytes(state.words_left));
SPU::voice[state.voice_id].set_volume(state.inital_vol, state.inital_vol);
config.processed(sizeof(VAGHeader)); config.processed(sizeof(VAGHeader));
SPU::internal::DMA::Receive::prepare(); SPU::internal::DMA::Receive::prepare();
SPU::internal::DMA::Receive::set_dst(state.adr); SPU::internal::DMA::Receive::set_dst(sram_adr);
SPU::internal::DMA::Receive::set_src(reinterpret_cast<uintptr_t>(config.data_adr)); SPU::internal::DMA::Receive::set_src(reinterpret_cast<uintptr_t>(config.data_adr));
return Helper::exchange_and_execute_process_function(parse_sample, config, state); return Helper::exchange_and_execute_process_function(parse_sample, config, state);
@ -69,7 +71,7 @@ namespace JabyEngine {
} }
State create(const uint32_t* data_adr, const VAG& file) { State create(const uint32_t* data_adr, const VAG& file) {
return State::from(VAGState::create(file.voice_number), data_adr, parse_header); return State::from(VAGState::create(file.voice_number, file.inital_stereo_vol), data_adr, parse_header);
} }
} }
} }

View File

@ -8,7 +8,7 @@
namespace JabyEngine { namespace JabyEngine {
namespace SPU { namespace SPU {
SRAMAdr Voice :: allocate(size_t size) const { SRAMAdr Voice :: allocate(size_t size) {
Voice::stop(); Voice::stop();
const auto voice_id = Voice::get_id(); const auto voice_id = Voice::get_id();
const auto adr = SRAMAdr{static_cast<SRAMAdr::UnderlyingType>(reinterpret_cast<uintptr_t>(SPU_MMU::allocate(voice_id, size)))}; const auto adr = SRAMAdr{static_cast<SRAMAdr::UnderlyingType>(reinterpret_cast<uintptr_t>(SPU_MMU::allocate(voice_id, size)))};
@ -17,13 +17,13 @@ namespace JabyEngine {
return adr; return adr;
} }
SRAMAdr Voice :: allocate(SPU_IO::SampleRate frequency, size_t size) const { SRAMAdr Voice :: allocate(SPU_IO::SampleRate frequency, size_t size) {
const auto result = Voice::allocate(size); const auto result = Voice::allocate(size);
Voice::set_sample_rate(frequency); Voice::set_sample_rate(frequency);
return result; return result;
} }
void Voice :: deallocate() const { void Voice :: deallocate() {
Voice::stop(); Voice::stop();
SPU_MMU::deallocate(Voice::get_id()); SPU_MMU::deallocate(Voice::get_id());
} }