#pragma once #include "../System/IOPorts/spu_io.hpp" namespace JabyEngine { namespace SPU { using SPU_IO_Values::operator""_vol; using SRAMAdr = SPU_IO_Values::SRAMAdr; using SimpleVolume = SPU_IO_Values::SimpleVolume; using SweepVolume = SPU_IO_Values::SweepVolume; struct Voice { size_t get_id() const { return reinterpret_cast(this); } SRAMAdr allocate(size_t size); SRAMAdr allocate(SPU_IO_Values::SampleRate frequency, size_t size); void deallocate(); void set_sample_rate(SPU_IO_Values::SampleRate frequency) { SPU_IO::Voice[Voice::get_id()].sampleRate.write(frequency); } void set_volume(SimpleVolume left, SimpleVolume right) { 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_Values::KeyOn::for_specific(Voice::get_id())); } void play_if_end() { if(Voice::is_end()) { Voice::play(); } } void stop() { SPU_IO::Key::Off.write(SPU_IO_Values::KeyOff::for_specific(Voice::get_id())); } bool is_end() const { return SPU_IO::Voice[Voice::get_id()].adsr_volume.read() == SimpleVolume::mute(); } }; static auto& voice = __declare_io_port_array(Voice, SPU_IO::VoiceCount, 0x0); } }