78 lines
3.1 KiB
C++
78 lines
3.1 KiB
C++
#include "../../../internal-include/SPU/spu_internal.hpp"
|
|
#include <PSX/Auxiliary/big_endian.hpp>
|
|
#include <PSX/Auxiliary/word_helper.hpp>
|
|
#include <PSX/File/file_processor_helper.hpp>
|
|
#include <PSX/SPU/spu.hpp>
|
|
#include <stdio.hpp>
|
|
|
|
namespace JabyEngine {
|
|
namespace FileProcessor {
|
|
struct VAGHeader {
|
|
char id[4];
|
|
uint32_t version;
|
|
uint32_t reserved;
|
|
uint32_t sample_size;
|
|
uint32_t sample_frequency;
|
|
uint8_t reserved_2[12];
|
|
char name[16];
|
|
|
|
constexpr uint32_t get_version() const {
|
|
return read_be(this->version);
|
|
}
|
|
|
|
constexpr uint32_t get_sample_size() const {
|
|
return read_be(this->sample_size);
|
|
}
|
|
|
|
constexpr uint32_t get_sample_frequency() const {
|
|
return read_be(this->sample_frequency);
|
|
}
|
|
};
|
|
|
|
struct VAGState {
|
|
uint32_t voice_id;
|
|
size_t words_left;
|
|
SPU::SimpleVolume inital_vol;
|
|
|
|
static constexpr VAGState create(uint32_t voice_id, SPU::SimpleVolume inital_vol) {
|
|
return VAGState{.voice_id = voice_id, .words_left = 0, .inital_vol = inital_vol};
|
|
}
|
|
};
|
|
|
|
static Progress parse_sample(State::Configuration& config, VAGState& state) {
|
|
const auto [words_to_use, is_last] = Helper::DMA::WordsReady::calculate(config, state.words_left);
|
|
const auto words_used = Helper::DMA::send_words<SPU::internal::DMA>(words_to_use, is_last);
|
|
|
|
state.words_left -= words_used;
|
|
config.processed(words_used*sizeof(uint32_t));
|
|
return is_last ? Progress::Done : Progress::InProgress;
|
|
}
|
|
|
|
static Progress parse_header(State::Configuration& config, VAGState& state) {
|
|
if(config.data_bytes >= sizeof(VAGHeader)) {
|
|
const auto& header = *reinterpret_cast<const VAGHeader*>(config.data_adr);
|
|
const auto words = bytes_to_words(header.get_sample_size());
|
|
const auto bytes = words_to_bytes(words);
|
|
|
|
state.words_left = words;
|
|
|
|
auto sram_adr = SPU::voice[state.voice_id].allocate(SPU_IO_Values::SampleRate::from_HZ(header.get_sample_frequency()), bytes);
|
|
|
|
SPU::voice[state.voice_id].set_volume(state.inital_vol, state.inital_vol);
|
|
|
|
config.processed(sizeof(VAGHeader));
|
|
SPU::internal::DMA::Receive::prepare();
|
|
SPU::internal::DMA::Receive::set_dst(sram_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 Progress::InProgress;
|
|
}
|
|
|
|
State create(const uint32_t* data_adr, const VAG& file) {
|
|
return State::from(VAGState::create(file.voice_number, file.inital_stereo_vol), data_adr, parse_header);
|
|
}
|
|
}
|
|
} |