mirror of
https://github.com/open-goal/jak-project.git
synced 2025-02-21 14:40:50 +00:00
Initial Sound Implementation (#1325)
This commit is contained in:
parent
be976d2e69
commit
07cc0ddc35
@ -127,6 +127,8 @@ add_subdirectory(common)
|
||||
# build decompiler
|
||||
add_subdirectory(decompiler)
|
||||
|
||||
add_subdirectory(third-party/cubeb)
|
||||
|
||||
# build glfw library
|
||||
add_subdirectory(third-party/glfw)
|
||||
add_subdirectory(third-party/zstd)
|
||||
|
@ -73,7 +73,6 @@ set(RUNTIME_SOURCE
|
||||
overlord/overlord.cpp
|
||||
overlord/ramdisk.cpp
|
||||
overlord/sbank.cpp
|
||||
overlord/sndshim.cpp
|
||||
overlord/soundcommon.cpp
|
||||
overlord/srpc.cpp
|
||||
overlord/ssound.cpp
|
||||
@ -149,10 +148,12 @@ endfunction()
|
||||
|
||||
write_svnrev_h()
|
||||
|
||||
add_subdirectory(sound)
|
||||
|
||||
# we build the runtime as a static library.
|
||||
add_library(runtime STATIC ${RUNTIME_SOURCE} "../third-party/glad/src/glad.c")
|
||||
|
||||
target_link_libraries(runtime common fmt glfw imgui discord-rpc)
|
||||
target_link_libraries(runtime common fmt glfw imgui discord-rpc sound)
|
||||
if(WIN32)
|
||||
target_link_libraries(runtime mman)
|
||||
else()
|
||||
|
@ -17,7 +17,12 @@ struct RPC_Str_Cmd {
|
||||
};
|
||||
|
||||
struct RPC_Play_Cmd {
|
||||
u8 pad[1024]; // TODO everything
|
||||
u16 rsvd;
|
||||
u16 result;
|
||||
u32 address;
|
||||
u32 section;
|
||||
u32 maxlen;
|
||||
char name[48];
|
||||
};
|
||||
|
||||
constexpr int STR_RPC_RESULT_ERROR = 1;
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "dma.h"
|
||||
#include "common/common_types.h"
|
||||
#include "game/sce/iop.h"
|
||||
#include "game/sound/sdshim.h"
|
||||
#include "game/sound/sndshim.h"
|
||||
|
||||
using namespace iop;
|
||||
|
||||
@ -85,9 +87,24 @@ void DMA_SendToEE(void* data, u32 size, void* dest) {
|
||||
* SPU DMA interrupt handler.
|
||||
|
||||
*/
|
||||
u32 intr() {
|
||||
s32 intr(s32 channel, void* userdata) {
|
||||
strobe = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO DMA_SendToSPUAndSync()
|
||||
bool DMA_SendToSPUAndSync(void* src_addr, u32 size, u32 dst_addr) {
|
||||
s32 channel = snd_GetFreeSPUDMA();
|
||||
if (channel == -1)
|
||||
return false;
|
||||
strobe = 0;
|
||||
sceSdSetTransIntrHandler(channel, intr, nullptr);
|
||||
// Skip this, we end up memcpy's from OOB (which trips asan)
|
||||
// u32 size_aligned = (size + 63) & 0xFFFFFFF0;
|
||||
u32 size_aligned = size;
|
||||
s32 transferred = sceSdVoiceTrans(channel, 0, src_addr, dst_addr, size_aligned);
|
||||
while (!strobe)
|
||||
;
|
||||
sceSdSetTransIntrHandler(channel, nullptr, nullptr);
|
||||
snd_FreeSPUDMA(channel);
|
||||
return transferred >= size_aligned;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
void DMA_Sync();
|
||||
void DMA_SendToEE(void* data, u32 size, void* dest);
|
||||
bool DMA_SendToSPUAndSync(void* src_addr, u32 size, u32 dst_addr);
|
||||
void dma_init_globals();
|
||||
|
||||
#endif // JAK_V2_DMA_H
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <filesystem>
|
||||
#include "fake_iso.h"
|
||||
#include "game/overlord/sbank.h"
|
||||
#include "game/overlord/sndshim.h"
|
||||
#include "game/sound/sndshim.h"
|
||||
#include "game/overlord/soundcommon.h"
|
||||
#include "game/overlord/srpc.h"
|
||||
#include "game/sce/iop.h"
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include "common/log/log.h"
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include "game/overlord/srpc.h"
|
||||
#include "game/sound/sndshim.h"
|
||||
#include "iso.h"
|
||||
#include "iso_cd.h"
|
||||
#include "iso_queue.h"
|
||||
@ -17,21 +19,44 @@
|
||||
#include "fake_iso.h"
|
||||
#include "game/common/dgo_rpc_types.h"
|
||||
#include "common/util/Assert.h"
|
||||
#include "game/sound/sdshim.h"
|
||||
|
||||
using namespace iop;
|
||||
|
||||
u32 ISOThread();
|
||||
u32 DGOThread();
|
||||
u32 ProcessVAGData(IsoMessage* _cmd, IsoBufferHeader* buffer_header);
|
||||
u32 RunDGOStateMachine(IsoMessage* _cmd, IsoBufferHeader* buffer_header);
|
||||
u32 CopyDataToEE(IsoMessage* _cmd, IsoBufferHeader* buffer_header);
|
||||
u32 CopyDataToIOP(IsoMessage* _cmd, IsoBufferHeader* buffer_header);
|
||||
u32 NullCallback(IsoMessage* _cmd, IsoBufferHeader* buffer_header);
|
||||
|
||||
constexpr int VAGDIR_SIZE = 0x28b4;
|
||||
static void InitVAGCmd(VagCommand* cmd, u32 x);
|
||||
static u32 ProcessVAGData(IsoMessage* _cmd, IsoBufferHeader* buffer_header);
|
||||
static s32 CheckVAGStreamProgress(VagCommand* vag);
|
||||
static void StopVAG(VagCommand* vag);
|
||||
static void PauseVAG(VagCommand* vag);
|
||||
static void UnpauseVAG(VagCommand* vag);
|
||||
static void SetVAGVol();
|
||||
static s32 GetPlayPos();
|
||||
static void UpdatePlayPos();
|
||||
static void VAG_MarkLoopEnd(void* data, u32 size);
|
||||
|
||||
constexpr int LOADING_SCREEN_SIZE = 0x800000;
|
||||
constexpr u32 LOADING_SCREEN_DEST_ADDR = 0x1000000;
|
||||
|
||||
static constexpr s32 LOOP_END = 1;
|
||||
static constexpr s32 LOOP_REPEAT = 2;
|
||||
static constexpr s32 LOOP_START = 4;
|
||||
|
||||
// Empty ADPCM block with loop flags
|
||||
// clang-format off
|
||||
static u8 VAG_SilentLoop[0x60] = {
|
||||
0x0, LOOP_START | LOOP_REPEAT, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, LOOP_REPEAT, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, LOOP_END | LOOP_REPEAT, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
IsoFs* isofs;
|
||||
u32 iso_init_flag;
|
||||
s32 sync_mbx;
|
||||
@ -41,10 +66,23 @@ s32 iso_thread;
|
||||
s32 dgo_thread;
|
||||
s32 str_thread;
|
||||
s32 play_thread;
|
||||
u8 gVagDir[VAGDIR_SIZE];
|
||||
VagDir gVagDir;
|
||||
u32 gPlayPos;
|
||||
static RPC_Dgo_Cmd sRPCBuff[1]; // todo move...
|
||||
DgoCommand scmd;
|
||||
static VagCommand vag_cmd;
|
||||
VagCommand* gVAGCMD = nullptr;
|
||||
s32 gDialogVolume = 0;
|
||||
s32 gFakeVAGClockPaused = 0;
|
||||
s32 gFakeVAGClockRunning = 0;
|
||||
s32 gFakeVAGClock = 0;
|
||||
s32 gRealVAGClockRunning = 0;
|
||||
s32 gRealVAGClock = 0;
|
||||
s32 gRealVAGClockS = 0;
|
||||
s32 gPlaying = 0;
|
||||
s32 gSampleRate = 0;
|
||||
bool gLastVagHalf = false;
|
||||
s32 gVoice;
|
||||
|
||||
void iso_init_globals() {
|
||||
isofs = nullptr;
|
||||
@ -56,7 +94,7 @@ void iso_init_globals() {
|
||||
dgo_thread = 0;
|
||||
str_thread = 0;
|
||||
play_thread = 0;
|
||||
memset(gVagDir, 0, sizeof(gVagDir));
|
||||
memset(&gVagDir, 0, sizeof(gVagDir));
|
||||
gPlayPos = 0;
|
||||
memset(sRPCBuff, 0, sizeof(sRPCBuff));
|
||||
memset(&scmd, 0, sizeof(DgoCommand));
|
||||
@ -119,10 +157,9 @@ u32 InitISOFS(const char* fs_mode, const char* loading_screen) {
|
||||
// mark us as NOT initialized.
|
||||
iso_init_flag = 1;
|
||||
|
||||
// TODO ADD
|
||||
// while(!DMA_SendToSPUAndSync(&VAG_SilentLoop, 0x30, gTrapSRAM)) {
|
||||
// DelayThread(1000);
|
||||
// }
|
||||
while (!DMA_SendToSPUAndSync(&VAG_SilentLoop, 0x30, gTrapSRAM)) {
|
||||
DelayThread(1000);
|
||||
}
|
||||
|
||||
// INITIALIZE MESSAGE BOXES
|
||||
MbxParam mbx_param;
|
||||
@ -205,7 +242,7 @@ u32 InitISOFS(const char* fs_mode, const char* loading_screen) {
|
||||
// LOAD VAGDIR file
|
||||
FileRecord* vagdir_file = FindISOFile("VAGDIR.AYB");
|
||||
if (vagdir_file) {
|
||||
LoadISOFileToIOP(vagdir_file, gVagDir, VAGDIR_SIZE);
|
||||
LoadISOFileToIOP(vagdir_file, &gVagDir, sizeof(gVagDir));
|
||||
}
|
||||
FileRecord* loading_screen_file = FindISOFile(loading_screen);
|
||||
if (loading_screen_file) {
|
||||
@ -230,29 +267,15 @@ u32 GetISOFileLength(FileRecord* f) {
|
||||
return isofs->get_length(f);
|
||||
}
|
||||
|
||||
struct VagDirEntry {
|
||||
union {
|
||||
char name[8];
|
||||
s32 name_as_s32s[2];
|
||||
};
|
||||
|
||||
u32 unknown;
|
||||
};
|
||||
static_assert(sizeof(VagDirEntry) == 12, "bad size of VagDirEntry");
|
||||
|
||||
/*!
|
||||
* Find VAG file by "name", where name is 8 bytes (chars with spaces at the end, treated as two
|
||||
* s32's). Returns pointer to name in the VAGDIR file data.
|
||||
*/
|
||||
VagDirEntry* FindVAGFile(s32* name) {
|
||||
// First 4 bytes of VAGDIR file are the number of entries.
|
||||
// Next is a list of entries.
|
||||
VagDirEntry* entry = (VagDirEntry*)(gVagDir + 4);
|
||||
|
||||
// loop over entries
|
||||
for (s32 idx = 0; idx < *(s32*)gVagDir; idx++) {
|
||||
VagDirEntry* FindVAGFile(const char* name) {
|
||||
VagDirEntry* entry = gVagDir.vag;
|
||||
for (s32 idx = 0; idx < gVagDir.count; idx++) {
|
||||
// check if matching name
|
||||
if (entry->name_as_s32s[0] == name[0] && entry->name_as_s32s[1] == name[1]) {
|
||||
if (memcmp(entry->name, name, 8) == 0) {
|
||||
return entry;
|
||||
}
|
||||
entry++;
|
||||
@ -271,6 +294,8 @@ u32 ISOThread() {
|
||||
FreeBuffer(temp_buffer);
|
||||
|
||||
VagCommand* in_progress_vag_command = nullptr;
|
||||
s32 vag_paused = 0;
|
||||
s32 unk = 0;
|
||||
|
||||
// main CD/DVD read loop
|
||||
for (;;) {
|
||||
@ -280,23 +305,27 @@ u32 ISOThread() {
|
||||
|
||||
// receive a message
|
||||
IsoMessage* msg_from_mbx;
|
||||
IsoCommandLoadSingle* load_single_cmd;
|
||||
s32 mbx_status = PollMbx((MsgPacket**)(&msg_from_mbx), iso_mbx);
|
||||
load_single_cmd = (IsoCommandLoadSingle*)msg_from_mbx;
|
||||
|
||||
if (mbx_status == 0) {
|
||||
if (mbx_status == KE_OK) {
|
||||
// we got a new message!
|
||||
|
||||
// initialize fields of the message
|
||||
msg_from_mbx->callback_buffer = nullptr;
|
||||
msg_from_mbx->ready_for_data = 1;
|
||||
msg_from_mbx->callback_function = NullCallback;
|
||||
msg_from_mbx->fd = nullptr;
|
||||
|
||||
if (msg_from_mbx->cmd_id == LOAD_TO_EE_CMD_ID || msg_from_mbx->cmd_id == LOAD_TO_IOP_CMD_ID ||
|
||||
msg_from_mbx->cmd_id == LOAD_TO_EE_OFFSET_CMD_ID) {
|
||||
// A Simple File Load, add it to the queue
|
||||
if (QueueMessage(msg_from_mbx, 2, "LoadSingle")) {
|
||||
switch (msg_from_mbx->cmd_id) {
|
||||
case LOAD_TO_EE_CMD_ID:
|
||||
case LOAD_TO_IOP_CMD_ID:
|
||||
case LOAD_TO_EE_OFFSET_CMD_ID: {
|
||||
// A Simple File Load, add it to the queue
|
||||
if (!QueueMessage(msg_from_mbx, 2, "LoadSingle")) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto* load_single_cmd = (IsoCommandLoadSingle*)msg_from_mbx;
|
||||
|
||||
// if queued successfully, start by opening the file:
|
||||
if (load_single_cmd->cmd_id == LOAD_TO_EE_OFFSET_CMD_ID) {
|
||||
load_single_cmd->fd =
|
||||
@ -314,39 +343,41 @@ u32 ISOThread() {
|
||||
UnqueueMessage(load_single_cmd);
|
||||
// and wake up whoever requested this.
|
||||
ReturnMessage(load_single_cmd);
|
||||
} else {
|
||||
// yep, opened correctly. Set up the pointers/sizes
|
||||
load_single_cmd->dst_ptr = load_single_cmd->dest_addr;
|
||||
load_single_cmd->bytes_done = 0;
|
||||
// by default, copy size is the full file.
|
||||
load_single_cmd->length_to_copy = isofs->get_length(load_single_cmd->file_record);
|
||||
|
||||
if (load_single_cmd->length_to_copy == 0) {
|
||||
// if we get zero for some reason, use the commanded length.
|
||||
ASSERT(false);
|
||||
load_single_cmd->length_to_copy = load_single_cmd->length;
|
||||
} else if (load_single_cmd->length < load_single_cmd->length_to_copy) {
|
||||
// if we ask for less than the full length, use the smaller value.
|
||||
load_single_cmd->length_to_copy = load_single_cmd->length;
|
||||
}
|
||||
|
||||
// set status and callback function.
|
||||
load_single_cmd->status = CMD_STATUS_IN_PROGRESS;
|
||||
switch (msg_from_mbx->cmd_id) {
|
||||
case LOAD_TO_EE_CMD_ID:
|
||||
case LOAD_TO_EE_OFFSET_CMD_ID:
|
||||
msg_from_mbx->callback_function = CopyDataToEE;
|
||||
break;
|
||||
case LOAD_TO_IOP_CMD_ID:
|
||||
msg_from_mbx->callback_function = CopyDataToIOP;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (msg_from_mbx->cmd_id == LOAD_DGO_CMD_ID) {
|
||||
// Got a DGO command. There is one LoadDGO command for the entire DGO.
|
||||
if (QueueMessage(msg_from_mbx, 0, "LoadDGO")) {
|
||||
|
||||
// yep, opened correctly. Set up the pointers/sizes
|
||||
load_single_cmd->dst_ptr = load_single_cmd->dest_addr;
|
||||
load_single_cmd->bytes_done = 0;
|
||||
// by default, copy size is the full file.
|
||||
load_single_cmd->length_to_copy = isofs->get_length(load_single_cmd->file_record);
|
||||
|
||||
if (load_single_cmd->length_to_copy == 0) {
|
||||
// if we get zero for some reason, use the commanded length.
|
||||
ASSERT(false);
|
||||
load_single_cmd->length_to_copy = load_single_cmd->length;
|
||||
} else if (load_single_cmd->length < load_single_cmd->length_to_copy) {
|
||||
// if we ask for less than the full length, use the smaller value.
|
||||
load_single_cmd->length_to_copy = load_single_cmd->length;
|
||||
}
|
||||
|
||||
// set status and callback function.
|
||||
load_single_cmd->status = CMD_STATUS_IN_PROGRESS;
|
||||
u32 cmd_id = msg_from_mbx->cmd_id;
|
||||
if (cmd_id == LOAD_TO_EE_CMD_ID || cmd_id == LOAD_TO_EE_OFFSET_CMD_ID) {
|
||||
msg_from_mbx->callback_function = CopyDataToEE;
|
||||
} else if (cmd_id == LOAD_TO_IOP_CMD_ID) {
|
||||
msg_from_mbx->callback_function = CopyDataToIOP;
|
||||
}
|
||||
|
||||
} break;
|
||||
case LOAD_DGO_CMD_ID: {
|
||||
if (!QueueMessage(msg_from_mbx, 0, "LoadDGO")) {
|
||||
break;
|
||||
}
|
||||
// Got a DGO command. There is one LoadDGO command for the entire DGO.
|
||||
// queued successfully, open the file.
|
||||
auto* load_single_cmd = (IsoCommandLoadSingle*)msg_from_mbx;
|
||||
load_single_cmd->fd = isofs->open(load_single_cmd->file_record, -1);
|
||||
if (!load_single_cmd->fd) {
|
||||
// failed to open, return error
|
||||
@ -359,56 +390,211 @@ u32 ISOThread() {
|
||||
((DgoCommand*)load_single_cmd)->dgo_state = DgoState::Init;
|
||||
load_single_cmd->callback_function = RunDGOStateMachine;
|
||||
}
|
||||
}
|
||||
} else if (msg_from_mbx->cmd_id == LOAD_SOUND_BANK) {
|
||||
// if there's an in progress vag command, try again.
|
||||
if (!in_progress_vag_command || !in_progress_vag_command->field_0x3c) {
|
||||
|
||||
} break;
|
||||
case LOAD_SOUND_BANK: {
|
||||
// if there's an in progress vag command, try again.
|
||||
if (in_progress_vag_command && !in_progress_vag_command->paused) {
|
||||
SendMbx(iso_mbx, msg_from_mbx);
|
||||
break;
|
||||
}
|
||||
|
||||
auto buff = TryAllocateBuffer(BUFFER_PAGE_SIZE);
|
||||
if (!buff) {
|
||||
// no buffers, try again.
|
||||
SendMbx(iso_mbx, msg_from_mbx);
|
||||
} else {
|
||||
auto* cmd = (SoundBankLoadCommand*)msg_from_mbx;
|
||||
isofs->load_sound_bank(cmd->bank_name, cmd->bank);
|
||||
FreeBuffer(buff);
|
||||
ReturnMessage(msg_from_mbx);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// just try again...
|
||||
SendMbx(iso_mbx, msg_from_mbx);
|
||||
}
|
||||
} else if (msg_from_mbx->cmd_id == LOAD_MUSIC) {
|
||||
// if there's an in progress vag command, try again.
|
||||
if (!in_progress_vag_command || !in_progress_vag_command->field_0x3c) {
|
||||
|
||||
auto* cmd = (SoundBankLoadCommand*)msg_from_mbx;
|
||||
isofs->load_sound_bank(cmd->bank_name, cmd->bank);
|
||||
FreeBuffer(buff);
|
||||
ReturnMessage(msg_from_mbx);
|
||||
} break;
|
||||
case LOAD_MUSIC: {
|
||||
// if there's an in progress vag command, try again.
|
||||
if (in_progress_vag_command && !in_progress_vag_command->paused) {
|
||||
SendMbx(iso_mbx, msg_from_mbx);
|
||||
break;
|
||||
}
|
||||
|
||||
auto buff = TryAllocateBuffer(BUFFER_PAGE_SIZE);
|
||||
if (!buff) {
|
||||
// no buffers, try again.
|
||||
SendMbx(iso_mbx, msg_from_mbx);
|
||||
} else {
|
||||
auto* cmd = (MusicLoadCommand*)msg_from_mbx;
|
||||
isofs->load_music(cmd->music_name, cmd->music_handle);
|
||||
FreeBuffer(buff);
|
||||
ReturnMessage(msg_from_mbx);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// just try again...
|
||||
SendMbx(iso_mbx, msg_from_mbx);
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
printf("[OVERLORD] Unknown ISOThread message id 0x%x\n", msg_from_mbx->cmd_id);
|
||||
}
|
||||
auto* cmd = (MusicLoadCommand*)msg_from_mbx;
|
||||
isofs->load_music(cmd->music_name, cmd->music_handle);
|
||||
FreeBuffer(buff);
|
||||
ReturnMessage(msg_from_mbx);
|
||||
|
||||
// TODO magic number
|
||||
} else if (mbx_status == -0x1a9) {
|
||||
} break;
|
||||
case QUEUE_VAG_STREAM: {
|
||||
auto* cmd = (VagCommand*)msg_from_mbx;
|
||||
if (cmd->vag &&
|
||||
(!in_progress_vag_command || in_progress_vag_command->vag != cmd->vag ||
|
||||
in_progress_vag_command->file != cmd->file) &&
|
||||
(!in_progress_vag_command || (!vag_paused && in_progress_vag_command->paused))) {
|
||||
if (in_progress_vag_command) {
|
||||
gVAGCMD = nullptr;
|
||||
StopVAG(in_progress_vag_command);
|
||||
ReleaseMessage(in_progress_vag_command);
|
||||
}
|
||||
in_progress_vag_command = &vag_cmd;
|
||||
memcpy(&vag_cmd, cmd, sizeof(vag_cmd));
|
||||
InitVAGCmd(&vag_cmd, 1);
|
||||
LoadStackEntry* file = nullptr;
|
||||
if (QueueMessage(&vag_cmd, 3, "QueueVAG")) {
|
||||
if (vag_cmd.vag) {
|
||||
file = isofs->open_wad(vag_cmd.file, vag_cmd.vag->offset);
|
||||
}
|
||||
vag_cmd.fd = file;
|
||||
vag_cmd.status = -1;
|
||||
vag_cmd.callback_function = ProcessVAGData;
|
||||
gVAGCMD = &vag_cmd;
|
||||
} else {
|
||||
in_progress_vag_command = nullptr;
|
||||
}
|
||||
}
|
||||
ReturnMessage(cmd);
|
||||
} break;
|
||||
case PLAY_VAG_STREAM: {
|
||||
auto* cmd = (VagCommand*)msg_from_mbx;
|
||||
bool thing = true;
|
||||
if (in_progress_vag_command && in_progress_vag_command->vag == cmd->vag &&
|
||||
in_progress_vag_command->file == cmd->file) {
|
||||
in_progress_vag_command->volume = cmd->volume;
|
||||
in_progress_vag_command->sound_id = cmd->sound_id;
|
||||
if (in_progress_vag_command->paused) {
|
||||
if (vag_paused) {
|
||||
unk = 1;
|
||||
} else {
|
||||
UnpauseVAG(in_progress_vag_command);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (in_progress_vag_command && !in_progress_vag_command->paused &&
|
||||
cmd->priority < in_progress_vag_command->priority) {
|
||||
thing = false;
|
||||
}
|
||||
if (thing) {
|
||||
if (in_progress_vag_command) {
|
||||
gVAGCMD = nullptr;
|
||||
StopVAG(in_progress_vag_command);
|
||||
ReleaseMessage(in_progress_vag_command);
|
||||
}
|
||||
in_progress_vag_command = &vag_cmd;
|
||||
memcpy(&vag_cmd, cmd, sizeof(vag_cmd));
|
||||
if (vag_paused) {
|
||||
InitVAGCmd(&vag_cmd, 1);
|
||||
unk = 1;
|
||||
} else {
|
||||
InitVAGCmd(&vag_cmd, 0);
|
||||
}
|
||||
vag_cmd.messagebox_to_reply = 0;
|
||||
vag_cmd.thread_id = 0;
|
||||
if (QueueMessage(&vag_cmd, 3, "PlayVag")) {
|
||||
if (vag_cmd.vag) {
|
||||
vag_cmd.fd = isofs->open_wad(vag_cmd.file, vag_cmd.vag->offset);
|
||||
} else {
|
||||
vag_cmd.fd = nullptr;
|
||||
}
|
||||
vag_cmd.status = -1;
|
||||
vag_cmd.callback_function = ProcessVAGData;
|
||||
gVAGCMD = &vag_cmd;
|
||||
} else {
|
||||
in_progress_vag_command = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (thing) {
|
||||
if (!in_progress_vag_command || in_progress_vag_command->fd) {
|
||||
gRealVAGClock = 0;
|
||||
gRealVAGClockS = 0;
|
||||
gRealVAGClockRunning = true;
|
||||
} else {
|
||||
gFakeVAGClock = 0;
|
||||
gFakeVAGClockRunning = true;
|
||||
gFakeVAGClockPaused = 0;
|
||||
}
|
||||
gVAG_Id = in_progress_vag_command->sound_id;
|
||||
}
|
||||
ReturnMessage(cmd);
|
||||
} break;
|
||||
case STOP_VAG_STREAM: {
|
||||
auto* cmd = (VagCommand*)msg_from_mbx;
|
||||
if (in_progress_vag_command && (!cmd->vag || in_progress_vag_command->vag == cmd->vag) &&
|
||||
(cmd->priority >= in_progress_vag_command->priority)) {
|
||||
gVAGCMD = nullptr;
|
||||
StopVAG(in_progress_vag_command);
|
||||
ReleaseMessage(in_progress_vag_command);
|
||||
in_progress_vag_command = nullptr;
|
||||
}
|
||||
vag_paused = 0;
|
||||
unk = 0;
|
||||
ReturnMessage(cmd);
|
||||
} break;
|
||||
case PAUSE_VAG_STREAM: {
|
||||
auto* cmd = (VagCommand*)msg_from_mbx;
|
||||
gFakeVAGClockPaused = 1;
|
||||
if (!vag_paused) {
|
||||
if (!in_progress_vag_command || in_progress_vag_command->paused) {
|
||||
unk = 0;
|
||||
} else {
|
||||
PauseVAG(in_progress_vag_command);
|
||||
unk = 1;
|
||||
}
|
||||
vag_paused = 1;
|
||||
}
|
||||
ReturnMessage(cmd);
|
||||
} break;
|
||||
case CONTINUE_VAG_STREAM: {
|
||||
auto* cmd = (VagCommand*)msg_from_mbx;
|
||||
gFakeVAGClockPaused = 0;
|
||||
if (vag_paused) {
|
||||
if (unk) {
|
||||
UnpauseVAG(in_progress_vag_command);
|
||||
}
|
||||
vag_paused = 0;
|
||||
unk = 0;
|
||||
}
|
||||
ReturnMessage(cmd);
|
||||
} break;
|
||||
case SET_VAG_VOLUME: {
|
||||
auto* cmd = (VagCommand*)msg_from_mbx;
|
||||
if (in_progress_vag_command) {
|
||||
in_progress_vag_command->volume = cmd->volume;
|
||||
SetVAGVol();
|
||||
}
|
||||
ReturnMessage(cmd);
|
||||
} break;
|
||||
case SET_DIALOG_VOLUME: {
|
||||
auto* cmd = (VagCommand*)msg_from_mbx;
|
||||
gDialogVolume = cmd->volume;
|
||||
if (in_progress_vag_command)
|
||||
SetVAGVol();
|
||||
ReturnMessage(cmd);
|
||||
} break;
|
||||
default:
|
||||
printf("[OVERLORD] Unknown ISOThread message id 0x%x\n", msg_from_mbx->cmd_id);
|
||||
}
|
||||
} else if (mbx_status == KE_WAIT_DELETE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// Handle Sound (TODO)
|
||||
// Handle Sound
|
||||
////////////////////////////
|
||||
|
||||
if (in_progress_vag_command && !CheckVAGStreamProgress(in_progress_vag_command)) {
|
||||
gVAGCMD = nullptr;
|
||||
StopVAG(in_progress_vag_command);
|
||||
ReleaseMessage(in_progress_vag_command);
|
||||
in_progress_vag_command = nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// Begin a read
|
||||
////////////////////////////
|
||||
@ -770,15 +956,16 @@ u32 NullCallback(IsoMessage* _cmd, IsoBufferHeader* buffer_header) {
|
||||
/*!
|
||||
* Initialize a VagCommand.
|
||||
*/
|
||||
void InitVAGCmd(VagCommand* cmd, u32 x) {
|
||||
cmd->field_0x30 = 0;
|
||||
cmd->field_0x34 = 0;
|
||||
cmd->field_0x38 = 0;
|
||||
cmd->field_0x3c = x;
|
||||
cmd->field_0x40 = 0;
|
||||
cmd->field_0x44 = 0;
|
||||
cmd->field_0x48 = 0xffffffff;
|
||||
gPlayPos = 0x30;
|
||||
static void InitVAGCmd(VagCommand* cmd, u32 x) {
|
||||
cmd->buffer_number = 0;
|
||||
cmd->data_left = 0;
|
||||
cmd->started = 0;
|
||||
cmd->paused = x;
|
||||
cmd->sample_rate = 0;
|
||||
cmd->stop = 0;
|
||||
cmd->end_point = -1;
|
||||
cmd->unk2 = 0;
|
||||
gPlayPos = 48;
|
||||
cmd->messagebox_to_reply = 0;
|
||||
cmd->thread_id = 0;
|
||||
}
|
||||
@ -790,24 +977,271 @@ u32 bswap(u32 in) {
|
||||
return ((in >> 0x18) & 0xff) | ((in >> 8) & 0xff00) | ((in & 0xff00) << 8) | (in << 0x18);
|
||||
}
|
||||
|
||||
/*!
|
||||
* TODO - implement.
|
||||
*/
|
||||
u32 ProcessVAGData(IsoMessage* _cmd, IsoBufferHeader* buffer_header) {
|
||||
(void)_cmd;
|
||||
(void)buffer_header;
|
||||
ASSERT(false);
|
||||
return 0;
|
||||
static u32 ProcessVAGData(IsoMessage* _cmd, IsoBufferHeader* buffer_header) {
|
||||
auto* vag = (VagCommand*)_cmd;
|
||||
if (vag->stop) {
|
||||
buffer_header->data_size = 0;
|
||||
return CMD_STATUS_IN_PROGRESS;
|
||||
}
|
||||
|
||||
if (vag->buffer_number == 0) {
|
||||
// first buffer, set stuff up
|
||||
u32* data = (u32*)buffer_header->data;
|
||||
if (data[0] != 0x70474156 /* 'pGAV' */ && data[0] != 0x56414770 /* 'VAGp' */) {
|
||||
vag->stop = true;
|
||||
buffer_header->data_size = 0;
|
||||
return CMD_STATUS_IN_PROGRESS;
|
||||
}
|
||||
|
||||
vag->sample_rate = data[4];
|
||||
vag->data_left = data[3];
|
||||
if (data[0] == 0x70474156 /* 'pGAV' */) {
|
||||
vag->sample_rate = bswap(vag->sample_rate);
|
||||
vag->data_left = bswap(vag->data_left);
|
||||
}
|
||||
|
||||
gSampleRate = vag->sample_rate;
|
||||
gLastVagHalf = false;
|
||||
vag->data_left += 48;
|
||||
if (buffer_header->data_size >= vag->data_left) {
|
||||
vag->end_point = vag->data_left - 16;
|
||||
}
|
||||
|
||||
if (!DMA_SendToSPUAndSync(buffer_header->data, buffer_header->data_size, gStreamSRAM)) {
|
||||
return CMD_STATUS_IN_PROGRESS;
|
||||
}
|
||||
|
||||
sceSdSetParam(gVoice | SD_VP_VOLL, 0);
|
||||
sceSdSetParam(gVoice | SD_VP_VOLR, 0);
|
||||
u32 vmix = sceSdGetSwitch((gVoice & 1) | SD_S_VMIXL);
|
||||
sceSdSetSwitch((gVoice & 1) | SD_S_VMIXL, vmix | (1 << (gVoice >> 1)));
|
||||
vmix = sceSdGetSwitch((gVoice & 1) | SD_S_VMIXR);
|
||||
sceSdSetSwitch((gVoice & 1) | SD_S_VMIXR, vmix | (1 << (gVoice >> 1)));
|
||||
sceSdSetParam(gVoice | SD_VP_PITCH, 0);
|
||||
sceSdSetAddr(gVoice | SD_VA_SSA, gStreamSRAM + 0x30);
|
||||
sceSdSetParam(gVoice | SD_VP_ADSR1, 0xf);
|
||||
sceSdSetParam(gVoice | SD_VP_ADSR2, 0x1fc0);
|
||||
if (vag->end_point == -1) {
|
||||
sceSdSetAddr(gVoice | SD_VA_LSAX, gTrapSRAM);
|
||||
}
|
||||
snd_keyOnVoiceRaw(gVoice & 1, gVoice >> 1);
|
||||
vag->started = 1;
|
||||
vag->data_left -= buffer_header->data_size;
|
||||
buffer_header->data_size = 0;
|
||||
}
|
||||
|
||||
if (vag->buffer_number == 1) {
|
||||
if (buffer_header->data_size < vag->data_left) {
|
||||
VAG_MarkLoopEnd(buffer_header->data, buffer_header->data_size);
|
||||
FlushDcache();
|
||||
} else {
|
||||
vag->end_point = vag->data_left + 0x5FF0;
|
||||
}
|
||||
|
||||
if (!DMA_SendToSPUAndSync(buffer_header->data, buffer_header->data_size,
|
||||
gStreamSRAM + 0x6000)) {
|
||||
return CMD_STATUS_IN_PROGRESS;
|
||||
}
|
||||
|
||||
if (!vag->paused) {
|
||||
vag->paused = 1;
|
||||
UnpauseVAG(vag);
|
||||
}
|
||||
|
||||
vag->ready_for_data = 0;
|
||||
vag->data_left -= buffer_header->data_size;
|
||||
buffer_header->data_size = 0;
|
||||
gPlayPos = 48;
|
||||
gPlaying = true;
|
||||
}
|
||||
|
||||
if (vag->buffer_number > 1) {
|
||||
if ((vag->buffer_number & 1) != 0) {
|
||||
if (buffer_header->data_size < vag->data_left) {
|
||||
VAG_MarkLoopEnd(buffer_header->data, buffer_header->data_size);
|
||||
FlushDcache();
|
||||
} else {
|
||||
vag->end_point = vag->data_left + 0x5FF0;
|
||||
}
|
||||
|
||||
if (!DMA_SendToSPUAndSync(buffer_header->data, buffer_header->data_size,
|
||||
gStreamSRAM + 0x6000)) {
|
||||
return CMD_STATUS_IN_PROGRESS;
|
||||
}
|
||||
|
||||
sceSdSetAddr(gVoice | SD_VA_LSAX, gStreamSRAM + 0x6000);
|
||||
} else {
|
||||
if (buffer_header->data_size < vag->data_left) {
|
||||
VAG_MarkLoopEnd(buffer_header->data, buffer_header->data_size);
|
||||
FlushDcache();
|
||||
} else {
|
||||
vag->end_point = vag->data_left - 16;
|
||||
}
|
||||
|
||||
if (!DMA_SendToSPUAndSync(buffer_header->data, buffer_header->data_size, gStreamSRAM)) {
|
||||
return CMD_STATUS_IN_PROGRESS;
|
||||
}
|
||||
|
||||
sceSdSetAddr(gVoice | SD_VA_LSAX, gStreamSRAM);
|
||||
}
|
||||
|
||||
vag->ready_for_data = 0;
|
||||
vag->data_left -= buffer_header->data_size;
|
||||
buffer_header->data_size = 0;
|
||||
}
|
||||
|
||||
vag->buffer_number++;
|
||||
return CMD_STATUS_IN_PROGRESS;
|
||||
}
|
||||
|
||||
// TODO - StopVAG
|
||||
// TODO - PauseVAG
|
||||
// TODO - CalculateVAGVolumes
|
||||
// TODO - UnpauseVAG
|
||||
// TODO - SetVAGVol
|
||||
// TODO - GetPlayPos
|
||||
// TODO - UpdatePlayPos
|
||||
// TODO - CheckVAGStreamProgress
|
||||
static s32 CheckVAGStreamProgress(VagCommand* vag) {
|
||||
if (vag->stop) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!vag->started) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vag->end_point != -1) {
|
||||
if ((gPlayPos & 0xFFFFFFF0) == vag->end_point) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((gPlayPos < 0x6000) && (vag->end_point < 0x6000)) ||
|
||||
((0x5fff < gPlayPos && (0x5fff < vag->end_point)))) {
|
||||
if ((vag->unk2 == 0) && (gPlayPos < vag->end_point)) {
|
||||
sceSdSetAddr(gVoice | SD_VA_LSAX, gStreamSRAM + vag->end_point);
|
||||
vag->unk2 = 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (gPlayPos < 0x6000) {
|
||||
if ((vag->buffer_number & 1) != 0) {
|
||||
vag->ready_for_data = 1;
|
||||
sceSdSetAddr(gVoice | SD_VA_LSAX, gTrapSRAM);
|
||||
}
|
||||
|
||||
} else {
|
||||
if ((vag->buffer_number & 1) == 0) {
|
||||
vag->ready_for_data = 1;
|
||||
sceSdSetAddr(gVoice | SD_VA_LSAX, gTrapSRAM);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void StopVAG(VagCommand* vag) {
|
||||
gPlaying = false;
|
||||
PauseVAG(vag);
|
||||
snd_keyOffVoiceRaw(gVoice & 1, gVoice >> 1);
|
||||
gFakeVAGClockRunning = false;
|
||||
gRealVAGClockRunning = false;
|
||||
gVAG_Id = 1;
|
||||
}
|
||||
|
||||
static void PauseVAG(VagCommand* vag) {
|
||||
gFakeVAGClockPaused = true;
|
||||
if (vag->paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
vag->paused = true;
|
||||
if (vag->started) {
|
||||
sceSdSetParam(gVoice | SD_VP_VOLL, 0);
|
||||
sceSdSetParam(gVoice | SD_VP_VOLR, 0);
|
||||
sceSdSetParam(gVoice | SD_VP_PITCH, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void CalculateVAGVolumes(s32 volume, s32 positioned, Vec3w* trans, s32* left, s32* right) {
|
||||
if (positioned) {
|
||||
volume = CalculateFallofVolume(trans, (volume * gDialogVolume) >> 10, 1, 10, 50);
|
||||
auto* pan = &gPanTable[(630 - CalculateAngle(trans)) % 360];
|
||||
*left = (pan->left * volume) >> 10;
|
||||
*right = (pan->right * volume) >> 10;
|
||||
if (*left >= 0x4000) {
|
||||
*left = 0x3FFF;
|
||||
}
|
||||
if (*right >= 0x4000) {
|
||||
*right = 0x3FFF;
|
||||
}
|
||||
} else {
|
||||
volume = (volume * gDialogVolume) >> 6;
|
||||
if (volume >= 0x4000) {
|
||||
volume = 0x3FFF;
|
||||
}
|
||||
|
||||
*left = volume;
|
||||
*right = volume;
|
||||
}
|
||||
}
|
||||
|
||||
static void UnpauseVAG(VagCommand* vag) {
|
||||
gFakeVAGClockPaused = false;
|
||||
if (vag->paused) {
|
||||
if (vag->started) {
|
||||
s32 left = 0, right = 0;
|
||||
CalculateVAGVolumes(vag->volume, vag->positioned, &vag->trans, &left, &right);
|
||||
sceSdSetParam(gVoice | SD_VP_VOLL, left);
|
||||
sceSdSetParam(gVoice | SD_VP_VOLR, right);
|
||||
sceSdSetParam(gVoice | SD_VP_PITCH, (vag->sample_rate << 12) / 48000);
|
||||
}
|
||||
|
||||
vag->paused = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void SetVAGVol() {
|
||||
if (gVAGCMD && gVAGCMD->started && !gVAGCMD->paused) {
|
||||
s32 left = 0, right = 0;
|
||||
CalculateVAGVolumes(gVAGCMD->volume, gVAGCMD->positioned, &gVAGCMD->trans, &left, &right);
|
||||
sceSdSetParam(gVoice | SD_VP_VOLL, left);
|
||||
sceSdSetParam(gVoice | SD_VP_VOLR, right);
|
||||
}
|
||||
}
|
||||
|
||||
static s32 GetPlayPos() {
|
||||
// This does the safe NAX read by reading NAX in a loop until it returns
|
||||
// the same value 3 times in a row. We can skip this on pc.
|
||||
u32 NAX = sceSdGetAddr(gVoice | SD_VA_NAX);
|
||||
// We can also say our sample buffer always starts at 0 to simplify things.
|
||||
if (NAX > 0xBFFF) {
|
||||
return -1;
|
||||
} else {
|
||||
return NAX;
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdatePlayPos() {
|
||||
if (!gPlaying) {
|
||||
return;
|
||||
}
|
||||
|
||||
u32 pos = GetPlayPos();
|
||||
if (pos == -1) {
|
||||
if (gLastVagHalf) {
|
||||
pos = 0xC000;
|
||||
} else {
|
||||
pos = 0x6000;
|
||||
}
|
||||
} else {
|
||||
gLastVagHalf = pos >= 0x6000;
|
||||
}
|
||||
|
||||
if (pos >= gPlayPos) {
|
||||
gRealVAGClockS += pos - gPlayPos;
|
||||
} else {
|
||||
gRealVAGClockS += pos + 0xC000 - gPlayPos;
|
||||
}
|
||||
|
||||
gRealVAGClock = 4 * (0x1C00 * (gRealVAGClockS / 16) / gSampleRate);
|
||||
gPlayPos = pos;
|
||||
}
|
||||
|
||||
void* RPC_DGO(unsigned int fno, void* _cmd, int y);
|
||||
void LoadDGO(RPC_Dgo_Cmd* cmd);
|
||||
@ -969,8 +1403,17 @@ void CancelDGO(RPC_Dgo_Cmd* cmd) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - GetVAGStreamPos
|
||||
// TODO - VAG_MarkLoopStart
|
||||
// TODO - VAG_MarkLoopEnd
|
||||
// TODO - VAG_MarkNonloopStart
|
||||
// TODO - VAG_MarkNonloopEnd
|
||||
s32 GetVAGStreamPos() {
|
||||
UpdatePlayPos();
|
||||
if (gFakeVAGClockRunning) {
|
||||
return gFakeVAGClock;
|
||||
}
|
||||
if (gRealVAGClockRunning) {
|
||||
return gRealVAGClock;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void VAG_MarkLoopEnd(void* data, u32 size) {
|
||||
((u8*)data)[size - 15] = 3;
|
||||
}
|
||||
|
@ -9,7 +9,26 @@
|
||||
#include "common/common_types.h"
|
||||
#include "isocommon.h"
|
||||
|
||||
extern s32 gFakeVAGClockPaused;
|
||||
extern s32 gFakeVAGClockRunning;
|
||||
extern s32 gFakeVAGClock;
|
||||
extern s32 gRealVAGClock;
|
||||
extern s32 gVoice;
|
||||
|
||||
struct VagDirEntry {
|
||||
char name[8];
|
||||
u32 offset;
|
||||
};
|
||||
|
||||
static constexpr int VAG_COUNT = 868;
|
||||
struct VagDir {
|
||||
u32 count;
|
||||
VagDirEntry vag[VAG_COUNT];
|
||||
};
|
||||
|
||||
void iso_init_globals();
|
||||
FileRecord* FindISOFile(const char* name);
|
||||
u32 GetISOFileLength(FileRecord* f);
|
||||
u32 InitISOFS(const char* fs_mode, const char* loading_screen);
|
||||
VagDirEntry* FindVAGFile(const char* name);
|
||||
s32 GetVAGStreamPos();
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "common/log/log.h"
|
||||
#include "sbank.h"
|
||||
#include "common/util/Assert.h"
|
||||
#include "iso_queue.h"
|
||||
|
||||
using namespace iop;
|
||||
|
||||
@ -106,3 +107,92 @@ void LoadMusic(const char* music_name, s32* bank) {
|
||||
|
||||
gMusicTweak = 0x80;
|
||||
}
|
||||
|
||||
void QueueVAGStream(FileRecord* file, VagDirEntry* vag, u32 sound_id, u32 priority) {
|
||||
if (vag == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* cmd = GetVAGCommand();
|
||||
cmd->cmd_id = QUEUE_VAG_STREAM;
|
||||
cmd->messagebox_to_reply = 0;
|
||||
cmd->thread_id = 0;
|
||||
cmd->file = file;
|
||||
cmd->vag = vag;
|
||||
cmd->sound_id = sound_id;
|
||||
cmd->priority = priority;
|
||||
cmd->positioned = 0;
|
||||
|
||||
SendMbx(iso_mbx, cmd);
|
||||
}
|
||||
|
||||
void PlayVAGStream(FileRecord* file,
|
||||
VagDirEntry* vag,
|
||||
u32 sound_id,
|
||||
s32 volume,
|
||||
u32 priority,
|
||||
Vec3w* trans) {
|
||||
auto cmd = GetVAGCommand();
|
||||
cmd->cmd_id = PLAY_VAG_STREAM;
|
||||
cmd->messagebox_to_reply = 0;
|
||||
cmd->thread_id = 0;
|
||||
cmd->file = file;
|
||||
cmd->vag = vag;
|
||||
cmd->sound_id = sound_id;
|
||||
cmd->volume = volume;
|
||||
cmd->priority = priority;
|
||||
|
||||
if (trans) {
|
||||
cmd->trans = *trans;
|
||||
cmd->positioned = 1;
|
||||
} else {
|
||||
cmd->positioned = 0;
|
||||
}
|
||||
|
||||
SendMbx(iso_mbx, cmd);
|
||||
}
|
||||
|
||||
void SetVAGStreamVolume(s32 volume) {
|
||||
auto cmd = GetVAGCommand();
|
||||
cmd->cmd_id = 1029;
|
||||
cmd->messagebox_to_reply = 0;
|
||||
cmd->thread_id = 0;
|
||||
cmd->volume = volume;
|
||||
SendMbx(iso_mbx, cmd);
|
||||
}
|
||||
|
||||
void SetDialogVolume(s32 volume) {
|
||||
auto cmd = GetVAGCommand();
|
||||
cmd->cmd_id = 1030;
|
||||
cmd->messagebox_to_reply = 0;
|
||||
cmd->thread_id = 0;
|
||||
cmd->volume = volume;
|
||||
SendMbx(iso_mbx, cmd);
|
||||
}
|
||||
|
||||
void StopVAGStream(VagDirEntry* vag, u32 priority) {
|
||||
auto cmd = GetVAGCommand();
|
||||
cmd->cmd_id = STOP_VAG_STREAM;
|
||||
cmd->messagebox_to_reply = 0;
|
||||
cmd->thread_id = 0;
|
||||
cmd->vag = vag;
|
||||
cmd->priority = priority;
|
||||
|
||||
SendMbx(iso_mbx, cmd);
|
||||
}
|
||||
|
||||
void PauseVAGStream() {
|
||||
auto cmd = GetVAGCommand();
|
||||
cmd->cmd_id = 1027;
|
||||
cmd->messagebox_to_reply = 0;
|
||||
cmd->thread_id = 0;
|
||||
SendMbx(iso_mbx, cmd);
|
||||
}
|
||||
|
||||
void UnpauseVAGStream() {
|
||||
auto cmd = GetVAGCommand();
|
||||
cmd->cmd_id = 1028;
|
||||
cmd->messagebox_to_reply = 0;
|
||||
cmd->thread_id = 0;
|
||||
SendMbx(iso_mbx, cmd);
|
||||
}
|
||||
|
@ -3,9 +3,23 @@
|
||||
#include "isocommon.h"
|
||||
|
||||
struct SoundBank;
|
||||
struct VagDirEntry;
|
||||
|
||||
s32 LoadISOFileToIOP(FileRecord* file, void* addr, uint32_t length);
|
||||
s32 LoadISOFileToEE(FileRecord* file, uint32_t ee_addr, uint32_t length);
|
||||
s32 LoadISOFileChunkToEE(FileRecord* file, uint32_t dest_addr, uint32_t length, uint32_t offset);
|
||||
void LoadSoundBank(const char* bank_name, SoundBank* bank);
|
||||
void LoadMusic(const char* music_name, s32* bank);
|
||||
|
||||
void QueueVAGStream(FileRecord* file, VagDirEntry* vag, u32 sound_id, u32 unk);
|
||||
void PlayVAGStream(FileRecord* file,
|
||||
VagDirEntry* vag,
|
||||
u32 sound_id,
|
||||
s32 volume,
|
||||
u32 unk,
|
||||
Vec3w* trans);
|
||||
void SetVAGStreamVolume(s32 volume);
|
||||
void SetDialogVolume(s32 volume);
|
||||
void StopVAGStream(VagDirEntry* vag, u32 unk);
|
||||
void PauseVAGStream();
|
||||
void UnpauseVAGStream();
|
||||
|
@ -35,9 +35,6 @@ VagCommand vag_cmds[N_VAG_CMDS];
|
||||
|
||||
static s32 sSema;
|
||||
|
||||
void ReleaseMessage(IsoMessage* cmd);
|
||||
void FreeVAGCommand(VagCommand* cmd);
|
||||
|
||||
void iso_queue_init_globals() {
|
||||
memset(sBuffer, 0, sizeof(sBuffer));
|
||||
memset(sStrBuffer, 0, sizeof(sStrBuffer));
|
||||
@ -260,41 +257,30 @@ IsoMessage* GetMessage() {
|
||||
* Execute callbacks and maintain buffers for finished reads in the priority stack
|
||||
*/
|
||||
void ProcessMessageData() {
|
||||
int32_t pri = N_PRIORITIES - 1;
|
||||
for (s32 pri = N_PRIORITIES - 1; pri >= 0; pri--) {
|
||||
for (s32 n = gPriStack[pri].n - 1; n >= 0; n--) {
|
||||
IsoMessage* cmd = gPriStack[pri].cmds[n];
|
||||
|
||||
for (;;) {
|
||||
if (pri < 0)
|
||||
return;
|
||||
int32_t cmdID = gPriStack[pri].n;
|
||||
IsoMessage* popped_command;
|
||||
do {
|
||||
cmdID--;
|
||||
if (cmdID < 0)
|
||||
goto end_cur;
|
||||
popped_command = gPriStack[pri].cmds[cmdID];
|
||||
auto* callback_buffer = popped_command->callback_buffer;
|
||||
if (popped_command->status == CMD_STATUS_IN_PROGRESS &&
|
||||
callback_buffer) { // if we have a callback buffer (meaning a read finished and let us
|
||||
// know)
|
||||
// execute the callback!
|
||||
uint32_t callback_result =
|
||||
popped_command->callback_function(popped_command, callback_buffer);
|
||||
popped_command->status = callback_result;
|
||||
// printf("ProcessMessage Data set command %p status to %d\n", popped_command,
|
||||
// popped_command->status);
|
||||
// if we're done with the buffer, free it and load the next one (if there is one)
|
||||
if (callback_buffer->data_size == 0) {
|
||||
popped_command->callback_buffer = (IsoBufferHeader*)callback_buffer->next;
|
||||
FreeBuffer(callback_buffer);
|
||||
if (cmd->status == CMD_STATUS_IN_PROGRESS) {
|
||||
IsoBufferHeader* callback_buffer = cmd->callback_buffer;
|
||||
|
||||
if (callback_buffer != nullptr) {
|
||||
cmd->status = cmd->callback_function(cmd, callback_buffer);
|
||||
|
||||
if (callback_buffer->data_size == 0) {
|
||||
cmd->callback_buffer = (IsoBufferHeader*)callback_buffer->next;
|
||||
FreeBuffer(callback_buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (popped_command->status == CMD_STATUS_IN_PROGRESS);
|
||||
ReleaseMessage(popped_command);
|
||||
ReturnMessage(popped_command);
|
||||
// return message todo this will free vag commands!
|
||||
pri++;
|
||||
end_cur:
|
||||
pri--;
|
||||
|
||||
if (cmd->status != CMD_STATUS_IN_PROGRESS) {
|
||||
ReleaseMessage(cmd);
|
||||
ReturnMessage(cmd);
|
||||
pri++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -342,8 +328,9 @@ VagCommand* GetVAGCommand() {
|
||||
}
|
||||
|
||||
// wait for VAG semaphore
|
||||
while (WaitSema(sSema)) {
|
||||
}
|
||||
// while (WaitSema(sSema)) {
|
||||
//}
|
||||
|
||||
// try to get something.
|
||||
for (s32 i = 0; i < N_VAG_CMDS; i++) {
|
||||
if (!((vag_cmd_used >> (i & 0x1f)) & 1)) {
|
||||
@ -353,24 +340,24 @@ VagCommand* GetVAGCommand() {
|
||||
if (vag_cmd_cnt > max_vag_cmd_cnt) {
|
||||
max_vag_cmd_cnt = vag_cmd_cnt;
|
||||
}
|
||||
SignalSema(sSema);
|
||||
// SignalSema(sSema);
|
||||
return &vag_cmds[i];
|
||||
}
|
||||
}
|
||||
|
||||
SignalSema(sSema);
|
||||
// SignalSema(sSema);
|
||||
}
|
||||
}
|
||||
|
||||
void FreeVAGCommand(VagCommand* cmd) {
|
||||
s32 idx = cmd - vag_cmds;
|
||||
if (idx >= 0 && idx < N_VAG_CMDS && ((vag_cmd_used >> (idx & 0x1f)) & 1)) {
|
||||
while (WaitSema(sSema)) {
|
||||
}
|
||||
// while (WaitSema(sSema)) {
|
||||
// }
|
||||
|
||||
vag_cmd_used &= ~(1 << (idx & 0x1f));
|
||||
vag_cmd_cnt--;
|
||||
SignalSema(sSema);
|
||||
// SignalSema(sSema);
|
||||
} else {
|
||||
printf("[OVERLORD] Invalid FreeVAGCommand!\n");
|
||||
}
|
||||
|
@ -13,3 +13,7 @@ IsoMessage* GetMessage();
|
||||
void ProcessMessageData();
|
||||
void ReturnMessage(IsoMessage* cmd);
|
||||
IsoBufferHeader* TryAllocateBuffer(uint32_t size);
|
||||
|
||||
VagCommand* GetVAGCommand();
|
||||
void FreeVAGCommand(VagCommand* cmd);
|
||||
void ReleaseMessage(IsoMessage* cmd);
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "common/common_types.h"
|
||||
#include "common/link_types.h"
|
||||
#include "game/common/overlord_common.h"
|
||||
#include "game/overlord/ssound.h"
|
||||
|
||||
constexpr int PRI_STACK_LENGTH = 4; // number of queued commands per priority
|
||||
constexpr int N_PRIORITIES = 4; // number of priorities
|
||||
@ -32,6 +33,13 @@ constexpr int LOAD_TO_EE_OFFSET_CMD_ID = 0x102; // command to load file to ee w
|
||||
constexpr int LOAD_DGO_CMD_ID = 0x200; // command to load DGO
|
||||
constexpr int LOAD_SOUND_BANK = 0x300; // Command to load a sound bank
|
||||
constexpr int LOAD_MUSIC = 0x380; // Command to load music
|
||||
constexpr int QUEUE_VAG_STREAM = 0x400; // Command to load a vag stream
|
||||
constexpr int PLAY_VAG_STREAM = 0x401; // Command to play a vag stream
|
||||
constexpr int STOP_VAG_STREAM = 0x402; // Command to stop a vag stream
|
||||
constexpr int PAUSE_VAG_STREAM = 0x403; // Command to pause a vag stream
|
||||
constexpr int CONTINUE_VAG_STREAM = 0x404; // Command to continue a vag stream
|
||||
constexpr int SET_VAG_VOLUME = 0x405; // Command to set the volume of vag playback
|
||||
constexpr int SET_DIALOG_VOLUME = 0x406; // Command to set the volume of vag playback
|
||||
|
||||
constexpr int MAX_ISO_FILES = 350; // maximum files on FS
|
||||
constexpr int MAX_OPEN_FILES = 16; // maximum number of open files at a time.
|
||||
@ -104,19 +112,26 @@ struct IsoCommandLoadSingle : public IsoMessage {
|
||||
s32 bytes_done; // 0x40
|
||||
};
|
||||
|
||||
struct VagDirEntry;
|
||||
/*!
|
||||
* Command to do something.
|
||||
*/
|
||||
struct VagCommand : public IsoMessage {
|
||||
u32 field_0x30;
|
||||
u32 field_0x34;
|
||||
u32 field_0x38;
|
||||
u32 field_0x3c;
|
||||
u32 field_0x40;
|
||||
u32 field_0x44;
|
||||
u32 field_0x48;
|
||||
u32 field_0x4c;
|
||||
// 0x6c max
|
||||
FileRecord* file;
|
||||
VagDirEntry* vag;
|
||||
u32 buffer_number;
|
||||
u32 data_left;
|
||||
u32 started;
|
||||
u32 paused;
|
||||
u32 sample_rate;
|
||||
u32 stop;
|
||||
s32 end_point;
|
||||
u32 unk2;
|
||||
s32 volume;
|
||||
u32 sound_id;
|
||||
u32 priority;
|
||||
u32 positioned;
|
||||
Vec3w trans;
|
||||
};
|
||||
|
||||
struct SoundBank;
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
extern u32 gMemFreeAtStart;
|
||||
|
||||
void ramdisk_init_globals();
|
||||
void InitRamdisk();
|
||||
u32 Thread_Server();
|
||||
|
@ -1,101 +0,0 @@
|
||||
#include "sndshim.h"
|
||||
#include <cstdio>
|
||||
|
||||
void snd_StartSoundSystem() {
|
||||
// printf("snd_StartSoundSystem\n");
|
||||
}
|
||||
void snd_StopSoundSystem() {
|
||||
// printf("snd_StopSoundSystem\n");
|
||||
}
|
||||
void snd_RegisterIOPMemAllocator(AllocFun, FreeFun) {
|
||||
// printf("snd_RegisterIOPMemAllocator\n");
|
||||
}
|
||||
void snd_LockVoiceAllocator(s32) {
|
||||
// printf("snd_LockVoiceAllocator\n");
|
||||
}
|
||||
void snd_UnlockVoiceAllocator() {
|
||||
// printf("snd_UnlockVoiceAllocator\n");
|
||||
}
|
||||
s32 snd_ExternVoiceVoiceAlloc(s32, s32) {
|
||||
// printf("snd_ExternVoiceVoiceAlloc\n");
|
||||
return 0;
|
||||
}
|
||||
u32 snd_SRAMMalloc(u32) {
|
||||
// printf("snd_SRAMMalloc\n");
|
||||
return 0;
|
||||
}
|
||||
void snd_SetMixerMode(s32, s32) {
|
||||
// printf("snd_SetMixerMode\n");
|
||||
}
|
||||
void snd_SetGroupVoiceRange(s32, s32, s32) {
|
||||
// printf("snd_SetGroupVoiceRange\n");
|
||||
}
|
||||
void snd_SetReverbDepth(s32, s32, s32) {
|
||||
// printf("snd_SetReverbDepth\n");
|
||||
}
|
||||
void snd_SetReverbType(s32, s32) {
|
||||
// printf("snd_SetReverbType\n");
|
||||
}
|
||||
void snd_SetPanTable(s16*) {
|
||||
// printf("snd_SetPanTable\n");
|
||||
}
|
||||
void snd_SetPlayBackMode(s32) {
|
||||
// printf("snd_SetPlayBackMode\n");
|
||||
}
|
||||
s32 snd_SoundIsStillPlaying(s32) {
|
||||
// printf("snd_SoundIsStillPlaying\n");
|
||||
return 0;
|
||||
}
|
||||
void snd_StopSound(s32) {
|
||||
// printf("snd_StopSound\n");
|
||||
}
|
||||
void snd_SetSoundVolPan(s32, s32, s32) {
|
||||
// printf("snd_SetSoundVolPan\n");
|
||||
}
|
||||
void snd_SetMasterVolume(s32, s32) {
|
||||
// printf("snd_SetMasterVolume\n");
|
||||
}
|
||||
void snd_UnloadBank(s32) {
|
||||
// printf("snd_UnloadBank\n");
|
||||
}
|
||||
void snd_ResolveBankXREFS() {
|
||||
// printf("snd_ResolveBankXREFS\n");
|
||||
}
|
||||
void snd_ContinueAllSoundsInGroup(u8) {
|
||||
// printf("snd_ContinueAllSoundsInGroup\n");
|
||||
}
|
||||
void snd_PauseAllSoundsInGroup(u8) {
|
||||
// printf("snd_PauseAllSoundsInGroup\n");
|
||||
}
|
||||
|
||||
void snd_SetMIDIRegister(s32, u8, u8) {
|
||||
// printf("snd_SetMIDIRegister\n");
|
||||
}
|
||||
|
||||
s32 snd_PlaySoundVolPanPMPB(s32, s32, s32, s32, s32, s32) {
|
||||
// printf("snd_PlaySoundVolPanPMPB\n");
|
||||
return 0;
|
||||
}
|
||||
void snd_SetSoundPitchModifier(s32, s32) {
|
||||
// printf("snd_SetSoundPitchModifier\n");
|
||||
}
|
||||
void snd_SetSoundPitchBend(s32, s32) {
|
||||
// printf("snd_SetSoundPitchBend\n");
|
||||
}
|
||||
void snd_PauseSound(s32) {
|
||||
// printf("snd_PauseSound\n");
|
||||
}
|
||||
void snd_ContinueSound(s32) {
|
||||
// printf("snd_ContinueSound\n");
|
||||
}
|
||||
void snd_AutoPitch(s32, s32, s32, s32) {
|
||||
// printf("snd_AutoPitch\n");
|
||||
}
|
||||
void snd_AutoPitchBend(s32, s32, s32, s32) {
|
||||
// printf("snd_AutoPitchBend\n");
|
||||
}
|
||||
|
||||
s32 snd_BankLoadEx(const char*, s32, s32, s32) {
|
||||
// printf("snd_BankLoadEx\n");
|
||||
return 0;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include "game/overlord/sndshim.h"
|
||||
#include "game/sound/sndshim.h"
|
||||
#include "srpc.h"
|
||||
#include "game/sce/iop.h"
|
||||
#include "game/common/loader_rpc_types.h"
|
||||
@ -11,6 +11,8 @@
|
||||
#include "iso_api.h"
|
||||
#include "common/util/Assert.h"
|
||||
#include "third-party/fmt/core.h"
|
||||
#include "iso.h"
|
||||
#include "ramdisk.h"
|
||||
|
||||
using namespace iop;
|
||||
|
||||
@ -25,6 +27,9 @@ static s32 gMusic;
|
||||
s32 gMusicTweak = 0x80;
|
||||
s32 gMusicPause = 0;
|
||||
u32 gFreeMem = 0;
|
||||
u32 gFrameNum = 0;
|
||||
|
||||
static SoundIopInfo info;
|
||||
|
||||
s32 gVAG_Id = 0; // TODO probably doesn't belong here.
|
||||
|
||||
@ -125,8 +130,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO vagfile = FindVAGFile(namebuf);
|
||||
void* vagfile = nullptr;
|
||||
auto vagfile = FindVAGFile(namebuf);
|
||||
|
||||
memcpy(namebuf, "VAGWAD ", 8);
|
||||
strcpy(&namebuf[8], gLanguage);
|
||||
@ -134,10 +138,10 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) {
|
||||
FileRecord* rec = isofs->find_in(namebuf);
|
||||
if (vagfile != nullptr) {
|
||||
if (cmd->play.parms.pitch_mod) { // ??? TODO Verify what is being checked here
|
||||
// PlayVagStream(rec, vagfile, cmd->play.sound_id, cmd->play.parms.volume, 0,
|
||||
// cmd->play.parms.trans);
|
||||
PlayVAGStream(rec, vagfile, cmd->play.sound_id, cmd->play.parms.volume, 0,
|
||||
&cmd->play.parms.trans);
|
||||
} else {
|
||||
// PlayVagStream(rec, vagfile, cmd->play.sound_id, cmd->play.parms.volume, 0, 0);
|
||||
PlayVAGStream(rec, vagfile, cmd->play.sound_id, cmd->play.parms.volume, 0, nullptr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -201,7 +205,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) {
|
||||
if (sound != nullptr) {
|
||||
snd_PauseSound(sound->sound_handle);
|
||||
} else if (cmd->sound_id.sound_id == gVAG_Id) {
|
||||
// TODO PauseVAGStream();
|
||||
PauseVAGStream();
|
||||
}
|
||||
} break;
|
||||
case SoundCommand::STOP_SOUND: {
|
||||
@ -209,7 +213,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) {
|
||||
if (sound != nullptr) {
|
||||
snd_StopSound(sound->sound_handle);
|
||||
} else if (cmd->sound_id.sound_id == gVAG_Id) {
|
||||
// TODO StopVAGStream();
|
||||
StopVAGStream(nullptr, 0);
|
||||
}
|
||||
} break;
|
||||
case SoundCommand::CONTINUE_SOUND: {
|
||||
@ -217,7 +221,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) {
|
||||
if (sound != nullptr) {
|
||||
snd_ContinueSound(sound->sound_handle);
|
||||
} else if (cmd->sound_id.sound_id == gVAG_Id) {
|
||||
// TODO UNpauseVAGStream();
|
||||
UnpauseVAGStream();
|
||||
}
|
||||
} break;
|
||||
case SoundCommand::SET_PARAM: {
|
||||
@ -258,7 +262,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) {
|
||||
}
|
||||
|
||||
} else if (cmd->sound_id.sound_id == gVAG_Id) {
|
||||
// TODO SetVAGStreamVolume();
|
||||
SetVAGStreamVolume(cmd->param.parms.volume);
|
||||
}
|
||||
} break;
|
||||
case SoundCommand::SET_MASTER_VOLUME: {
|
||||
@ -268,7 +272,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) {
|
||||
if (i == 1) {
|
||||
gMusicVol = cmd->master_volume.volume;
|
||||
} else if (i == 2) {
|
||||
// TODO SetDialogVolume(cmd->master_volume.volume);
|
||||
SetDialogVolume(cmd->master_volume.volume);
|
||||
} else {
|
||||
snd_SetMasterVolume(i, cmd->master_volume.volume);
|
||||
}
|
||||
@ -278,7 +282,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) {
|
||||
case SoundCommand::PAUSE_GROUP: {
|
||||
snd_PauseAllSoundsInGroup(cmd->group.group);
|
||||
if ((cmd->group.group & 4) != 0) {
|
||||
// TODO PauseVAGStream(0,0);
|
||||
PauseVAGStream();
|
||||
}
|
||||
if (cmd->group.group & 2) {
|
||||
gMusicPause = 1;
|
||||
@ -288,13 +292,13 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) {
|
||||
u8 group = cmd->group.group;
|
||||
KillSoundsInGroup(group);
|
||||
if ((group & 4) != 0) {
|
||||
// TODO StopVAGStream(0,0);
|
||||
StopVAGStream(nullptr, 0);
|
||||
}
|
||||
} break;
|
||||
case SoundCommand::CONTINUE_GROUP: {
|
||||
snd_ContinueAllSoundsInGroup(cmd->group.group);
|
||||
if (cmd->group.group & 4) {
|
||||
// UnpauseVAGStream();
|
||||
UnpauseVAGStream();
|
||||
}
|
||||
|
||||
if (cmd->group.group & 2) {
|
||||
@ -421,6 +425,8 @@ void* RPC_Loader(unsigned int /*fno*/, void* data, int size) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static s32 dmaid = 0;
|
||||
|
||||
s32 VBlank_Handler() {
|
||||
if (!gSoundEnable)
|
||||
return 1;
|
||||
@ -439,5 +445,51 @@ s32 VBlank_Handler() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!gInfoEE)
|
||||
return 1;
|
||||
|
||||
gFrameNum++;
|
||||
|
||||
if (gFakeVAGClockRunning && !gFakeVAGClockPaused) {
|
||||
gFakeVAGClock += 17;
|
||||
}
|
||||
|
||||
// We don't need this, our DMA's are instant
|
||||
// if (dmaid) {
|
||||
// if (sceSifDmaStat(dmaid) >= 0) {
|
||||
// return 1;
|
||||
// }
|
||||
// dmaid = 0;
|
||||
//}
|
||||
|
||||
info.frame = gFrameNum;
|
||||
info.strpos = GetVAGStreamPos();
|
||||
info.std_id = gVAG_Id;
|
||||
info.freemem = gFreeMem;
|
||||
info.freemem2 = gMemFreeAtStart;
|
||||
// info.nocd = gNoCD;
|
||||
// info.dirtycd = gDirtyCD;
|
||||
info.nocd = 0;
|
||||
info.dirtycd = 0;
|
||||
// info.diskspeed[0] = gDiskSpeed[0];
|
||||
// info.diskspeed[1] = gDiskSpeed[1];
|
||||
// info.lastspeed = gLastSpeed;
|
||||
// info.dupseg = gDupSeg;
|
||||
|
||||
for (int i = 0; i < 48; i++) {
|
||||
if (snd_GetVoiceStatus(i) == 1) {
|
||||
info.chinfo[i] = -1;
|
||||
} else {
|
||||
info.chinfo[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
sceSifDmaData dma;
|
||||
dma.data = &info;
|
||||
dma.addr = (void*)gInfoEE;
|
||||
dma.size = 0x110;
|
||||
dma.mode = 0;
|
||||
dmaid = sceSifSetDma(&dma, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -5,6 +5,9 @@
|
||||
|
||||
void srpc_init_globals();
|
||||
|
||||
extern const char* gLanguage;
|
||||
extern s32 gVAG_Id;
|
||||
|
||||
constexpr int MUSIC_TWEAK_COUNT = 32;
|
||||
|
||||
struct MusicTweaks {
|
||||
@ -143,6 +146,23 @@ struct SoundRpcCommand {
|
||||
|
||||
static_assert(sizeof(SoundRpcCommand) == 0x50);
|
||||
|
||||
struct SoundIopInfo {
|
||||
u32 frame;
|
||||
s32 strpos;
|
||||
u32 std_id;
|
||||
u32 freemem;
|
||||
u8 chinfo[48];
|
||||
u32 freemem2;
|
||||
u32 nocd;
|
||||
u32 dirtycd;
|
||||
u32 diskspeed[2];
|
||||
u32 lastspeed;
|
||||
s32 dupseg;
|
||||
u32 times[41];
|
||||
u32 times_seq;
|
||||
u8 pad[10]; // pad up to transfer size
|
||||
};
|
||||
|
||||
extern MusicTweaks gMusicTweakInfo;
|
||||
extern s32 gMusicTweak;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "game/overlord/srpc.h"
|
||||
#include "ssound.h"
|
||||
#include "common/util/Assert.h"
|
||||
#include "sndshim.h"
|
||||
#include "game/sound/sndshim.h"
|
||||
|
||||
using namespace iop;
|
||||
|
||||
@ -19,8 +19,9 @@ s32 gMusicVol = 0x400;
|
||||
s32 gMusicFade = 0;
|
||||
s32 gMusicFadeDir = 0;
|
||||
|
||||
u32 gVoice;
|
||||
u32 gStreamSRAM;
|
||||
u32 gStreamSRAM = 0;
|
||||
u32 gTrapSRAM = 0;
|
||||
|
||||
s32 gSema;
|
||||
|
||||
static u32 sLastTick;
|
||||
@ -87,10 +88,12 @@ void InitSound_Overlord() {
|
||||
// The voice allocator returns a number in the range 0-47 where voices
|
||||
// 0-23 are on SPU Core 0 and 24-47 are on core 2.
|
||||
// For some reason we convert it to this format where 0-47 alternate core every step.
|
||||
gVoice = voice / 24 + ((voice % 24) * 2);
|
||||
voice = voice / 24 + ((voice % 24) * 2);
|
||||
|
||||
// Allocate SPU RAM for our streams.
|
||||
// (Which we don't need on PC)
|
||||
gStreamSRAM = snd_SRAMMalloc(0xc030);
|
||||
gTrapSRAM = gStreamSRAM + 0xC000;
|
||||
|
||||
snd_SetMixerMode(0, 0);
|
||||
|
||||
@ -100,9 +103,10 @@ void InitSound_Overlord() {
|
||||
|
||||
snd_SetGroupVoiceRange(1, 0, 0xf);
|
||||
snd_SetGroupVoiceRange(2, 0, 0xf);
|
||||
snd_SetReverbDepth(3, 0, 0);
|
||||
snd_SetReverbType(1, 0);
|
||||
snd_SetReverbType(2, 0);
|
||||
|
||||
snd_SetReverbDepth(SND_CORE_0 | SND_CORE_1, 0, 0);
|
||||
snd_SetReverbType(SND_CORE_0, SD_REV_MODE_OFF);
|
||||
snd_SetReverbType(SND_CORE_1, SD_REV_MODE_OFF);
|
||||
|
||||
CatalogSRAM();
|
||||
|
||||
@ -432,8 +436,8 @@ void UpdateVolume(Sound* sound) {
|
||||
}
|
||||
|
||||
void SetEarTrans(Vec3w* ear_trans, Vec3w* cam_trans, s32 cam_angle) {
|
||||
s32 tick = 0; // snd_GetTick();
|
||||
s32 delta = tick - sLastTick;
|
||||
s32 tick = snd_GetTick();
|
||||
u32 delta = tick - sLastTick;
|
||||
sLastTick = tick;
|
||||
|
||||
gEarTrans = *ear_trans;
|
||||
|
@ -5,12 +5,19 @@
|
||||
#include "game/sce/iop.h"
|
||||
#include "sbank.h"
|
||||
|
||||
struct VolumePair {
|
||||
s16 left;
|
||||
s16 right;
|
||||
};
|
||||
|
||||
extern s32 gSema;
|
||||
extern s32 gMusicFade;
|
||||
extern s32 gMusicFadeDir;
|
||||
extern s32 gMusicVol;
|
||||
extern VolumePair gPanTable[361];
|
||||
extern u32 gStreamSRAM;
|
||||
extern u32 gTrapSRAM;
|
||||
|
||||
// FIXME where to put this
|
||||
struct Vec3w {
|
||||
s32 x;
|
||||
s32 y;
|
||||
@ -47,11 +54,6 @@ struct Curve {
|
||||
s32 unk4;
|
||||
};
|
||||
|
||||
struct VolumePair {
|
||||
s16 left;
|
||||
s16 right;
|
||||
};
|
||||
|
||||
void InitSound_Overlord();
|
||||
void SetCurve(s32 curve, s32 fallof, s32 ease);
|
||||
void SetEarTrans(Vec3w* ear_trans, Vec3w* cam_trans, s32 cam_angle);
|
||||
@ -63,5 +65,7 @@ Sound* AllocateSound();
|
||||
void UpdateVolume(Sound* sound);
|
||||
s32 GetVolume(Sound* sound);
|
||||
s32 GetPan(Sound* sound);
|
||||
s32 CalculateFallofVolume(Vec3w* pos, s32 volume, s32 fo_curve, s32 fo_min, s32 fo_max);
|
||||
s32 CalculateAngle(Vec3w* trans);
|
||||
|
||||
#endif // JAK_V2_SSOUND_H
|
||||
|
@ -11,15 +11,21 @@
|
||||
#include "game/common/play_rpc_types.h"
|
||||
#include "game/overlord/isocommon.h"
|
||||
#include "game/overlord/iso_api.h"
|
||||
#include "game/overlord/iso.h"
|
||||
#include "game/overlord/srpc.h"
|
||||
#include "common/util/Assert.h"
|
||||
|
||||
using namespace iop;
|
||||
|
||||
static RPC_Str_Cmd sSTRBuf;
|
||||
static RPC_Play_Cmd sPLAYBuf; // todo type
|
||||
static RPC_Play_Cmd sPLAYBuf[2]; // todo type
|
||||
void* RPC_STR(unsigned int fno, void* _cmd, int y);
|
||||
void* RPC_PLAY(unsigned int fno, void* _cmd, int y);
|
||||
|
||||
static constexpr int PLAY_MSG_SIZE = 0x40;
|
||||
|
||||
static u32 global_vag_count = 0;
|
||||
|
||||
/*!
|
||||
* We cache the chunk file headers so we can avoid seeking to the chunk header each time we
|
||||
* need to load another chunk, even if we load chunks out of order.
|
||||
@ -65,7 +71,7 @@ u32 PLAYThread() {
|
||||
CpuDisableIntr();
|
||||
sceSifInitRpc(0);
|
||||
sceSifSetRpcQueue(&dq, GetThreadId());
|
||||
sceSifRegisterRpc(&serve, PLAY_RPC_ID, RPC_PLAY, &sPLAYBuf, nullptr, nullptr, &dq);
|
||||
sceSifRegisterRpc(&serve, PLAY_RPC_ID, RPC_PLAY, sPLAYBuf, nullptr, nullptr, &dq);
|
||||
CpuEnableIntr();
|
||||
sceSifRpcLoop(&dq);
|
||||
return 0;
|
||||
@ -148,12 +154,63 @@ void* RPC_STR(unsigned int fno, void* _cmd, int y) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void* RPC_PLAY(unsigned int fno, void* _cmd, int y) {
|
||||
(void)fno;
|
||||
(void)y;
|
||||
// printf("[RPC_PLAY] ignoring...\n");
|
||||
void* RPC_PLAY([[maybe_unused]] unsigned int fno, void* _cmd, int size) {
|
||||
s32 n_messages = size / PLAY_MSG_SIZE;
|
||||
char namebuf[16];
|
||||
|
||||
auto* cmd = (RPC_Play_Cmd*)(_cmd);
|
||||
while (n_messages > 0) {
|
||||
if (cmd->name[0] == '$') {
|
||||
char* name_part = &cmd->name[1];
|
||||
size_t name_len = strlen(name_part);
|
||||
|
||||
if (name_len < 9) {
|
||||
memset(namebuf, ' ', 8);
|
||||
memcpy(namebuf, name_part, name_len);
|
||||
} else {
|
||||
memcpy(namebuf, name_part, 8);
|
||||
}
|
||||
|
||||
// ASCII toupper
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (namebuf[i] >= 0x61 && namebuf[i] < 0x7b) {
|
||||
namebuf[i] -= 0x20;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ISONameFromAnimationName(namebuf, cmd->name);
|
||||
}
|
||||
|
||||
auto vag = FindVAGFile(namebuf);
|
||||
memcpy(namebuf, "VAGWAD ", 8);
|
||||
strcpy(&namebuf[8], gLanguage);
|
||||
|
||||
FileRecord* file = nullptr;
|
||||
|
||||
global_vag_count = (global_vag_count + 1) & 0x3f;
|
||||
if (!cmd->result && global_vag_count == 0) {
|
||||
namebuf[0] -= 3;
|
||||
file = isofs->find_in(namebuf);
|
||||
namebuf[0] += 3;
|
||||
}
|
||||
|
||||
file = isofs->find_in(namebuf);
|
||||
|
||||
if (cmd->result == 0) {
|
||||
PlayVAGStream(file, vag, cmd->address, 0x400, 1, nullptr);
|
||||
} else if (cmd->result == 1) {
|
||||
StopVAGStream(vag, 1);
|
||||
} else {
|
||||
QueueVAGStream(file, vag, 0, 1);
|
||||
}
|
||||
|
||||
n_messages--;
|
||||
cmd++;
|
||||
}
|
||||
|
||||
return _cmd;
|
||||
}
|
||||
|
@ -22,7 +22,9 @@
|
||||
|
||||
#define SCECdComplete 0x02
|
||||
#define SCECdNotReady 0x06
|
||||
#define KE_OK 0
|
||||
#define KE_MBOX_NOMSG -424
|
||||
#define KE_WAIT_DELETE -425
|
||||
|
||||
#define TH_C 0x02000000
|
||||
|
||||
|
315
game/sound/989snd/ame_handler.cpp
Normal file
315
game/sound/989snd/ame_handler.cpp
Normal file
@ -0,0 +1,315 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#include "ame_handler.h"
|
||||
#include "game/sound/989snd/blocksound_handler.h"
|
||||
|
||||
namespace snd {
|
||||
|
||||
ame_handler::ame_handler(MultiMIDIBlockHeader* block,
|
||||
voice_manager& vm,
|
||||
MIDISound& sound,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
locator& loc,
|
||||
u32 bank)
|
||||
: m_sound(sound),
|
||||
m_bank(bank),
|
||||
m_header(block),
|
||||
m_locator(loc),
|
||||
m_vm(vm),
|
||||
m_repeats(sound.Repeats) {
|
||||
if (vol == VOLUME_DONT_CHANGE) {
|
||||
vol = 1024;
|
||||
}
|
||||
|
||||
m_vol = (vol * m_sound.Vol) >> 10;
|
||||
|
||||
if (m_vol >= 128) {
|
||||
m_vol = 127;
|
||||
}
|
||||
|
||||
if (pan == PAN_DONT_CHANGE || pan == PAN_RESET) {
|
||||
m_pan = m_sound.Pan;
|
||||
} else {
|
||||
m_pan = pan;
|
||||
}
|
||||
|
||||
start_segment(0);
|
||||
};
|
||||
|
||||
bool ame_handler::tick() {
|
||||
for (auto it = m_midis.begin(); it != m_midis.end();) {
|
||||
bool done = it->second->tick();
|
||||
if (done) {
|
||||
it = m_midis.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
return m_midis.empty();
|
||||
};
|
||||
|
||||
void ame_handler::start_segment(u32 id) {
|
||||
auto midiblock = (MIDIBlockHeader*)(m_header->BlockPtr[id] + (uintptr_t)m_header);
|
||||
fmt::print("starting segment {}\n", id);
|
||||
m_midis.emplace(id, std::make_unique<midi_handler>(midiblock, m_vm, m_sound, m_vol, m_pan,
|
||||
m_locator, m_bank, this));
|
||||
}
|
||||
|
||||
void ame_handler::stop() {
|
||||
for (auto it = m_midis.begin(); it != m_midis.end();) {
|
||||
it->second->stop();
|
||||
it = m_midis.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void ame_handler::stop_segment(u32 id) {
|
||||
auto m = m_midis.find(id);
|
||||
if (m == m_midis.end())
|
||||
return;
|
||||
|
||||
m->second->stop();
|
||||
m_midis.erase(id);
|
||||
}
|
||||
|
||||
void ame_handler::pause() {
|
||||
for (auto& m : m_midis) {
|
||||
m.second->pause();
|
||||
}
|
||||
}
|
||||
|
||||
void ame_handler::unpause() {
|
||||
for (auto& m : m_midis) {
|
||||
m.second->unpause();
|
||||
}
|
||||
}
|
||||
|
||||
void ame_handler::set_vol_pan(s32 vol, s32 pan) {
|
||||
if (vol >= 0) {
|
||||
if (vol != VOLUME_DONT_CHANGE) {
|
||||
m_vol = (m_sound.Vol * vol) >> 10;
|
||||
}
|
||||
} else {
|
||||
m_vol = -vol;
|
||||
}
|
||||
|
||||
if (m_vol >= 128) {
|
||||
m_vol = 127;
|
||||
}
|
||||
|
||||
if (pan == PAN_RESET) {
|
||||
m_pan = m_sound.Pan;
|
||||
} else if (pan != PAN_DONT_CHANGE) {
|
||||
m_pan = pan;
|
||||
}
|
||||
|
||||
for (auto& m : m_midis) {
|
||||
m.second->set_vol_pan(vol, pan);
|
||||
}
|
||||
}
|
||||
|
||||
void ame_handler::set_pmod(s32 mod) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
#define AME_BEGIN(op) \
|
||||
if (skip) { \
|
||||
if (skip == 1) { \
|
||||
skip = 0; \
|
||||
} \
|
||||
} else \
|
||||
do {
|
||||
#define AME_END(x) \
|
||||
} \
|
||||
while (0) \
|
||||
; \
|
||||
stream += (x);
|
||||
|
||||
std::pair<bool, u8*> ame_handler::run_ame(midi_handler& midi, u8* stream) {
|
||||
int skip = 0;
|
||||
bool done = false;
|
||||
bool cont = true;
|
||||
|
||||
while (!done) {
|
||||
auto op = static_cast<u8>(*stream++);
|
||||
switch (op) {
|
||||
case 0x0: {
|
||||
AME_BEGIN(op)
|
||||
if (m_excite <= (stream[0] + 1)) {
|
||||
skip = 1;
|
||||
}
|
||||
AME_END(1)
|
||||
} break;
|
||||
case 0x1: {
|
||||
AME_BEGIN(op)
|
||||
if (m_excite != (stream[0] + 1)) {
|
||||
skip = 1;
|
||||
}
|
||||
AME_END(1)
|
||||
} break;
|
||||
case 0x2: {
|
||||
AME_BEGIN(op)
|
||||
if (m_excite > (stream[0] + 1)) {
|
||||
skip = 1;
|
||||
}
|
||||
AME_END(1)
|
||||
} break;
|
||||
case 0x3: {
|
||||
AME_BEGIN(op)
|
||||
stop_segment(stream[0]);
|
||||
AME_END(1)
|
||||
} break;
|
||||
case 0x4: {
|
||||
// fmt::print("ame trace 4\n");
|
||||
if (skip == 1) {
|
||||
skip = 2;
|
||||
}
|
||||
} break;
|
||||
case 0x5: {
|
||||
// fmt::print("ame trace 5\n");
|
||||
if (skip == 2) {
|
||||
skip = 0;
|
||||
}
|
||||
} break;
|
||||
case 0x6: {
|
||||
AME_BEGIN(op)
|
||||
if (m_register[stream[0]] > (stream[1] - 1)) {
|
||||
skip = 1;
|
||||
}
|
||||
AME_END(2)
|
||||
} break;
|
||||
case 0x7: {
|
||||
AME_BEGIN(op)
|
||||
if (m_register[stream[0]] < (stream[1] + 1)) {
|
||||
skip = 1;
|
||||
}
|
||||
AME_END(2)
|
||||
} break;
|
||||
case 0xB: {
|
||||
// fmt::print("ame trace b\n");
|
||||
m_macro[stream[0]] = &stream[1];
|
||||
while (*stream != 0xf7) {
|
||||
stream++;
|
||||
}
|
||||
stream++;
|
||||
} break;
|
||||
case 0xc: {
|
||||
AME_BEGIN(op)
|
||||
auto [sub_cont, ptr] = run_ame(midi, m_macro[stream[0]]);
|
||||
if (!sub_cont) {
|
||||
cont = false;
|
||||
done = true;
|
||||
}
|
||||
AME_END(1)
|
||||
} break;
|
||||
case 0xd: {
|
||||
AME_BEGIN(op)
|
||||
cont = false;
|
||||
done = true;
|
||||
start_segment(m_register[stream[0] - 1]);
|
||||
AME_END(1)
|
||||
} break;
|
||||
case 0xe: {
|
||||
AME_BEGIN(op)
|
||||
start_segment(m_register[stream[0] - 1]);
|
||||
AME_END(1)
|
||||
} break;
|
||||
case 0xf: {
|
||||
// fmt::print("ame trace f\n");
|
||||
if (skip) {
|
||||
while (*stream != 0x7f) {
|
||||
stream++;
|
||||
}
|
||||
stream++;
|
||||
if (skip == 1)
|
||||
skip = 0;
|
||||
} else {
|
||||
auto group = *stream++;
|
||||
m_groups[group].basis = *stream++;
|
||||
u8 channel = 0;
|
||||
while (*stream != 0xf7) {
|
||||
m_groups[group].channel[channel] = *stream++;
|
||||
m_groups[group].excite_min[channel] = *stream++;
|
||||
m_groups[group].excite_max[channel] = *stream++;
|
||||
channel++;
|
||||
}
|
||||
m_groups[group].num_channels = channel;
|
||||
stream++;
|
||||
}
|
||||
} break;
|
||||
case 0x10: {
|
||||
AME_BEGIN(op)
|
||||
u8 group = stream[0];
|
||||
u8 comp = 0;
|
||||
if (m_groups[group].basis == 0) {
|
||||
comp = m_excite;
|
||||
} else {
|
||||
comp = m_register[m_groups[group].basis - 1];
|
||||
}
|
||||
for (int i = 0; i < m_groups[group].num_channels; i++) {
|
||||
if ((m_groups[group].excite_min[i] - 1 >= comp) ||
|
||||
(m_groups[group].excite_max[i] + 1 <= comp)) {
|
||||
midi.mute_channel(m_groups[group].channel[i]);
|
||||
} else {
|
||||
midi.unmute_channel(m_groups[group].channel[i]);
|
||||
}
|
||||
}
|
||||
AME_END(1)
|
||||
} break;
|
||||
case 0x11: {
|
||||
AME_BEGIN(op)
|
||||
done = true;
|
||||
cont = false;
|
||||
start_segment(stream[0]);
|
||||
AME_END(1)
|
||||
} break;
|
||||
case 0x12: {
|
||||
AME_BEGIN(op)
|
||||
start_segment(stream[0]);
|
||||
AME_END(1)
|
||||
} break;
|
||||
case 0x13: {
|
||||
AME_BEGIN(op)
|
||||
m_register[stream[0]] = stream[1];
|
||||
AME_END(2)
|
||||
} break;
|
||||
case 0x14: {
|
||||
AME_BEGIN(op)
|
||||
if (m_register[stream[0]] < 0x7f) {
|
||||
m_register[stream[0]]++;
|
||||
}
|
||||
AME_END(1)
|
||||
} break;
|
||||
case 0x15: {
|
||||
AME_BEGIN(op)
|
||||
if (m_register[stream[0]] > 0) {
|
||||
m_register[stream[0]]--;
|
||||
}
|
||||
AME_END(1)
|
||||
} break;
|
||||
case 0x16: {
|
||||
AME_BEGIN(op)
|
||||
if (m_register[stream[0]] != stream[1]) {
|
||||
skip = 1;
|
||||
}
|
||||
AME_END(2)
|
||||
} break;
|
||||
default: {
|
||||
throw ame_error(fmt::format("Unhandled AME event {:02x}", (u8)op));
|
||||
} break;
|
||||
}
|
||||
|
||||
if (*stream == 0xf7) {
|
||||
// fmt::print("ame done\n");
|
||||
stream++;
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
return {cont, stream};
|
||||
}
|
||||
|
||||
} // namespace snd
|
||||
#undef AME_BEGIN
|
||||
#undef AME_END
|
75
game/sound/989snd/ame_handler.h
Normal file
75
game/sound/989snd/ame_handler.h
Normal file
@ -0,0 +1,75 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#pragma once
|
||||
#include "loader.h"
|
||||
#include "midi_handler.h"
|
||||
#include "sound_handler.h"
|
||||
#include "vagvoice.h"
|
||||
#include "common/common_types.h"
|
||||
#include <array>
|
||||
|
||||
namespace snd {
|
||||
|
||||
class midi_handler;
|
||||
class ame_handler : public sound_handler {
|
||||
friend class midi_handler;
|
||||
|
||||
public:
|
||||
ame_handler(MultiMIDIBlockHeader* block,
|
||||
voice_manager& vm,
|
||||
MIDISound& sound,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
locator& loc,
|
||||
u32 bank);
|
||||
bool tick() override;
|
||||
u32 bank() override { return m_bank; };
|
||||
|
||||
void pause() override;
|
||||
void unpause() override;
|
||||
void stop() override;
|
||||
u8 group() override { return m_sound.VolGroup; };
|
||||
void set_vol_pan(s32 vol, s32 pan) override;
|
||||
|
||||
void set_register(u8 reg, u8 value) override { m_register[reg] = value; }
|
||||
void set_pmod(s32 mod) override;
|
||||
|
||||
private:
|
||||
struct ame_error : public std::exception {
|
||||
ame_error(std::string text) : msg(std::move(text)) {}
|
||||
ame_error() : msg("Unknown AME error") {}
|
||||
std::string msg;
|
||||
const char* what() const noexcept override { return msg.c_str(); }
|
||||
};
|
||||
|
||||
struct GroupDescription {
|
||||
/* 0 */ s8 num_channels;
|
||||
/* 1 */ s8 basis;
|
||||
/* 2 */ s8 pad[2];
|
||||
/* 4 */ s8 channel[16];
|
||||
/* 14 */ s8 excite_min[16];
|
||||
/* 24 */ s8 excite_max[16];
|
||||
};
|
||||
|
||||
void start_segment(u32 id);
|
||||
void stop_segment(u32 id);
|
||||
std::pair<bool, u8*> run_ame(midi_handler&, u8* stream);
|
||||
|
||||
MIDISound& m_sound;
|
||||
u32 m_bank{0};
|
||||
|
||||
MultiMIDIBlockHeader* m_header{nullptr};
|
||||
locator& m_locator;
|
||||
voice_manager& m_vm;
|
||||
s32 m_vol{0};
|
||||
s32 m_pan{0};
|
||||
s8 m_repeats{0};
|
||||
|
||||
std::unordered_map<u32, std::unique_ptr<midi_handler>> m_midis;
|
||||
|
||||
u8 m_excite{0};
|
||||
std::array<GroupDescription, 16> m_groups{};
|
||||
std::array<u8, 16> m_register{};
|
||||
std::array<u8*, 16> m_macro{};
|
||||
};
|
||||
} // namespace snd
|
232
game/sound/989snd/blocksound_handler.cpp
Normal file
232
game/sound/989snd/blocksound_handler.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
#include "blocksound_handler.h"
|
||||
#include "util.h"
|
||||
#include <random>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace snd {
|
||||
void blocksound_handler::init() {
|
||||
m_next_grain = 0;
|
||||
m_countdown = m_sfx.grains[0].Delay;
|
||||
|
||||
// if (m_sfx.d.Flags & 2) {
|
||||
// fmt::print("solo flag\n");
|
||||
// m_done = true;
|
||||
// return;
|
||||
// }
|
||||
|
||||
while (m_countdown <= 0 && !m_done) {
|
||||
do_grain();
|
||||
}
|
||||
}
|
||||
|
||||
bool blocksound_handler::tick() {
|
||||
m_voices.remove_if([](std::weak_ptr<vag_voice>& p) { return p.expired(); });
|
||||
|
||||
if (m_done) {
|
||||
if (m_voices.empty()) {
|
||||
// fmt::print("{}: voices empty\n", (void*)this);
|
||||
return m_done;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_paused)
|
||||
return false;
|
||||
|
||||
m_countdown--;
|
||||
while (m_countdown <= 0 && !m_done) {
|
||||
do_grain();
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
void blocksound_handler::pause() {
|
||||
m_paused = true;
|
||||
|
||||
for (auto& p : m_voices) {
|
||||
auto voice = p.lock();
|
||||
if (voice == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_vm.pause(voice);
|
||||
}
|
||||
}
|
||||
|
||||
void blocksound_handler::unpause() {
|
||||
m_paused = false;
|
||||
|
||||
for (auto& p : m_voices) {
|
||||
auto voice = p.lock();
|
||||
if (voice == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_vm.unpause(voice);
|
||||
}
|
||||
}
|
||||
|
||||
void blocksound_handler::stop() {
|
||||
m_done = true;
|
||||
|
||||
for (auto& p : m_voices) {
|
||||
auto voice = p.lock();
|
||||
if (voice == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
voice->key_off();
|
||||
}
|
||||
}
|
||||
|
||||
void blocksound_handler::set_vol_pan(s32 vol, s32 pan) {
|
||||
if (vol >= 0) {
|
||||
if (vol != VOLUME_DONT_CHANGE) {
|
||||
m_app_volume = (vol * m_sfx.d.Vol) >> 10;
|
||||
}
|
||||
} else {
|
||||
m_app_volume = -vol;
|
||||
}
|
||||
|
||||
if (m_app_volume >= 128) {
|
||||
m_app_volume = 127;
|
||||
}
|
||||
|
||||
if (pan == PAN_RESET) {
|
||||
m_app_pan = m_sfx.d.Pan;
|
||||
} else if (pan != PAN_DONT_CHANGE) {
|
||||
m_app_pan = pan;
|
||||
}
|
||||
|
||||
vol = m_app_volume; // + lfo vol
|
||||
// TODO LFO logic here
|
||||
|
||||
pan = m_app_pan; // + lfo pan
|
||||
while (pan >= 360) {
|
||||
pan -= 360;
|
||||
}
|
||||
|
||||
while (pan < 0) {
|
||||
pan += 360;
|
||||
}
|
||||
|
||||
if (pan != m_cur_pan || vol != m_cur_volume) {
|
||||
m_cur_volume = vol;
|
||||
m_cur_pan = pan;
|
||||
|
||||
for (auto& p : m_voices) {
|
||||
auto voice = p.lock();
|
||||
if (voice == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto volume =
|
||||
m_vm.make_volume(127, 0, m_cur_volume, m_cur_pan, voice->tone.Vol, voice->tone.Pan);
|
||||
auto left = m_vm.adjust_vol_to_group(volume.left, m_sfx.d.VolGroup);
|
||||
auto right = m_vm.adjust_vol_to_group(volume.right, m_sfx.d.VolGroup);
|
||||
|
||||
voice->set_volume(left >> 1, right >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void blocksound_handler::update_pitch() {
|
||||
m_cur_pm = m_app_pm;
|
||||
m_cur_pb = m_app_pb;
|
||||
|
||||
for (auto& p : m_voices) {
|
||||
auto voice = p.lock();
|
||||
if (voice == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto note = pitchbend(voice->tone, m_cur_pb, m_cur_pm, m_note, m_fine);
|
||||
auto pitch =
|
||||
PS1Note2Pitch(voice->tone.CenterNote, voice->tone.CenterFine, note.first, note.second);
|
||||
voice->set_pitch(pitch);
|
||||
}
|
||||
}
|
||||
|
||||
void blocksound_handler::set_pmod(s32 mod) {
|
||||
m_app_pm = mod;
|
||||
update_pitch();
|
||||
}
|
||||
|
||||
void blocksound_handler::set_pbend(s32 bend) {
|
||||
m_app_pb = bend;
|
||||
update_pitch();
|
||||
}
|
||||
|
||||
s32 blocksound_handler::null(SFXGrain& grain) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 blocksound_handler::play_tone(SFXGrain& grain) {
|
||||
auto voice = std::make_shared<vag_voice>(grain.GrainParams.tone);
|
||||
|
||||
voice->basevol = m_vm.make_volume(127, 0, m_cur_volume, m_cur_pan, grain.GrainParams.tone.Vol,
|
||||
grain.GrainParams.tone.Pan);
|
||||
|
||||
voice->start_note = m_note;
|
||||
voice->start_fine = m_fine;
|
||||
voice->group = m_group;
|
||||
|
||||
m_vm.start_tone(voice);
|
||||
m_voices.emplace_front(voice);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 blocksound_handler::rand_play(SFXGrain& grain) {
|
||||
int options = grain.GrainParams.control.param[0];
|
||||
int count = grain.GrainParams.control.param[1];
|
||||
int previous = grain.GrainParams.control.param[2];
|
||||
|
||||
int rnd = rand() % options;
|
||||
if (rnd == previous) {
|
||||
rnd++;
|
||||
if (rnd >= options) {
|
||||
rnd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
grain.GrainParams.control.param[2] = rnd;
|
||||
m_next_grain += rnd * count;
|
||||
m_grains_to_play = count + 1;
|
||||
m_grains_to_skip = (options - 1 - rnd) * count;
|
||||
m_skip_grains = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void blocksound_handler::do_grain() {
|
||||
auto& grain = m_sfx.grains[m_next_grain];
|
||||
|
||||
auto handler = m_grain_handler.find((grain_type)grain.Type);
|
||||
if (handler != m_grain_handler.end()) {
|
||||
(this->*(handler->second))(grain);
|
||||
} else {
|
||||
throw std::runtime_error(
|
||||
fmt::format("{}: Ignoring grain {}, type {}\n", (void*)this, m_next_grain, grain.Type));
|
||||
}
|
||||
|
||||
if (m_skip_grains) {
|
||||
m_grains_to_play--;
|
||||
if (m_grains_to_play == 0) {
|
||||
m_next_grain += m_grains_to_skip;
|
||||
m_skip_grains = false;
|
||||
}
|
||||
}
|
||||
|
||||
m_next_grain++;
|
||||
if (m_next_grain >= m_sfx.grains.size()) {
|
||||
m_done = true;
|
||||
return;
|
||||
}
|
||||
|
||||
m_countdown = m_sfx.grains[m_next_grain].Delay;
|
||||
}
|
||||
|
||||
} // namespace snd
|
132
game/sound/989snd/blocksound_handler.h
Normal file
132
game/sound/989snd/blocksound_handler.h
Normal file
@ -0,0 +1,132 @@
|
||||
#pragma once
|
||||
#include <unordered_map>
|
||||
#include "sfxblock.h"
|
||||
#include "vagvoice.h"
|
||||
#include "sound_handler.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace snd {
|
||||
class blocksound_handler : public sound_handler {
|
||||
public:
|
||||
blocksound_handler(SFX& sfx, voice_manager& vm, s32 vol, s32 pan, s32 pm, s32 pb, u32 bank_id)
|
||||
: m_sfx(sfx), m_vm(vm), m_bank(bank_id) {
|
||||
vol = (vol * m_sfx.d.Vol) >> 10;
|
||||
if (vol >= 128) {
|
||||
vol = 127;
|
||||
}
|
||||
|
||||
if (pan >= PAN_DONT_CHANGE) {
|
||||
pan = m_sfx.d.Pan;
|
||||
}
|
||||
|
||||
m_cur_volume = vol;
|
||||
m_cur_pan = pan;
|
||||
m_cur_pm = pm;
|
||||
m_cur_pb = pb;
|
||||
|
||||
m_app_volume = vol;
|
||||
m_app_pan = pan;
|
||||
m_app_pm = 0; // why only this one?
|
||||
m_app_pb = pb;
|
||||
|
||||
m_orig_pan = m_sfx.d.Pan;
|
||||
m_orig_volume = m_sfx.d.Vol;
|
||||
|
||||
m_group = sfx.d.VolGroup;
|
||||
|
||||
m_grain_handler.insert(std::make_pair(grain_type::null, &blocksound_handler::null));
|
||||
m_grain_handler.insert(std::make_pair(grain_type::tone, &blocksound_handler::play_tone));
|
||||
m_grain_handler.insert(std::make_pair(grain_type::rand_play, &blocksound_handler::rand_play));
|
||||
}
|
||||
|
||||
~blocksound_handler() override {
|
||||
for (auto& p : m_voices) {
|
||||
auto v = p.lock();
|
||||
if (v != nullptr) {
|
||||
v->stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool tick() override;
|
||||
u32 bank() override { return m_bank; };
|
||||
|
||||
void pause() override;
|
||||
void unpause() override;
|
||||
void stop() override;
|
||||
u8 group() override { return m_group; };
|
||||
void set_vol_pan(s32 vol, s32 pan) override;
|
||||
void set_pmod(s32 mod) override;
|
||||
void set_pbend(s32 bend); // TODO override;
|
||||
|
||||
void init();
|
||||
|
||||
private:
|
||||
enum class grain_type : u32 {
|
||||
null = 0,
|
||||
tone = 1,
|
||||
xref_id = 2,
|
||||
xref_num = 3,
|
||||
lfo_settings = 4,
|
||||
loop_start = 21,
|
||||
loop_end = 22,
|
||||
loop_continue = 23,
|
||||
rand_play = 25,
|
||||
rand_delay = 26,
|
||||
};
|
||||
|
||||
void do_grain();
|
||||
|
||||
s32 null(SFXGrain& grain);
|
||||
s32 play_tone(SFXGrain& grain);
|
||||
s32 rand_play(SFXGrain& grain);
|
||||
void update_pitch();
|
||||
|
||||
using grain_fp = int (blocksound_handler::*)(SFXGrain& grain);
|
||||
std::unordered_map<grain_type, grain_fp> m_grain_handler;
|
||||
|
||||
bool m_paused{false};
|
||||
|
||||
u8 m_group{0};
|
||||
bool m_done{false};
|
||||
|
||||
u32 m_grains_to_play{0};
|
||||
u32 m_grains_to_skip{0};
|
||||
bool m_skip_grains{false};
|
||||
|
||||
SFX& m_sfx;
|
||||
voice_manager& m_vm;
|
||||
|
||||
std::list<std::weak_ptr<vag_voice>> m_voices;
|
||||
|
||||
s32 m_current_pb{0};
|
||||
s32 m_current_pm{0};
|
||||
|
||||
s32 m_orig_volume{0};
|
||||
s32 m_orig_pan{0};
|
||||
s32 m_cur_volume{0};
|
||||
s32 m_cur_pan{0};
|
||||
s32 m_cur_pm{0};
|
||||
s32 m_cur_pb{0};
|
||||
s32 m_app_volume{0};
|
||||
s32 m_app_pan{0};
|
||||
s32 m_app_pm{0};
|
||||
s32 m_app_pb{0};
|
||||
|
||||
s32 m_lfo_volume{0};
|
||||
s32 m_lfo_pan{0};
|
||||
s32 m_lfo_pm{0};
|
||||
|
||||
u32 m_bank{0};
|
||||
|
||||
u8 m_note{60};
|
||||
u8 m_fine{0};
|
||||
|
||||
std::array<u8, 4> m_registers{};
|
||||
|
||||
// TODO LFO
|
||||
|
||||
s32 m_countdown{0};
|
||||
u32 m_next_grain{0};
|
||||
};
|
||||
} // namespace snd
|
31
game/sound/989snd/handle_allocator.h
Normal file
31
game/sound/989snd/handle_allocator.h
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace snd {
|
||||
|
||||
class id_allocator {
|
||||
public:
|
||||
u32 get_id() {
|
||||
u32 id = 0;
|
||||
if (m_free_ids.empty()) {
|
||||
id = next_id++;
|
||||
} else {
|
||||
id = m_free_ids.front();
|
||||
m_free_ids.pop();
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
void free_id(u32 id) { m_free_ids.push(id); }
|
||||
|
||||
private:
|
||||
u32 next_id{1};
|
||||
std::queue<u32> m_free_ids;
|
||||
};
|
||||
|
||||
} // namespace snd
|
194
game/sound/989snd/loader.cpp
Normal file
194
game/sound/989snd/loader.cpp
Normal file
@ -0,0 +1,194 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#include "loader.h"
|
||||
#include "midi_handler.h"
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
#include <third-party/fmt/core.h>
|
||||
|
||||
namespace snd {
|
||||
enum chunk : u32 { bank, samples, midi };
|
||||
|
||||
#define FOURCC(a, b, c, d) ((u32)(((d) << 24) | ((c) << 16) | ((b) << 8) | (a)))
|
||||
|
||||
u32 loader::read_music_bank(SoundBankData* data) {
|
||||
u32 handle = m_id_allocator.get_id();
|
||||
|
||||
auto bank = std::make_unique<MusicBank>(*this);
|
||||
|
||||
auto sound = (MIDISound*)((uintptr_t)data + data->FirstSound);
|
||||
for (int i = 0; i < data->NumSounds; i++) {
|
||||
bank->sounds.emplace_back(sound[i]);
|
||||
}
|
||||
|
||||
auto progdata = (ProgData*)((uintptr_t)data + data->FirstProg);
|
||||
for (int i = 0; i < data->NumProgs; i++) {
|
||||
Prog prog;
|
||||
prog.d = progdata[i];
|
||||
bank->programs.emplace_back(std::move(prog));
|
||||
}
|
||||
|
||||
for (auto& prog : bank->programs) {
|
||||
auto tonedata = (Tone*)((uintptr_t)data + prog.d.FirstTone);
|
||||
for (int i = 0; i < prog.d.NumTones; i++) {
|
||||
Tone tone = tonedata[i];
|
||||
tone.BankID = handle;
|
||||
prog.tones.emplace_back(tone);
|
||||
}
|
||||
}
|
||||
|
||||
bank->type = BankType::Music;
|
||||
|
||||
bank->bank_id = handle;
|
||||
bank->bank_name = data->BankID;
|
||||
m_soundbanks.emplace(handle, std::move(bank));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
u32 loader::read_sfx_bank(SFXBlockData* data) {
|
||||
u32 handle = m_id_allocator.get_id();
|
||||
|
||||
auto bank = std::make_unique<SFXBlock>(*this);
|
||||
|
||||
auto sounddata = (SFXData*)((uintptr_t)data + data->FirstSound);
|
||||
for (int i = 0; i < data->NumSounds; i++) {
|
||||
SFX sound;
|
||||
sound.d = sounddata[i];
|
||||
bank->sounds.push_back(sound);
|
||||
}
|
||||
|
||||
for (auto& sound : bank->sounds) {
|
||||
auto graindata = (SFXGrain*)((uintptr_t)data + data->FirstGrain + sound.d.FirstGrain);
|
||||
for (int i = 0; i < sound.d.NumGrains; i++) {
|
||||
SFXGrain grain = graindata[i];
|
||||
if (grain.Type == 1) {
|
||||
grain.GrainParams.tone.BankID = handle;
|
||||
}
|
||||
sound.grains.push_back(grain);
|
||||
}
|
||||
}
|
||||
|
||||
bank->type = BankType::SFX;
|
||||
|
||||
bank->bank_id = handle;
|
||||
m_soundbanks.emplace(handle, std::move(bank));
|
||||
return handle;
|
||||
}
|
||||
|
||||
u32 loader::read_bank(std::fstream& in) {
|
||||
size_t origin = in.tellg();
|
||||
FileAttributes<3> attr;
|
||||
in.read((char*)(&attr), sizeof(attr));
|
||||
|
||||
if (attr.type != 1 && attr.type != 3) {
|
||||
fmt::print("Error: File type {} not supported.", attr.type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (attr.num_chunks > 2) {
|
||||
// Fix for bugged tooling I assume?
|
||||
attr.where[chunk::bank].size += 4;
|
||||
}
|
||||
|
||||
auto pos = in.tellg();
|
||||
auto bank_buf = std::make_unique<u8[]>(attr.where[chunk::bank].size);
|
||||
in.seekg(origin + attr.where[chunk::bank].offset, std::fstream::beg);
|
||||
in.read((char*)bank_buf.get(), attr.where[chunk::bank].size);
|
||||
auto bank = (BankTag*)bank_buf.get();
|
||||
|
||||
u32 bank_id = 0;
|
||||
|
||||
if (bank->DataID == FOURCC('S', 'B', 'v', '2')) {
|
||||
bank_id = read_music_bank((SoundBankData*)bank_buf.get());
|
||||
} else if (bank->DataID == FOURCC('S', 'B', 'l', 'k')) {
|
||||
bank_id = read_sfx_bank((SFXBlockData*)bank_buf.get());
|
||||
} else {
|
||||
throw std::runtime_error("Unknown bank ID, bad file?");
|
||||
}
|
||||
|
||||
if (attr.num_chunks >= 2) {
|
||||
in.seekg(origin + attr.where[chunk::samples].offset, std::fstream::beg);
|
||||
auto samples = std::make_unique<u8[]>(attr.where[chunk::samples].size);
|
||||
in.read((char*)samples.get(), attr.where[chunk::samples].size);
|
||||
load_samples(bank_id, std::move(samples));
|
||||
}
|
||||
|
||||
if (attr.num_chunks >= 3) {
|
||||
in.seekg(origin + attr.where[chunk::midi].offset, std::fstream::beg);
|
||||
load_midi(in);
|
||||
}
|
||||
|
||||
fmt::print("Created bank {}\n", bank_id);
|
||||
|
||||
return bank_id;
|
||||
}
|
||||
|
||||
void loader::load_midi(std::fstream& in) {
|
||||
FileAttributes<1> attr;
|
||||
u32 cur = in.tellg();
|
||||
|
||||
in.read((char*)&attr, sizeof(attr));
|
||||
in.seekg(cur + attr.where[0].offset, std::fstream::beg);
|
||||
|
||||
auto midi = std::make_unique<u8[]>(attr.where[0].size);
|
||||
in.read((char*)midi.get(), attr.where[0].size);
|
||||
|
||||
auto h = (MIDIBlock*)midi.get();
|
||||
fmt::print("Loaded midi {:.4}\n", (char*)&h->ID);
|
||||
|
||||
m_midi.emplace(h->ID, (MIDIBlock*)midi.get());
|
||||
m_midi_chunks.emplace_back(std::move(midi));
|
||||
}
|
||||
|
||||
SoundBank* loader::get_bank_by_handle(u32 id) {
|
||||
if (m_soundbanks.find(id) == m_soundbanks.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_soundbanks[id].get();
|
||||
}
|
||||
|
||||
MusicBank* loader::get_bank_by_name(u32 id) {
|
||||
for (auto& b : m_soundbanks) {
|
||||
if (b.second->type == BankType::Music) {
|
||||
auto* bank = static_cast<MusicBank*>(b.second.get());
|
||||
if (bank->bank_name == id) {
|
||||
return bank;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MIDIBlock* loader::get_midi(u32 id) {
|
||||
return m_midi.at(id);
|
||||
}
|
||||
|
||||
u8* loader::get_bank_samples(u32 id) {
|
||||
return m_soundbanks.at(id).get()->sampleBuf.get();
|
||||
}
|
||||
|
||||
void loader::load_samples(u32 bank_id, std::unique_ptr<u8[]> samples) {
|
||||
auto& bank = m_soundbanks.at(bank_id);
|
||||
bank->sampleBuf = std::move(samples);
|
||||
}
|
||||
|
||||
void loader::unload_bank(u32 id) {
|
||||
for (auto it = m_midi_chunks.begin(); it != m_midi_chunks.end();) {
|
||||
bool del = false;
|
||||
// FIXME delete midi
|
||||
|
||||
if (del) {
|
||||
it = m_midi_chunks.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
m_soundbanks.erase(id);
|
||||
m_id_allocator.free_id(id);
|
||||
}
|
||||
|
||||
} // namespace snd
|
58
game/sound/989snd/loader.h
Normal file
58
game/sound/989snd/loader.h
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#pragma once
|
||||
#include "../common/synth.h"
|
||||
#include "common/common_types.h"
|
||||
#include "handle_allocator.h"
|
||||
#include "sound_handler.h"
|
||||
#include "musicbank.h"
|
||||
#include "soundbank.h"
|
||||
#include "sfxblock.h"
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace snd {
|
||||
|
||||
#define FOURCC(a, b, c, d) ((u32)(((d) << 24) | ((c) << 16) | ((b) << 8) | (a)))
|
||||
struct LocAndSize {
|
||||
/* 0 */ u32 offset;
|
||||
/* 4 */ u32 size;
|
||||
};
|
||||
|
||||
template <size_t chunks>
|
||||
struct FileAttributes {
|
||||
/* 0 */ u32 type;
|
||||
/* 4 */ u32 num_chunks;
|
||||
/* 8 */ LocAndSize where[chunks];
|
||||
};
|
||||
|
||||
class loader : public locator {
|
||||
public:
|
||||
SoundBank* get_bank_by_handle(u32 id) override;
|
||||
MusicBank* get_bank_by_name(u32 id) override;
|
||||
MIDIBlock* get_midi(u32 id) override;
|
||||
u8* get_bank_samples(u32 id) override;
|
||||
|
||||
void unload_bank(u32 id);
|
||||
|
||||
u32 read_bank(std::fstream& in);
|
||||
void load_midi(std::fstream& in);
|
||||
|
||||
bool read_midi();
|
||||
|
||||
private:
|
||||
void load_samples(u32 bank, std::unique_ptr<u8[]> samples);
|
||||
u32 read_music_bank(SoundBankData* data);
|
||||
u32 read_sfx_bank(SFXBlockData* data);
|
||||
|
||||
id_allocator m_id_allocator;
|
||||
std::unordered_map<u32, std::unique_ptr<SoundBank>> m_soundbanks;
|
||||
|
||||
std::vector<std::unique_ptr<u8[]>> m_midi_chunks;
|
||||
|
||||
std::unordered_map<u32, MIDIBlock*> m_midi;
|
||||
|
||||
u32 m_next_id{0};
|
||||
};
|
||||
} // namespace snd
|
19
game/sound/989snd/locator.h
Normal file
19
game/sound/989snd/locator.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace snd {
|
||||
|
||||
class MusicBank;
|
||||
class SoundBank;
|
||||
struct MIDIBlock;
|
||||
|
||||
class locator {
|
||||
public:
|
||||
virtual ~locator() = default;
|
||||
virtual SoundBank* get_bank_by_handle(u32 id) = 0;
|
||||
virtual MusicBank* get_bank_by_name(u32 id) = 0;
|
||||
virtual u8* get_bank_samples(u32 id) = 0;
|
||||
virtual MIDIBlock* get_midi(u32 id) = 0;
|
||||
};
|
||||
} // namespace snd
|
406
game/sound/989snd/midi_handler.cpp
Normal file
406
game/sound/989snd/midi_handler.cpp
Normal file
@ -0,0 +1,406 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#include "midi_handler.h"
|
||||
#include "ame_handler.h"
|
||||
|
||||
#include <third-party/fmt/core.h>
|
||||
|
||||
namespace snd {
|
||||
/*
|
||||
** In the original 989snd, the player struct can live in different places
|
||||
** depending on the type of file.
|
||||
**
|
||||
** For files with multiple tracks it lives in-place before the sequence data
|
||||
** where the file is loaded. For single track (like sunken) it lives separetely
|
||||
**
|
||||
** the sequencer ticks at 240hz
|
||||
**
|
||||
*/
|
||||
|
||||
midi_handler::midi_handler(MIDIBlockHeader* block,
|
||||
voice_manager& vm,
|
||||
MIDISound& sound,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
locator& loc,
|
||||
u32 bank)
|
||||
: m_sound(sound),
|
||||
m_locator(loc),
|
||||
m_repeats(sound.Repeats),
|
||||
m_bank(bank),
|
||||
m_header(block),
|
||||
m_vm(vm) {
|
||||
if (vol == VOLUME_DONT_CHANGE) {
|
||||
vol = 1024;
|
||||
}
|
||||
|
||||
m_vol = (vol * m_sound.Vol) >> 10;
|
||||
if (m_vol >= 128) {
|
||||
m_vol = 127;
|
||||
}
|
||||
|
||||
if (pan == PAN_DONT_CHANGE || pan == PAN_RESET) {
|
||||
m_pan = m_sound.Pan;
|
||||
} else {
|
||||
m_pan = pan;
|
||||
}
|
||||
|
||||
init_midi();
|
||||
}
|
||||
|
||||
midi_handler::midi_handler(MIDIBlockHeader* block,
|
||||
voice_manager& vm,
|
||||
MIDISound& sound,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
locator& loc,
|
||||
u32 bank,
|
||||
std::optional<ame_handler*> parent)
|
||||
: m_parent(parent),
|
||||
m_sound(sound),
|
||||
m_locator(loc),
|
||||
m_vol(vol),
|
||||
m_pan(pan),
|
||||
m_repeats(sound.Repeats),
|
||||
m_bank(bank),
|
||||
m_header(block),
|
||||
m_vm(vm) {
|
||||
init_midi();
|
||||
}
|
||||
|
||||
void midi_handler::init_midi() {
|
||||
m_seq_data_start = (u8*)((uintptr_t)m_header + (uintptr_t)m_header->DataStart);
|
||||
m_seq_ptr = m_seq_data_start;
|
||||
m_tempo = m_header->Tempo;
|
||||
m_ppq = m_header->PPQ;
|
||||
m_chanvol.fill(0x7f);
|
||||
m_chanpan.fill(0);
|
||||
}
|
||||
|
||||
std::pair<size_t, u32> midi_handler::read_vlq(u8* value) {
|
||||
size_t len = 1;
|
||||
u32 out = *value & 0x7f;
|
||||
// fmt::print("starting with {:x}\n", *value);
|
||||
|
||||
if ((*value & 0x80) != 0) {
|
||||
while ((*value & 0x80) != 0) {
|
||||
len++;
|
||||
value++;
|
||||
out = (out << 7) + (*value & 0x7f);
|
||||
}
|
||||
}
|
||||
|
||||
return {len, out};
|
||||
}
|
||||
|
||||
void midi_handler::pause() {
|
||||
m_paused = true;
|
||||
|
||||
for (auto& p : m_voices) {
|
||||
auto voice = p.lock();
|
||||
if (voice == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_vm.pause(voice);
|
||||
}
|
||||
}
|
||||
|
||||
void midi_handler::unpause() {
|
||||
m_paused = false;
|
||||
|
||||
for (auto& p : m_voices) {
|
||||
auto voice = p.lock();
|
||||
if (voice == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_vm.unpause(voice);
|
||||
}
|
||||
}
|
||||
|
||||
void midi_handler::stop() {
|
||||
m_track_complete = true;
|
||||
|
||||
for (auto& p : m_voices) {
|
||||
auto voice = p.lock();
|
||||
if (voice == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
voice->key_off();
|
||||
}
|
||||
}
|
||||
|
||||
void midi_handler::set_vol_pan(s32 vol, s32 pan) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void midi_handler::set_pmod(s32 mod) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void midi_handler::mute_channel(u8 channel) {
|
||||
// fmt::print("{:x} ame muting channel {}\n", (u64)this, channel);
|
||||
m_mute_state[channel] = true;
|
||||
}
|
||||
|
||||
void midi_handler::unmute_channel(u8 channel) {
|
||||
// fmt::print("{:x} ame unmuting channel {}\n", (u64)this, channel);
|
||||
m_mute_state[channel] = false;
|
||||
}
|
||||
|
||||
void midi_handler::note_on() {
|
||||
u8 channel = m_status & 0xf;
|
||||
u8 note = m_seq_ptr[0];
|
||||
u8 velocity = m_seq_ptr[1];
|
||||
|
||||
if (velocity == 0) {
|
||||
note_off();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_mute_state[channel]) {
|
||||
m_seq_ptr += 2;
|
||||
return;
|
||||
}
|
||||
|
||||
// fmt::print("{:x} {}: [ch{:01x}] note on {:02x} {:02x}\n", (u64)this, m_time, channel, note,
|
||||
// velocity);
|
||||
|
||||
// Key on all the applicable tones for the program
|
||||
auto bank = dynamic_cast<MusicBank*>(m_locator.get_bank_by_name(m_header->BankID));
|
||||
auto& program = bank->programs[m_programs[channel]];
|
||||
|
||||
for (auto& t : program.tones) {
|
||||
if (note >= t.MapLow && note <= t.MapHigh) {
|
||||
s16 pan = m_chanpan[channel] + m_pan;
|
||||
if (pan >= 360) {
|
||||
pan -= 360;
|
||||
}
|
||||
|
||||
auto voice = std::make_shared<midi_voice>(t);
|
||||
voice->basevol = m_vm.make_volume_b(m_vol, (velocity * m_chanvol[channel]) / 0x7f, pan,
|
||||
program.d.Vol, program.d.Pan, t.Vol, t.Pan);
|
||||
|
||||
voice->note = note;
|
||||
voice->channel = channel;
|
||||
|
||||
voice->start_note = note;
|
||||
voice->start_fine = 0;
|
||||
|
||||
// TODO
|
||||
// voice->current_pm = 0;
|
||||
// voice->current_pb = 0;
|
||||
|
||||
voice->group = m_sound.VolGroup;
|
||||
m_vm.start_tone(voice);
|
||||
m_voices.emplace_front(voice);
|
||||
}
|
||||
}
|
||||
|
||||
m_seq_ptr += 2;
|
||||
}
|
||||
|
||||
void midi_handler::note_off() {
|
||||
u8 channel = m_status & 0xf;
|
||||
u8 note = m_seq_ptr[0];
|
||||
// Yep, no velocity for note-offs
|
||||
[[maybe_unused]] u8 velocity = m_seq_ptr[1];
|
||||
|
||||
// fmt::print("{}: note off {:02x} {:02x} {:02x}\n", m_time, m_status, m_seq_ptr[0],
|
||||
// m_seq_ptr[1]);
|
||||
|
||||
for (auto& v : m_voices) {
|
||||
auto voice = v.lock();
|
||||
if (voice == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (voice->channel == channel && voice->note == note) {
|
||||
voice->key_off();
|
||||
}
|
||||
}
|
||||
|
||||
m_seq_ptr += 2;
|
||||
}
|
||||
|
||||
void midi_handler::program_change() {
|
||||
u8 channel = m_status & 0xf;
|
||||
u8 program = m_seq_ptr[0];
|
||||
|
||||
m_programs[channel] = program;
|
||||
|
||||
// fmt::print("{:x} {}: [ch{:01x}] program change {:02x} -> {:02x}\n", (u64)this, m_time, channel,
|
||||
// m_programs[channel], program);
|
||||
m_seq_ptr += 1;
|
||||
}
|
||||
|
||||
void midi_handler::channel_pressure() {
|
||||
u8 channel = m_status & 0xf;
|
||||
u8 note = m_seq_ptr[0];
|
||||
// fmt::print("{}: channel pressure {:02x} {:02x}\n", m_time, m_status, m_seq_ptr[0]);
|
||||
|
||||
for (auto& v : m_voices) {
|
||||
auto voice = v.lock();
|
||||
if (voice == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (voice->channel == channel && voice->note == note) {
|
||||
voice->key_off();
|
||||
}
|
||||
}
|
||||
|
||||
m_seq_ptr += 1;
|
||||
}
|
||||
|
||||
void midi_handler::channel_pitch() {
|
||||
u8 channel = m_status & 0xF;
|
||||
u32 pitch = (m_seq_ptr[0] << 7) | m_seq_ptr[1];
|
||||
fmt::print("{}: pitch ch{:01x} {:04x}\n", m_time, channel, pitch);
|
||||
m_seq_ptr += 2;
|
||||
}
|
||||
|
||||
void midi_handler::meta_event() {
|
||||
// fmt::print("{}: meta event {:02x}\n", m_time, *m_seq_ptr);
|
||||
size_t len = m_seq_ptr[1];
|
||||
|
||||
if (*m_seq_ptr == 0x2f) {
|
||||
m_seq_ptr = m_seq_data_start;
|
||||
|
||||
// If repeats was 0 we'll go negative, fail this test, and loop infinitely as intended
|
||||
m_repeats--;
|
||||
if (m_repeats == 0) {
|
||||
m_track_complete = true;
|
||||
}
|
||||
|
||||
if (m_repeats < 0) {
|
||||
m_repeats = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (*m_seq_ptr == 0x51) {
|
||||
m_tempo = (m_seq_ptr[2] << 16) | (m_seq_ptr[3] << 8) | (m_seq_ptr[4]);
|
||||
}
|
||||
|
||||
m_seq_ptr += len + 2;
|
||||
}
|
||||
|
||||
void midi_handler::system_event() {
|
||||
// fmt::print("{}: system event {:02x}\n", m_time, *m_seq_ptr);
|
||||
|
||||
switch (*m_seq_ptr) {
|
||||
case 0x75:
|
||||
m_seq_ptr++;
|
||||
if (m_parent.has_value()) {
|
||||
auto [cont, ptr] = m_parent.value()->run_ame(*this, m_seq_ptr);
|
||||
m_seq_ptr = ptr;
|
||||
|
||||
if (!cont) {
|
||||
fmt::print("{:x} track stopped by ame\n", (u64)this);
|
||||
m_track_complete = true;
|
||||
}
|
||||
} else {
|
||||
throw midi_error("MIDI tried to run AME without an AME handler");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw midi_error(fmt::format("Unknown system message {:02x}", *m_seq_ptr));
|
||||
}
|
||||
}
|
||||
|
||||
bool midi_handler::tick() {
|
||||
if (m_paused) {
|
||||
return m_track_complete;
|
||||
}
|
||||
|
||||
try {
|
||||
m_voices.remove_if([](auto& v) { return v.expired(); });
|
||||
step();
|
||||
} catch (midi_error& e) {
|
||||
m_track_complete = true;
|
||||
fmt::print("MIDI Error: {}\n", e.what());
|
||||
|
||||
fmt::print("Sequence following: ");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
fmt::print("{:x} ", m_seq_ptr[i]);
|
||||
}
|
||||
fmt::print("\n");
|
||||
}
|
||||
|
||||
return m_track_complete;
|
||||
}
|
||||
|
||||
void midi_handler::new_delta() {
|
||||
auto [len, delta] = read_vlq(m_seq_ptr);
|
||||
|
||||
m_seq_ptr += len;
|
||||
m_time += delta;
|
||||
|
||||
m_ppt = 100 * mics_per_tick / (m_tempo / m_ppq);
|
||||
m_tickdelta = 100 * delta + m_tickerror;
|
||||
if (m_tickdelta < 0 || m_tickdelta < m_ppt / 2) {
|
||||
m_tickerror = m_tickdelta;
|
||||
m_tickdelta = 0;
|
||||
}
|
||||
if (m_tickdelta != 0) {
|
||||
m_tick_countdown = (m_tickdelta / 100 * m_tempo / m_ppq - 1 + mics_per_tick) / mics_per_tick;
|
||||
m_tickerror = m_tickdelta - m_ppt * m_tick_countdown;
|
||||
}
|
||||
}
|
||||
|
||||
void midi_handler::step() {
|
||||
if (m_get_delta) {
|
||||
new_delta();
|
||||
m_get_delta = false;
|
||||
} else {
|
||||
m_tick_countdown--;
|
||||
}
|
||||
|
||||
while (!m_tick_countdown && !m_track_complete) {
|
||||
// running status, new events always have top bit
|
||||
if (*m_seq_ptr & 0x80) {
|
||||
m_status = *m_seq_ptr;
|
||||
m_seq_ptr++;
|
||||
}
|
||||
|
||||
switch (m_status >> 4) {
|
||||
case 0x8:
|
||||
note_off();
|
||||
break;
|
||||
case 0x9:
|
||||
note_on();
|
||||
break;
|
||||
case 0xD:
|
||||
channel_pressure();
|
||||
break;
|
||||
case 0xC:
|
||||
program_change();
|
||||
break;
|
||||
case 0xE:
|
||||
channel_pitch();
|
||||
break;
|
||||
case 0xF:
|
||||
// normal meta-event
|
||||
if (m_status == 0xFF) {
|
||||
meta_event();
|
||||
break;
|
||||
}
|
||||
if (m_status == 0xF0) {
|
||||
system_event();
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
default:
|
||||
throw midi_error(fmt::format("MIDI error: invalid status {}", m_status));
|
||||
return;
|
||||
}
|
||||
|
||||
new_delta();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace snd
|
142
game/sound/989snd/midi_handler.h
Normal file
142
game/sound/989snd/midi_handler.h
Normal file
@ -0,0 +1,142 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#pragma once
|
||||
#include "ame_handler.h"
|
||||
#include "vagvoice.h"
|
||||
#include "loader.h"
|
||||
#include "sound_handler.h"
|
||||
#include "common/common_types.h"
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <list>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace snd {
|
||||
|
||||
struct ProgData {
|
||||
/* 0 */ s8 NumTones;
|
||||
/* 1 */ s8 Vol;
|
||||
/* 2 */ s16 Pan;
|
||||
/* 4 */ /*Tone**/ u32 FirstTone;
|
||||
};
|
||||
|
||||
struct Prog {
|
||||
ProgData d;
|
||||
std::vector<Tone> tones;
|
||||
};
|
||||
|
||||
class midi_voice : public vag_voice {
|
||||
public:
|
||||
midi_voice(Tone& t) : vag_voice(t) {}
|
||||
u8 note{0};
|
||||
u8 channel{0};
|
||||
};
|
||||
|
||||
class ame_handler;
|
||||
class midi_handler : public sound_handler {
|
||||
public:
|
||||
midi_handler(MIDIBlockHeader* block,
|
||||
voice_manager& vm,
|
||||
MIDISound& sound,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
locator& loc,
|
||||
u32 bank);
|
||||
|
||||
midi_handler(MIDIBlockHeader* block,
|
||||
voice_manager& vm,
|
||||
MIDISound& sound,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
locator& loc,
|
||||
u32 bank,
|
||||
std::optional<ame_handler*> parent);
|
||||
|
||||
~midi_handler() override {
|
||||
for (auto& p : m_voices) {
|
||||
auto v = p.lock();
|
||||
if (v != nullptr) {
|
||||
v->stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
void init_midi();
|
||||
void start();
|
||||
bool tick() override;
|
||||
void mute_channel(u8 channel);
|
||||
void unmute_channel(u8 channel);
|
||||
u32 bank() override { return m_bank; };
|
||||
|
||||
void pause() override;
|
||||
void stop() override;
|
||||
void unpause() override;
|
||||
u8 group() override { return m_sound.VolGroup; }
|
||||
void set_vol_pan(s32 vol, s32 pan) override;
|
||||
|
||||
bool complete() { return m_track_complete; };
|
||||
void set_pmod(s32 mod) override;
|
||||
|
||||
private:
|
||||
static constexpr int tickrate = 240;
|
||||
static constexpr int mics_per_tick = 1000000 / tickrate;
|
||||
struct midi_error : public std::exception {
|
||||
midi_error(std::string text) : msg(std::move(text)) {}
|
||||
midi_error() : msg("Unknown MIDI error") {}
|
||||
std::string msg;
|
||||
const char* what() const noexcept override { return msg.c_str(); }
|
||||
};
|
||||
|
||||
std::optional<ame_handler*> m_parent;
|
||||
|
||||
std::list<std::weak_ptr<midi_voice>> m_voices;
|
||||
|
||||
MIDISound& m_sound;
|
||||
locator& m_locator;
|
||||
s32 m_vol{0x7f};
|
||||
s32 m_pan{0};
|
||||
s8 m_repeats{0};
|
||||
u32 m_bank;
|
||||
|
||||
bool m_paused{false};
|
||||
|
||||
MIDIBlockHeader* m_header{nullptr};
|
||||
|
||||
std::array<bool, 16> m_mute_state{};
|
||||
std::array<s8, 16> m_chanvol{};
|
||||
std::array<s8, 16> m_chanpan{};
|
||||
u8* m_sample_data{nullptr};
|
||||
|
||||
u8* m_seq_data_start{nullptr};
|
||||
u8* m_seq_ptr{nullptr};
|
||||
u8 m_status{0};
|
||||
u32 m_tempo{500000};
|
||||
u32 m_ppq{480};
|
||||
u32 m_time{0};
|
||||
s32 m_tickerror{0};
|
||||
s32 m_tickdelta{0};
|
||||
s32 m_ppt{0};
|
||||
u64 m_tick_countdown{0};
|
||||
bool m_get_delta{true};
|
||||
bool m_track_complete{false};
|
||||
u32 m_muted_channels{0};
|
||||
|
||||
std::array<u8, 16> m_programs{};
|
||||
|
||||
voice_manager& m_vm;
|
||||
|
||||
void step();
|
||||
void new_delta();
|
||||
|
||||
void note_on();
|
||||
void note_off();
|
||||
void channel_pressure();
|
||||
void program_change();
|
||||
void meta_event();
|
||||
void system_event();
|
||||
void channel_pitch();
|
||||
|
||||
static std::pair<size_t, u32> read_vlq(u8* value);
|
||||
};
|
||||
} // namespace snd
|
29
game/sound/989snd/musicbank.cpp
Normal file
29
game/sound/989snd/musicbank.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
#include "musicbank.h"
|
||||
#include "ame_handler.h"
|
||||
#include "midi_handler.h"
|
||||
#include "../common/synth.h"
|
||||
|
||||
namespace snd {
|
||||
std::unique_ptr<sound_handler> MusicBank::make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
s32 pm,
|
||||
s32 pb) {
|
||||
auto& sound = sounds[sound_id];
|
||||
std::unique_ptr<sound_handler> handler;
|
||||
|
||||
if (sound.Type == 4) { // midi
|
||||
auto midi = static_cast<MIDIBlockHeader*>(m_locator.get_midi(sound.MIDIID));
|
||||
handler = std::make_unique<midi_handler>(midi, vm, sound, vol, pan, m_locator, bank_id);
|
||||
} else if (sound.Type == 5) { // ame
|
||||
auto midi = static_cast<MultiMIDIBlockHeader*>(m_locator.get_midi(sound.MIDIID));
|
||||
handler = std::make_unique<ame_handler>(midi, vm, sound, vol, pan, m_locator, bank_id);
|
||||
} else {
|
||||
// error
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
} // namespace snd
|
76
game/sound/989snd/musicbank.h
Normal file
76
game/sound/989snd/musicbank.h
Normal file
@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "soundbank.h"
|
||||
|
||||
namespace snd {
|
||||
struct SoundBankData : BankTag {
|
||||
/* 10 */ s8 BankNum;
|
||||
/* 11 */ s8 pad1;
|
||||
/* 12 */ s16 pad2;
|
||||
/* 14 */ s16 NumSounds;
|
||||
/* 16 */ s16 NumProgs;
|
||||
/* 18 */ s16 NumTones;
|
||||
/* 1a */ s16 NumVAGs;
|
||||
/* 1c */ /*Sound**/ u32 FirstSound;
|
||||
/* 20 */ /*Prog**/ u32 FirstProg;
|
||||
/* 24 */ /*Tone**/ u32 FirstTone;
|
||||
/* 28 */ /*void**/ u32 VagsInSR;
|
||||
/* 2c */ u32 VagDataSize;
|
||||
/* 30 */ /*SoundBank**/ u32 NextBank;
|
||||
};
|
||||
|
||||
struct MIDIBlock {
|
||||
/* 0 */ u32 DataID;
|
||||
/* 4 */ s16 Version;
|
||||
/* 6 */ s8 Flags;
|
||||
/* 7 */ s8 NumMIDIBlocks;
|
||||
/* 8 */ u32 ID;
|
||||
};
|
||||
|
||||
struct MIDIBlockHeader : MIDIBlock {
|
||||
/* c */ /*void**/ u32 NextMIDIBlock;
|
||||
/* 10 */ u32 BankID;
|
||||
/* 14 */ /*SoundBank**/ u32 BankPtr;
|
||||
/* 18 */ /*s8**/ u32 DataStart;
|
||||
/* 1c */ /*s8**/ u32 MultiMIDIParent;
|
||||
/* 20 */ u32 Tempo;
|
||||
/* 24 */ u32 PPQ;
|
||||
};
|
||||
|
||||
struct MultiMIDIBlockHeader : MIDIBlock {
|
||||
/* c */ /*void**/ u32 NextMIDIBlock;
|
||||
/* 10 */ /*s8**/ u32 BlockPtr[0];
|
||||
};
|
||||
|
||||
struct MIDISound {
|
||||
/* 0 */ s32 Type;
|
||||
/* 4 */ /*SoundBank**/ u32 Bank;
|
||||
/* 8 */ /*void**/ u32 OrigBank;
|
||||
/* c */ u32 MIDIID;
|
||||
/* 10 */ s16 Vol;
|
||||
/* 12 */ s8 Repeats;
|
||||
/* 13 */ s8 VolGroup;
|
||||
/* 14 */ s16 Pan;
|
||||
/* 16 */ s8 Index;
|
||||
/* 17 */ s8 Flags;
|
||||
/* 18 */ /*void**/ u32 MIDIBlock;
|
||||
};
|
||||
|
||||
struct Prog;
|
||||
class MusicBank : public SoundBank {
|
||||
public:
|
||||
MusicBank(locator& loc) : m_locator(loc) {}
|
||||
std::unique_ptr<sound_handler> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
s32 pm,
|
||||
s32 pb) override;
|
||||
|
||||
std::vector<Prog> programs;
|
||||
std::vector<MIDISound> sounds;
|
||||
|
||||
private:
|
||||
locator& m_locator;
|
||||
};
|
||||
} // namespace snd
|
285
game/sound/989snd/player.cpp
Normal file
285
game/sound/989snd/player.cpp
Normal file
@ -0,0 +1,285 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#include "player.h"
|
||||
#include <third-party/fmt/core.h>
|
||||
#include <fstream>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace snd {
|
||||
|
||||
player::player() : m_vmanager(m_synth, m_loader) {
|
||||
init_cubeb();
|
||||
}
|
||||
|
||||
player::~player() {
|
||||
destroy_cubeb();
|
||||
}
|
||||
|
||||
void player::init_cubeb() {
|
||||
#ifdef _WIN32
|
||||
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
|
||||
m_coinitialized = SUCCEEDED(hr);
|
||||
if (FAILED(hr) && hr != RPC_E_CHANGED_MODE) {
|
||||
fmt::print("Couldn't initialize COM\n");
|
||||
fmt::print("Cubeb init failed\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
cubeb_init(&m_ctx, "OpenGOAL", nullptr);
|
||||
|
||||
cubeb_stream_params outparam = {};
|
||||
outparam.channels = 2;
|
||||
outparam.format = CUBEB_SAMPLE_S16LE;
|
||||
outparam.rate = 48000;
|
||||
outparam.layout = CUBEB_LAYOUT_STEREO;
|
||||
outparam.prefs = CUBEB_STREAM_PREF_NONE;
|
||||
|
||||
s32 err = 0;
|
||||
u32 latency = 0;
|
||||
err = cubeb_get_min_latency(m_ctx, &outparam, &latency);
|
||||
if (err != CUBEB_OK) {
|
||||
fmt::print("Cubeb init failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
err = cubeb_stream_init(m_ctx, &m_stream, "OpenGOAL", nullptr, nullptr, nullptr, &outparam,
|
||||
latency, &sound_callback, &state_callback, this);
|
||||
if (err != CUBEB_OK) {
|
||||
fmt::print("Cubeb init failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
err = cubeb_stream_start(m_stream);
|
||||
if (err != CUBEB_OK) {
|
||||
fmt::print("Cubeb init failed\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void player::destroy_cubeb() {
|
||||
cubeb_stream_stop(m_stream);
|
||||
cubeb_stream_destroy(m_stream);
|
||||
cubeb_destroy(m_ctx);
|
||||
#ifdef _WIN32
|
||||
if (m_coinitialized) {
|
||||
CoUninitialize();
|
||||
m_coinitialized = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
long player::sound_callback([[maybe_unused]] cubeb_stream* stream,
|
||||
void* user,
|
||||
[[maybe_unused]] const void* input,
|
||||
void* output_buffer,
|
||||
long nframes) {
|
||||
((player*)user)->tick((s16_output*)output_buffer, nframes);
|
||||
return nframes;
|
||||
}
|
||||
|
||||
void player::state_callback([[maybe_unused]] cubeb_stream* stream,
|
||||
[[maybe_unused]] void* user,
|
||||
[[maybe_unused]] cubeb_state state) {}
|
||||
|
||||
void player::tick(s16_output* stream, int samples) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
m_tick++;
|
||||
static int htick = 200;
|
||||
static int stick = 48000;
|
||||
for (int i = 0; i < samples; i++) {
|
||||
// The handlers expect to tick at 240hz
|
||||
// 48000/240 = 200
|
||||
if (htick == 200) {
|
||||
for (auto it = m_handlers.begin(); it != m_handlers.end();) {
|
||||
bool done = it->second->tick();
|
||||
if (done) {
|
||||
// fmt::print("erasing handler\n");
|
||||
m_handle_allocator.free_id(it->first);
|
||||
it = m_handlers.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
htick = 0;
|
||||
}
|
||||
|
||||
if (stick == 48000) {
|
||||
// fmt::print("{} handlers active\n", m_handlers.size());
|
||||
stick = 0;
|
||||
}
|
||||
|
||||
stick++;
|
||||
htick++;
|
||||
*stream++ = m_synth.tick();
|
||||
}
|
||||
}
|
||||
|
||||
u32 player::play_sound(u32 bank_id, u32 sound_id, s32 vol, s32 pan, s32 pm, s32 pb) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
auto bank = m_loader.get_bank_by_handle(bank_id);
|
||||
if (bank == nullptr) {
|
||||
fmt::print("play_sound: Bank {} does not exist\n", bank_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto handler = bank->make_handler(m_vmanager, sound_id, vol, pan, pm, pb);
|
||||
if (handler == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 handle = m_handle_allocator.get_id();
|
||||
m_handlers.emplace(handle, std::move(handler));
|
||||
// fmt::print("play_sound {}:{} - {}\n", bank_id, sound_id, handle);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void player::stop_sound(u32 sound_id) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
auto handler = m_handlers.find(sound_id);
|
||||
if (handler == m_handlers.end())
|
||||
return;
|
||||
|
||||
handler->second->stop();
|
||||
|
||||
// m_handle_allocator.free_id(sound_id);
|
||||
// m_handlers.erase(sound_id);
|
||||
}
|
||||
|
||||
void player::set_midi_reg(u32 sound_id, u8 reg, u8 value) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
if (m_handlers.find(sound_id) == m_handlers.end()) {
|
||||
// fmt::print("set_midi_reg: Handler {} does not exist\n", sound_id);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* handler = m_handlers.at(sound_id).get();
|
||||
handler->set_register(reg, value);
|
||||
}
|
||||
|
||||
bool player::sound_still_active(u32 sound_id) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
auto handler = m_handlers.find(sound_id);
|
||||
if (handler == m_handlers.end())
|
||||
return false;
|
||||
|
||||
// fmt::print("sound_still_active {}\n", sound_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
void player::set_master_volume(u32 group, s32 volume) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
if (volume > 0x400)
|
||||
volume = 0x400;
|
||||
|
||||
if (volume < 0)
|
||||
volume = 0;
|
||||
|
||||
if (group == 15)
|
||||
return;
|
||||
|
||||
m_vmanager.set_master_vol(group, volume);
|
||||
|
||||
// Master volume
|
||||
if (group == 16) {
|
||||
m_synth.set_master_vol(0x3ffff * volume / 0x400);
|
||||
}
|
||||
}
|
||||
|
||||
u32 player::load_bank(std::filesystem::path& filepath, size_t offset) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
fmt::print("Loading bank {}\n", filepath.string());
|
||||
std::fstream in(filepath, std::fstream::binary | std::fstream::in);
|
||||
in.seekg(offset, std::fstream::beg);
|
||||
|
||||
return m_loader.read_bank(in);
|
||||
}
|
||||
|
||||
void player::unload_bank(u32 bank_handle) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
auto* bank = m_loader.get_bank_by_handle(bank_handle);
|
||||
if (bank == nullptr)
|
||||
return;
|
||||
|
||||
for (auto it = m_handlers.begin(); it != m_handlers.end();) {
|
||||
if (it->second->bank() == bank_handle) {
|
||||
m_handle_allocator.free_id(it->first);
|
||||
it = m_handlers.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
m_loader.unload_bank(bank_handle);
|
||||
}
|
||||
|
||||
void player::set_pan_table(vol_pair* pantable) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
m_vmanager.set_pan_table(pantable);
|
||||
}
|
||||
|
||||
void player::set_playback_mode(s32 mode) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
m_vmanager.set_playback_mode(mode);
|
||||
}
|
||||
|
||||
void player::pause_sound(s32 sound_id) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
auto handler = m_handlers.find(sound_id);
|
||||
if (handler == m_handlers.end())
|
||||
return;
|
||||
|
||||
handler->second->pause();
|
||||
}
|
||||
|
||||
void player::continue_sound(s32 sound_id) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
auto handler = m_handlers.find(sound_id);
|
||||
if (handler == m_handlers.end())
|
||||
return;
|
||||
|
||||
handler->second->unpause();
|
||||
}
|
||||
|
||||
void player::pause_all_sounds_in_group(u8 group) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
|
||||
for (auto& h : m_handlers) {
|
||||
if ((1 << h.second->group()) & group) {
|
||||
h.second->pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void player::continue_all_sounds_in_group(u8 group) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
|
||||
for (auto& h : m_handlers) {
|
||||
if ((1 << h.second->group()) & group) {
|
||||
h.second->unpause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void player::set_sound_vol_pan(s32 sound_id, s32 vol, s32 pan) {
|
||||
std::scoped_lock lock(m_ticklock);
|
||||
auto handler = m_handlers.find(sound_id);
|
||||
if (handler == m_handlers.end())
|
||||
return;
|
||||
|
||||
handler->second->set_vol_pan(vol, pan);
|
||||
}
|
||||
|
||||
void player::set_sound_pmod(s32 sound_handle, s32 mod) {
|
||||
auto handler = m_handlers.find(sound_handle);
|
||||
if (handler == m_handlers.end())
|
||||
return;
|
||||
|
||||
handler->second->set_pmod(mod);
|
||||
}
|
||||
} // namespace snd
|
79
game/sound/989snd/player.h
Normal file
79
game/sound/989snd/player.h
Normal file
@ -0,0 +1,79 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#pragma once
|
||||
#include "ame_handler.h"
|
||||
#include "game/sound/989snd/vagvoice.h"
|
||||
#include "third-party/cubeb/cubeb/include/cubeb/cubeb.h"
|
||||
#include "midi_handler.h"
|
||||
#include "sound_handler.h"
|
||||
#include "loader.h"
|
||||
#include "../common/synth.h"
|
||||
#include "common/common_types.h"
|
||||
#include "handle_allocator.h"
|
||||
#include <filesystem>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace snd {
|
||||
|
||||
class player {
|
||||
public:
|
||||
player();
|
||||
~player();
|
||||
player(const player&) = delete;
|
||||
player operator=(const player&) = delete;
|
||||
|
||||
// player(player&& other) noexcept = default;
|
||||
// player& operator=(player&& other) noexcept = default;
|
||||
|
||||
u32 load_bank(std::filesystem::path& path, size_t offset);
|
||||
|
||||
u32 play_sound(u32 bank, u32 sound, s32 vol, s32 pan, s32 pm, s32 pb);
|
||||
void set_midi_reg(u32 sound_id, u8 reg, u8 value);
|
||||
bool sound_still_active(u32 sound_id);
|
||||
void set_master_volume(u32 group, s32 volume);
|
||||
void unload_bank(u32 bank_handle);
|
||||
void stop_sound(u32 sound_handle);
|
||||
void set_pan_table(vol_pair* pantable);
|
||||
void set_playback_mode(s32 mode);
|
||||
void pause_sound(s32 sound_handle);
|
||||
void continue_sound(s32 sound_handle);
|
||||
void pause_all_sounds_in_group(u8 group);
|
||||
void continue_all_sounds_in_group(u8 group);
|
||||
void set_sound_vol_pan(s32 sound_handle, s32 vol, s32 pan);
|
||||
void submit_voice(std::shared_ptr<voice>& voice) { m_synth.add_voice(voice); };
|
||||
void set_sound_pmod(s32 sound_handle, s32 mod);
|
||||
void init_cubeb();
|
||||
void destroy_cubeb();
|
||||
s32 get_tick() { return m_tick; };
|
||||
|
||||
private:
|
||||
std::recursive_mutex m_ticklock; // TODO does not need to recursive with some light restructuring
|
||||
id_allocator m_handle_allocator;
|
||||
std::unordered_map<u32, std::unique_ptr<sound_handler>> m_handlers;
|
||||
|
||||
void tick(s16_output* stream, int samples);
|
||||
|
||||
#ifdef _WIN32
|
||||
bool m_coinitialized = false;
|
||||
#endif
|
||||
|
||||
loader m_loader;
|
||||
synth m_synth;
|
||||
voice_manager m_vmanager;
|
||||
s32 m_tick{0};
|
||||
|
||||
cubeb* m_ctx{nullptr};
|
||||
cubeb_stream* m_stream{nullptr};
|
||||
|
||||
static long sound_callback(cubeb_stream* stream,
|
||||
void* user,
|
||||
const void* input,
|
||||
void* output_buffer,
|
||||
long len);
|
||||
static void state_callback(cubeb_stream* stream, void* user, cubeb_state state);
|
||||
};
|
||||
} // namespace snd
|
24
game/sound/989snd/sfxblock.cpp
Normal file
24
game/sound/989snd/sfxblock.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include "sfxblock.h"
|
||||
#include "blocksound_handler.h"
|
||||
|
||||
namespace snd {
|
||||
std::unique_ptr<sound_handler> SFXBlock::make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
s32 pm,
|
||||
s32 pb) {
|
||||
std::unique_ptr<blocksound_handler> handler;
|
||||
auto& SFX = sounds[sound_id];
|
||||
|
||||
if (SFX.grains.empty()) {
|
||||
// fmt::print("skipping empty sfx\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
handler = std::make_unique<blocksound_handler>(sounds[sound_id], vm, vol, pan, pm, pb, bank_id);
|
||||
handler->init();
|
||||
return handler;
|
||||
}
|
||||
|
||||
} // namespace snd
|
127
game/sound/989snd/sfxblock.h
Normal file
127
game/sound/989snd/sfxblock.h
Normal file
@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "soundbank.h"
|
||||
|
||||
namespace snd {
|
||||
|
||||
struct SFXBlockData : BankTag {
|
||||
/* 10 */ s8 BlockNum;
|
||||
/* 11 */ s8 pad1;
|
||||
/* 12 */ s16 pad2;
|
||||
/* 14 */ s16 pad3;
|
||||
/* 16 */ s16 NumSounds;
|
||||
/* 18 */ s16 NumGrains;
|
||||
/* 1a */ s16 NumVAGs;
|
||||
/* 1c */ u32 FirstSound;
|
||||
/* 20 */ u32 FirstGrain;
|
||||
/* 24 */ u32 VagsInSR;
|
||||
/* 28 */ u32 VagDataSize;
|
||||
/* 2c */ u32 SRAMAllocSize;
|
||||
/* 30 */ u32 NextBlock;
|
||||
/* 34 */ u32 BlockNames;
|
||||
/* 38 */ u32 SFXUD;
|
||||
};
|
||||
|
||||
static_assert(sizeof(SFXBlockData) == 0x38 + 4);
|
||||
|
||||
struct XREFGrainParams {
|
||||
/* 0 */ u32 BankID;
|
||||
/* 4 */ u32 SoundIndex;
|
||||
/* 8 */ s32 PitchMod;
|
||||
/* c */ u32 Flags;
|
||||
};
|
||||
|
||||
struct RandDelayParams {
|
||||
/* 0 */ s32 Amount;
|
||||
};
|
||||
|
||||
struct ControlParams {
|
||||
/* 0 */ s16 param[4];
|
||||
};
|
||||
|
||||
struct LFOParams {
|
||||
/* 0 */ u8 which_lfo;
|
||||
/* 1 */ u8 target;
|
||||
/* 2 */ u8 target_extra;
|
||||
/* 3 */ u8 shape;
|
||||
/* 4 */ u16 duty_cycle;
|
||||
/* 6 */ u16 depth;
|
||||
/* 8 */ u16 flags;
|
||||
/* a */ u16 start_offset;
|
||||
/* c */ u32 step_size;
|
||||
};
|
||||
|
||||
struct PlaySoundParams {
|
||||
/* 0 */ s32 vol;
|
||||
/* 4 */ s32 pan;
|
||||
/* 8 */ s8 reg_settings[4];
|
||||
/* c */ s32 sound_id;
|
||||
/* 10 */ char snd_name[16];
|
||||
};
|
||||
|
||||
struct PluginParams {
|
||||
/* 0 */ u32 id;
|
||||
/* 4 */ u32 index;
|
||||
/* 8 */ u8 data[24];
|
||||
};
|
||||
|
||||
struct LargestGrainParamStruct {
|
||||
/* 0 */ char blank[32];
|
||||
};
|
||||
|
||||
/*
|
||||
** Type 1 = Tone
|
||||
*/
|
||||
|
||||
struct SFXGrain {
|
||||
/* 0 */ u32 Type;
|
||||
/* 4 */ s32 Delay;
|
||||
union {
|
||||
/* 8 */ Tone tone;
|
||||
/* 8 */ XREFGrainParams xref;
|
||||
/* 8 */ RandDelayParams delay;
|
||||
/* 8 */ ControlParams control;
|
||||
/* 8 */ LFOParams lfo;
|
||||
/* 8 */ PlaySoundParams play_sound;
|
||||
/* 8 */ PluginParams plugin_params;
|
||||
/* 8 */ LargestGrainParamStruct junk;
|
||||
} GrainParams;
|
||||
};
|
||||
|
||||
struct SFXData {
|
||||
/* 0 */ s8 Vol;
|
||||
/* 1 */ s8 VolGroup;
|
||||
/* 2 */ s16 Pan;
|
||||
/* 4 */ s8 NumGrains;
|
||||
/* 5 */ s8 InstanceLimit;
|
||||
/* 6 */ u16 Flags;
|
||||
/* 8 */ u32 FirstGrain;
|
||||
};
|
||||
|
||||
enum SFXFlags {
|
||||
Looper = 1,
|
||||
SoloSound = 2, // Stop previous instances
|
||||
};
|
||||
|
||||
struct SFX {
|
||||
SFXData d;
|
||||
std::vector<SFXGrain> grains;
|
||||
};
|
||||
|
||||
class SFXBlock : public SoundBank {
|
||||
public:
|
||||
SFXBlock(locator& loc) : m_locator(loc) {}
|
||||
std::unique_ptr<sound_handler> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
s32 pm,
|
||||
s32 pb) override;
|
||||
|
||||
std::vector<SFX> sounds;
|
||||
|
||||
private:
|
||||
locator& m_locator;
|
||||
};
|
||||
|
||||
} // namespace snd
|
28
game/sound/989snd/sndplay.cpp
Normal file
28
game/sound/989snd/sndplay.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
#include "player.h"
|
||||
#include <filesystem>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
snd::player player;
|
||||
unsigned bankid = 0;
|
||||
|
||||
std::filesystem::path file = argv[1];
|
||||
|
||||
if (argc > 2) {
|
||||
bankid = player.load_bank(file, 0);
|
||||
unsigned sound = player.play_sound(bankid, atoi(argv[2]), 0x400, 0, 0, 0);
|
||||
fmt::print("sound {} started\n", sound);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
timespec rqtp{}, rmtp{};
|
||||
rqtp.tv_nsec = 0;
|
||||
rqtp.tv_sec = 1;
|
||||
#ifdef __linux
|
||||
if (nanosleep(&rqtp, &rmtp) == -1) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
25
game/sound/989snd/sound_handler.h
Normal file
25
game/sound/989snd/sound_handler.h
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
static constexpr int PAN_RESET = -1;
|
||||
static constexpr int PAN_DONT_CHANGE = -2;
|
||||
static constexpr int VOLUME_DONT_CHANGE = 0x7fffffff;
|
||||
|
||||
namespace snd {
|
||||
class sound_handler {
|
||||
public:
|
||||
virtual ~sound_handler() = default;
|
||||
virtual bool tick() = 0;
|
||||
virtual u32 bank() = 0;
|
||||
virtual void pause() = 0;
|
||||
virtual void unpause() = 0;
|
||||
virtual u8 group() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual void set_vol_pan(s32 vol, s32 pan) = 0;
|
||||
virtual void set_pmod(s32 mod) = 0;
|
||||
virtual void set_register(u8 reg, u8 value) {}
|
||||
};
|
||||
} // namespace snd
|
38
game/sound/989snd/soundbank.h
Normal file
38
game/sound/989snd/soundbank.h
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include "vagvoice.h"
|
||||
#include "locator.h"
|
||||
#include "sound_handler.h"
|
||||
#include "common/common_types.h"
|
||||
#include "../common/synth.h"
|
||||
|
||||
namespace snd {
|
||||
struct BankTag {
|
||||
/* 0 */ u32 DataID;
|
||||
/* 4 */ u32 Version;
|
||||
/* 8 */ u32 Flags;
|
||||
/* c */ u32 BankID;
|
||||
};
|
||||
|
||||
enum class BankType {
|
||||
Music,
|
||||
SFX,
|
||||
};
|
||||
|
||||
class SoundBank {
|
||||
public:
|
||||
virtual ~SoundBank() = default;
|
||||
BankType type;
|
||||
virtual std::unique_ptr<sound_handler> make_handler(voice_manager& vm,
|
||||
u32 sound_id,
|
||||
s32 vol,
|
||||
s32 pan,
|
||||
s32 pm,
|
||||
s32 pb) = 0;
|
||||
|
||||
u32 bank_id;
|
||||
u32 bank_name;
|
||||
std::unique_ptr<u8[]> sampleBuf;
|
||||
};
|
||||
|
||||
} // namespace snd
|
141
game/sound/989snd/util.cpp
Normal file
141
game/sound/989snd/util.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
#include "util.h"
|
||||
|
||||
namespace snd {
|
||||
const u16 NotePitchTable[] = {
|
||||
0x8000, 0x879C, 0x8FAC, 0x9837, 0xA145, 0xAADC, 0xB504, 0xBFC8, 0xCB2F, 0xD744, 0xE411, 0xF1A1,
|
||||
0x8000, 0x800E, 0x801D, 0x802C, 0x803B, 0x804A, 0x8058, 0x8067, 0x8076, 0x8085, 0x8094, 0x80A3,
|
||||
0x80B1, 0x80C0, 0x80CF, 0x80DE, 0x80ED, 0x80FC, 0x810B, 0x811A, 0x8129, 0x8138, 0x8146, 0x8155,
|
||||
0x8164, 0x8173, 0x8182, 0x8191, 0x81A0, 0x81AF, 0x81BE, 0x81CD, 0x81DC, 0x81EB, 0x81FA, 0x8209,
|
||||
0x8218, 0x8227, 0x8236, 0x8245, 0x8254, 0x8263, 0x8272, 0x8282, 0x8291, 0x82A0, 0x82AF, 0x82BE,
|
||||
0x82CD, 0x82DC, 0x82EB, 0x82FA, 0x830A, 0x8319, 0x8328, 0x8337, 0x8346, 0x8355, 0x8364, 0x8374,
|
||||
0x8383, 0x8392, 0x83A1, 0x83B0, 0x83C0, 0x83CF, 0x83DE, 0x83ED, 0x83FD, 0x840C, 0x841B, 0x842A,
|
||||
0x843A, 0x8449, 0x8458, 0x8468, 0x8477, 0x8486, 0x8495, 0x84A5, 0x84B4, 0x84C3, 0x84D3, 0x84E2,
|
||||
0x84F1, 0x8501, 0x8510, 0x8520, 0x852F, 0x853E, 0x854E, 0x855D, 0x856D, 0x857C, 0x858B, 0x859B,
|
||||
0x85AA, 0x85BA, 0x85C9, 0x85D9, 0x85E8, 0x85F8, 0x8607, 0x8617, 0x8626, 0x8636, 0x8645, 0x8655,
|
||||
0x8664, 0x8674, 0x8683, 0x8693, 0x86A2, 0x86B2, 0x86C1, 0x86D1, 0x86E0, 0x86F0, 0x8700, 0x870F,
|
||||
0x871F, 0x872E, 0x873E, 0x874E, 0x875D, 0x876D, 0x877D, 0x878C};
|
||||
|
||||
u16 sceSdNote2Pitch(u16 center_note, u16 center_fine, u16 note, short fine) {
|
||||
s32 _fine;
|
||||
s32 _fine2;
|
||||
s32 _note;
|
||||
s32 offset1, offset2;
|
||||
s32 val;
|
||||
s32 val2;
|
||||
s32 val3;
|
||||
s32 ret;
|
||||
|
||||
_fine = fine + (u16)center_fine;
|
||||
_fine2 = _fine;
|
||||
|
||||
if (_fine < 0)
|
||||
_fine2 = _fine + 127;
|
||||
|
||||
_fine2 = _fine2 / 128;
|
||||
_note = note + _fine2 - center_note;
|
||||
val3 = _note / 6;
|
||||
|
||||
if (_note < 0)
|
||||
val3--;
|
||||
|
||||
offset2 = _fine - _fine2 * 128;
|
||||
|
||||
if (_note < 0)
|
||||
val2 = -1;
|
||||
else
|
||||
val2 = 0;
|
||||
if (val3 < 0)
|
||||
val3--;
|
||||
|
||||
val2 = (val3 / 2) - val2;
|
||||
val = val2 - 2;
|
||||
offset1 = _note - (val2 * 12);
|
||||
|
||||
if ((offset1 < 0) || ((offset1 == 0) && (offset2 < 0))) {
|
||||
offset1 = offset1 + 12;
|
||||
val = val2 - 3;
|
||||
}
|
||||
|
||||
if (offset2 < 0) {
|
||||
offset1 = (offset1 - 1) + _fine2;
|
||||
offset2 += (_fine2 + 1) * 128;
|
||||
}
|
||||
|
||||
ret = (NotePitchTable[offset1] * NotePitchTable[offset2 + 12]) / 0x10000;
|
||||
|
||||
if (val < 0)
|
||||
ret = (ret + (1 << (-val - 1))) >> -val;
|
||||
|
||||
return (u16)ret;
|
||||
}
|
||||
|
||||
const vol_pair normalPanTable[181] = {
|
||||
{0x3fff, 0x0000}, {0x3ffe, 0x008e}, {0x3ffc, 0x011d}, {0x3ff9, 0x01ac}, {0x3ff5, 0x023b},
|
||||
{0x3fef, 0x02ca}, {0x3fe8, 0x0359}, {0x3fe0, 0x03e8}, {0x3fd7, 0x0476}, {0x3fcc, 0x0505},
|
||||
{0x3fc0, 0x0593}, {0x3fb3, 0x0622}, {0x3fa5, 0x06b0}, {0x3f95, 0x073e}, {0x3f84, 0x07cc},
|
||||
{0x3f72, 0x085a}, {0x3f5f, 0x08e8}, {0x3f4b, 0x0975}, {0x3f35, 0x0a02}, {0x3f1e, 0x0a8f},
|
||||
{0x3f06, 0x0b1c}, {0x3eec, 0x0ba9}, {0x3ed1, 0x0c36}, {0x3eb6, 0x0cc2}, {0x3e98, 0x0d4e},
|
||||
{0x3e7a, 0x0dd9}, {0x3e5b, 0x0e65}, {0x3e3a, 0x0ef0}, {0x3e18, 0x0f7b}, {0x3df5, 0x1005},
|
||||
{0x3dd0, 0x1090}, {0x3dab, 0x111a}, {0x3d84, 0x11a3}, {0x3d5c, 0x122d}, {0x3d33, 0x12b5},
|
||||
{0x3d08, 0x133e}, {0x3cdd, 0x13c6}, {0x3cb0, 0x144e}, {0x3c82, 0x14d5}, {0x3c53, 0x155c},
|
||||
{0x3c22, 0x15e3}, {0x3bf1, 0x1669}, {0x3bbe, 0x16ef}, {0x3b8b, 0x1774}, {0x3b56, 0x17f9},
|
||||
{0x3b1f, 0x187d}, {0x3ae8, 0x1901}, {0x3ab0, 0x1984}, {0x3a76, 0x1a07}, {0x3a3b, 0x1a89},
|
||||
{0x3a00, 0x1b0b}, {0x39c3, 0x1b8d}, {0x3984, 0x1c0d}, {0x3945, 0x1c8e}, {0x3905, 0x1d0d},
|
||||
{0x38c3, 0x1d8c}, {0x3881, 0x1e0b}, {0x383d, 0x1e89}, {0x37f8, 0x1f06}, {0x37b3, 0x1f83},
|
||||
{0x376c, 0x1fff}, {0x3724, 0x207b}, {0x36da, 0x20f5}, {0x3690, 0x2170}, {0x3645, 0x21e9},
|
||||
{0x35f9, 0x2262}, {0x35ab, 0x22da}, {0x355d, 0x2352}, {0x350e, 0x23c9}, {0x34bd, 0x243f},
|
||||
{0x346c, 0x24b4}, {0x3419, 0x2529}, {0x33c6, 0x259d}, {0x3371, 0x2610}, {0x331c, 0x2683},
|
||||
{0x32c5, 0x26f5}, {0x326d, 0x2766}, {0x3215, 0x27d6}, {0x31bb, 0x2846}, {0x3161, 0x28b4},
|
||||
{0x3106, 0x2922}, {0x30a9, 0x298f}, {0x304c, 0x29fc}, {0x2fee, 0x2a67}, {0x2f8e, 0x2ad2},
|
||||
{0x2f2e, 0x2b3c}, {0x2ecd, 0x2ba5}, {0x2e6b, 0x2c0d}, {0x2e08, 0x2c74}, {0x2da5, 0x2cda},
|
||||
{0x2d40, 0x2d40}, {0x2cda, 0x2da5}, {0x2c74, 0x2e08}, {0x2c0d, 0x2e6b}, {0x2ba5, 0x2ecd},
|
||||
{0x2b3c, 0x2f2e}, {0x2ad2, 0x2f8e}, {0x2a67, 0x2fee}, {0x29fc, 0x304c}, {0x298f, 0x30a9},
|
||||
{0x2922, 0x3106}, {0x28b4, 0x3161}, {0x2846, 0x31bb}, {0x27d6, 0x3215}, {0x2766, 0x326d},
|
||||
{0x26f5, 0x32c5}, {0x2683, 0x331c}, {0x2610, 0x3371}, {0x259d, 0x33c6}, {0x2529, 0x3419},
|
||||
{0x24b4, 0x346c}, {0x243f, 0x34bd}, {0x23c9, 0x350e}, {0x2352, 0x355d}, {0x22da, 0x35ab},
|
||||
{0x2262, 0x35f9}, {0x21e9, 0x3645}, {0x2170, 0x3690}, {0x20f5, 0x36da}, {0x207b, 0x3724},
|
||||
{0x1fff, 0x376c}, {0x1f83, 0x37b3}, {0x1f06, 0x37f8}, {0x1e89, 0x383d}, {0x1e0b, 0x3881},
|
||||
{0x1d8c, 0x38c3}, {0x1d0d, 0x3905}, {0x1c8e, 0x3945}, {0x1c0d, 0x3984}, {0x1b8d, 0x39c3},
|
||||
{0x1b0b, 0x3a00}, {0x1a89, 0x3a3b}, {0x1a07, 0x3a76}, {0x1984, 0x3ab0}, {0x1901, 0x3ae8},
|
||||
{0x187d, 0x3b1f}, {0x17f9, 0x3b56}, {0x1774, 0x3b8b}, {0x16ef, 0x3bbe}, {0x1669, 0x3bf1},
|
||||
{0x15e3, 0x3c22}, {0x155c, 0x3c53}, {0x14d5, 0x3c82}, {0x144e, 0x3cb0}, {0x13c6, 0x3cdd},
|
||||
{0x133e, 0x3d08}, {0x12b5, 0x3d33}, {0x122d, 0x3d5c}, {0x11a3, 0x3d84}, {0x111a, 0x3dab},
|
||||
{0x1090, 0x3dd0}, {0x1005, 0x3df5}, {0x0f7b, 0x3e18}, {0x0ef0, 0x3e3a}, {0x0e65, 0x3e5b},
|
||||
{0x0dd9, 0x3e7a}, {0x0d4e, 0x3e98}, {0x0cc2, 0x3eb6}, {0x0c36, 0x3ed1}, {0x0ba9, 0x3eec},
|
||||
{0x0b1c, 0x3f06}, {0x0a8f, 0x3f1e}, {0x0a02, 0x3f35}, {0x0975, 0x3f4b}, {0x08e8, 0x3f5f},
|
||||
{0x085a, 0x3f72}, {0x07cc, 0x3f84}, {0x073e, 0x3f95}, {0x06b0, 0x3fa5}, {0x0622, 0x3fb3},
|
||||
{0x0593, 0x3fc0}, {0x0505, 0x3fcc}, {0x0476, 0x3fd7}, {0x03e8, 0x3fe0}, {0x0359, 0x3fe8},
|
||||
{0x02ca, 0x3fef}, {0x023b, 0x3ff5}, {0x01ac, 0x3ff9}, {0x011d, 0x3ffc}, {0x008e, 0x3ffe},
|
||||
};
|
||||
|
||||
u16 PS1Note2Pitch(s8 center_note, s8 center_fine, short note, short fine) {
|
||||
bool ps1_note = false;
|
||||
if (center_note >= 0) {
|
||||
ps1_note = true;
|
||||
} else {
|
||||
center_note = -center_note;
|
||||
}
|
||||
|
||||
u16 pitch = sceSdNote2Pitch(center_note, center_fine, note, fine);
|
||||
if (ps1_note) {
|
||||
pitch = 44100 * pitch / 48000;
|
||||
}
|
||||
|
||||
return pitch;
|
||||
}
|
||||
|
||||
std::pair<s16, s16> pitchbend(Tone& tone,
|
||||
int current_pb,
|
||||
int current_pm,
|
||||
int start_note,
|
||||
int start_fine) {
|
||||
auto v9 = (start_note << 7) + start_fine + current_pm;
|
||||
u32 v7;
|
||||
if (current_pb >= 0)
|
||||
v7 = tone.PBHigh * (current_pb << 7) / 0x7fff + v9;
|
||||
else
|
||||
v7 = tone.PBLow * (current_pb << 7) / 0x7fff + v9;
|
||||
return {v7 / 128, v7 % 128};
|
||||
}
|
||||
|
||||
} // namespace snd
|
20
game/sound/989snd/util.h
Normal file
20
game/sound/989snd/util.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include "game/sound/989snd/vagvoice.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace snd {
|
||||
|
||||
extern const u16 NotePitchTable[];
|
||||
extern const vol_pair normalPanTable[181];
|
||||
|
||||
u16 PS1Note2Pitch(s8 center_note, s8 center_fine, short note, short fine);
|
||||
u16 sceSdNote2Pitch(u16 center_note, u16 center_fine, u16 note, short fine);
|
||||
std::pair<s16, s16> pitchbend(Tone& tone,
|
||||
int current_pb,
|
||||
int current_pm,
|
||||
int start_note,
|
||||
int start_fine);
|
||||
|
||||
} // namespace snd
|
221
game/sound/989snd/vagvoice.cpp
Normal file
221
game/sound/989snd/vagvoice.cpp
Normal file
@ -0,0 +1,221 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#include "vagvoice.h"
|
||||
#include "util.h"
|
||||
#include "../common/voice.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace snd {
|
||||
voice_manager::voice_manager(synth& synth, locator& loc) : m_synth(synth), m_locator(loc) {
|
||||
m_pan_table = normalPanTable;
|
||||
m_master_vol.fill(0x400);
|
||||
m_group_duck.fill(0x10000);
|
||||
}
|
||||
|
||||
void voice_manager::start_tone(std::shared_ptr<vag_voice> voice) {
|
||||
s16 left = adjust_vol_to_group(voice->basevol.left, voice->group);
|
||||
s16 right = adjust_vol_to_group(voice->basevol.right, voice->group);
|
||||
|
||||
voice->set_volume(left >> 1, right >> 1);
|
||||
|
||||
if ((voice->tone.Flags & 0x10) != 0x0) {
|
||||
throw std::runtime_error("reverb only voice not handler");
|
||||
}
|
||||
|
||||
std::pair<s16, s16> note = pitchbend(voice->tone, voice->current_pb, voice->current_pm,
|
||||
voice->start_note, voice->start_fine);
|
||||
|
||||
auto pitch =
|
||||
PS1Note2Pitch(voice->tone.CenterNote, voice->tone.CenterFine, note.first, note.second);
|
||||
|
||||
voice->set_pitch(pitch);
|
||||
voice->set_asdr1(voice->tone.ADSR1);
|
||||
voice->set_asdr2(voice->tone.ADSR2);
|
||||
|
||||
u8* sbuf = m_locator.get_bank_samples(voice->tone.BankID);
|
||||
voice->set_sample((u16*)(sbuf + voice->tone.VAGInSR));
|
||||
|
||||
voice->key_on();
|
||||
|
||||
clean_voices();
|
||||
m_voices.emplace_front(voice);
|
||||
m_synth.add_voice(voice);
|
||||
}
|
||||
vol_pair voice_manager::make_volume(int vol1, int pan1, int vol2, int pan2, int vol3, int pan3) {
|
||||
// Scale up as close as we can to max positive 16bit volume
|
||||
// I'd have just used shifting but I guess this does get closer
|
||||
|
||||
s32 vol = vol1 * 258;
|
||||
vol = (vol * vol2) / 0x7f;
|
||||
vol = (vol * vol3) / 0x7f;
|
||||
|
||||
// volume accurate up to here for sure
|
||||
if (vol == 0) {
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
if (m_stereo_or_mono == 1) {
|
||||
return {(s16)vol, (s16)vol};
|
||||
}
|
||||
|
||||
int total_pan = pan1 + pan3 + pan2;
|
||||
while (total_pan >= 360) {
|
||||
total_pan -= 360;
|
||||
}
|
||||
|
||||
while (total_pan < 0) {
|
||||
total_pan += 360;
|
||||
}
|
||||
|
||||
if (total_pan >= 270) {
|
||||
total_pan -= 270;
|
||||
} else {
|
||||
total_pan += 90;
|
||||
}
|
||||
|
||||
// fmt::print("total pan {}\n", total_pan);
|
||||
s16 lvol = 0;
|
||||
s16 rvol = 0;
|
||||
|
||||
// TODO Presumable for the purposes of some effects this function needs
|
||||
// to know the sign of the previous volume so that it can maintain
|
||||
// it. (For surround audio positioning?)
|
||||
|
||||
if (total_pan < 180) {
|
||||
lvol = (m_pan_table[total_pan].left * vol) / 0x3fff;
|
||||
rvol = (m_pan_table[total_pan].right * vol) / 0x3fff;
|
||||
} else {
|
||||
rvol = (m_pan_table[total_pan - 180].left * vol) / 0x3fff;
|
||||
lvol = (m_pan_table[total_pan - 180].right * vol) / 0x3fff;
|
||||
}
|
||||
|
||||
// TODO rest of this function
|
||||
// there is a whole bunch of math depending on what the volume was previously?
|
||||
|
||||
return {lvol, rvol};
|
||||
}
|
||||
|
||||
vol_pair voice_manager::make_volume_b(int sound_vol,
|
||||
int velocity_volume,
|
||||
int pan,
|
||||
int prog_vol,
|
||||
int prog_pan,
|
||||
int tone_vol,
|
||||
int tone_pan) {
|
||||
// Scale up as close as we can to max positive 16bit volume
|
||||
// I'd have just used shifting but I guess this does get closer
|
||||
|
||||
s32 vol = sound_vol * 258;
|
||||
vol = (vol * velocity_volume) / 0x7f;
|
||||
vol = (vol * prog_vol) / 0x7f;
|
||||
vol = (vol * tone_vol) / 0x7f;
|
||||
|
||||
// volume accurate up to here for sure
|
||||
if (vol == 0) {
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
if (m_stereo_or_mono == 1) {
|
||||
return {(s16)vol, (s16)vol};
|
||||
}
|
||||
|
||||
int total_pan = pan + tone_pan + prog_pan;
|
||||
while (total_pan >= 360) {
|
||||
total_pan -= 360;
|
||||
}
|
||||
|
||||
while (total_pan < 0) {
|
||||
total_pan += 360;
|
||||
}
|
||||
|
||||
if (total_pan >= 270) {
|
||||
total_pan -= 270;
|
||||
} else {
|
||||
total_pan += 90;
|
||||
}
|
||||
|
||||
// fmt::print("total pan {}\n", total_pan);
|
||||
s16 lvol = 0;
|
||||
s16 rvol = 0;
|
||||
|
||||
// TODO Presumable for the purposes of some effects this function needs
|
||||
// to know the sign of the previous volume so that it can maintain
|
||||
// it. (For surround audio positioning?)
|
||||
|
||||
if (total_pan < 180) {
|
||||
lvol = (m_pan_table[total_pan].left * vol) / 0x3fff;
|
||||
rvol = (m_pan_table[total_pan].right * vol) / 0x3fff;
|
||||
} else {
|
||||
rvol = (m_pan_table[total_pan - 180].left * vol) / 0x3fff;
|
||||
lvol = (m_pan_table[total_pan - 180].right * vol) / 0x3fff;
|
||||
}
|
||||
|
||||
// TODO rest of this function
|
||||
// there is a whole bunch of math depending on what the volume was previously?
|
||||
|
||||
return {lvol, rvol};
|
||||
}
|
||||
|
||||
s16 voice_manager::adjust_vol_to_group(s16 involume, int group) {
|
||||
s32 volume = involume;
|
||||
// NOTE grou >= 7 in version 2
|
||||
if (group >= 15)
|
||||
return volume;
|
||||
|
||||
if (volume >= 0x7fff)
|
||||
volume = 0x7ffe;
|
||||
|
||||
// NOTE no duckers in version 2
|
||||
s32 modifier = (m_master_vol[group] * m_group_duck[group]) / 0x10000;
|
||||
volume = (volume * modifier) / 0x400;
|
||||
int sign = 1;
|
||||
if (volume < 0) {
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
// fmt::print("made volume {:x} -> {:x}\n", involume, volume);
|
||||
s16 retval = static_cast<s16>((volume * volume) / 0x7ffe * sign);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void voice_manager::set_master_vol(u8 group, s32 volume) {
|
||||
m_master_vol[group] = volume;
|
||||
|
||||
for (auto& p : m_voices) {
|
||||
auto voice = p.lock();
|
||||
if (voice == nullptr || voice->paused) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (voice->group == group) {
|
||||
s16 left = adjust_vol_to_group(voice->basevol.left, voice->group);
|
||||
s16 right = adjust_vol_to_group(voice->basevol.right, voice->group);
|
||||
|
||||
voice->set_volume(left >> 1, right >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void voice_manager::pause(std::shared_ptr<vag_voice> voice) {
|
||||
voice->set_volume(0, 0);
|
||||
voice->set_pitch(0);
|
||||
voice->paused = true;
|
||||
}
|
||||
|
||||
void voice_manager::unpause(std::shared_ptr<vag_voice> voice) {
|
||||
s16 left = adjust_vol_to_group(voice->basevol.left, voice->group);
|
||||
s16 right = adjust_vol_to_group(voice->basevol.right, voice->group);
|
||||
|
||||
voice->set_volume(left >> 1, right >> 1);
|
||||
|
||||
std::pair<s16, s16> note = pitchbend(voice->tone, voice->current_pb, voice->current_pm,
|
||||
voice->start_note, voice->start_fine);
|
||||
|
||||
auto pitch =
|
||||
PS1Note2Pitch(voice->tone.CenterNote, voice->tone.CenterFine, note.first, note.second);
|
||||
|
||||
voice->set_pitch(pitch);
|
||||
voice->paused = false;
|
||||
}
|
||||
|
||||
}; // namespace snd
|
92
game/sound/989snd/vagvoice.h
Normal file
92
game/sound/989snd/vagvoice.h
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#pragma once
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include "common/common_types.h"
|
||||
#include "locator.h"
|
||||
#include "game/sound/common/synth.h"
|
||||
#include "game/sound/common/voice.h"
|
||||
|
||||
namespace snd {
|
||||
|
||||
enum class toneflag : u16 {
|
||||
out_reverb = 1,
|
||||
out_dry = 0x10,
|
||||
};
|
||||
|
||||
struct Tone {
|
||||
/* 0 */ s8 Priority;
|
||||
/* 1 */ s8 Vol;
|
||||
/* 2 */ s8 CenterNote;
|
||||
/* 3 */ s8 CenterFine;
|
||||
/* 4 */ s16 Pan;
|
||||
/* 6 */ s8 MapLow;
|
||||
/* 7 */ s8 MapHigh;
|
||||
/* 8 */ s8 PBLow;
|
||||
/* 9 */ s8 PBHigh;
|
||||
/* a */ s16 ADSR1;
|
||||
/* c */ s16 ADSR2;
|
||||
/* e */ s16 Flags;
|
||||
/* 10 */ /*void**/ u32 VAGInSR;
|
||||
///* 14 */ u32 reserved1; confiscated
|
||||
|
||||
// FIXME I'd rather restructure things than mess about like this.
|
||||
// If we have to edit the structs they should't be loaded like this
|
||||
/* 14 */ u32 BankID;
|
||||
};
|
||||
|
||||
class vag_voice : public voice {
|
||||
public:
|
||||
vag_voice(Tone& t) : tone(t) {}
|
||||
Tone& tone;
|
||||
u8 group{0};
|
||||
vol_pair basevol{};
|
||||
s32 current_pm{0};
|
||||
s32 current_pb{0};
|
||||
s32 start_note{0};
|
||||
s32 start_fine{0};
|
||||
bool paused{false};
|
||||
};
|
||||
|
||||
class voice_manager {
|
||||
public:
|
||||
voice_manager(synth& synth, locator& loc);
|
||||
void start_tone(std::shared_ptr<vag_voice> voice);
|
||||
void pause(std::shared_ptr<vag_voice> voice);
|
||||
void unpause(std::shared_ptr<vag_voice> voice);
|
||||
void set_pan_table(vol_pair* table) { m_pan_table = table; };
|
||||
|
||||
vol_pair make_volume(int vol1, int pan1, int vol2, int pan2, int vol3, int pan3);
|
||||
|
||||
// This is super silly, but it's what 989snd does
|
||||
vol_pair make_volume_b(int sound_vol,
|
||||
int velocity_volume,
|
||||
int pan,
|
||||
int prog_vol,
|
||||
int prog_pan,
|
||||
int tone_vol,
|
||||
int tone_pan);
|
||||
|
||||
void set_master_vol(u8 group, s32 volume);
|
||||
void set_playback_mode(s32 mode) { m_stereo_or_mono = mode; }
|
||||
s16 adjust_vol_to_group(s16 involume, int group);
|
||||
|
||||
private:
|
||||
synth& m_synth;
|
||||
locator& m_locator;
|
||||
|
||||
std::list<std::weak_ptr<vag_voice>> m_voices;
|
||||
void clean_voices() {
|
||||
m_voices.remove_if([](auto& v) { return v.expired(); });
|
||||
}
|
||||
|
||||
s32 m_stereo_or_mono{0};
|
||||
|
||||
std::array<s32, 32> m_master_vol;
|
||||
std::array<s32, 32> m_group_duck;
|
||||
|
||||
const vol_pair* m_pan_table{nullptr};
|
||||
};
|
||||
|
||||
} // namespace snd
|
24
game/sound/CMakeLists.txt
Normal file
24
game/sound/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
set(SOUND_SOURCES
|
||||
989snd/player.cpp
|
||||
989snd/midi_handler.cpp
|
||||
989snd/ame_handler.cpp
|
||||
989snd/blocksound_handler.cpp
|
||||
989snd/musicbank.cpp
|
||||
989snd/sfxblock.cpp
|
||||
989snd/loader.cpp
|
||||
989snd/vagvoice.cpp
|
||||
989snd/util.cpp
|
||||
common/synth.cpp
|
||||
common/voice.cpp
|
||||
common/envelope.cpp
|
||||
sndshim.cpp
|
||||
sdshim.cpp
|
||||
)
|
||||
|
||||
add_library(sound STATIC ${SOUND_SOURCES})
|
||||
target_link_libraries(sound PRIVATE fmt cubeb)
|
||||
|
||||
add_executable(sndplay 989snd/sndplay.cpp)
|
||||
target_link_libraries(sndplay PRIVATE sound cubeb)
|
21
game/sound/common/bitfield.h
Normal file
21
game/sound/common/bitfield.h
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#pragma once
|
||||
|
||||
/* Bitfield convenience class for use with unions
|
||||
* should be allowed as per common initial subsequence rule regarding unions */
|
||||
template <typename sourcetype, typename type, int pos, int width>
|
||||
class bitfield {
|
||||
public:
|
||||
constexpr type get() { return static_cast<type>((underlying >> pos) & mask()); };
|
||||
|
||||
constexpr void set(type value) {
|
||||
underlying &= ~(mask() << pos);
|
||||
underlying |= (value & mask()) << pos;
|
||||
};
|
||||
|
||||
private:
|
||||
sourcetype underlying;
|
||||
|
||||
constexpr int mask() { return (1 << width) - 1; };
|
||||
};
|
164
game/sound/common/envelope.cpp
Normal file
164
game/sound/common/envelope.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
|
||||
#include "envelope.h"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
||||
namespace snd {
|
||||
void Envelope::Step() {
|
||||
// arbitrary number of bits, this is probably incorrect for the
|
||||
// "reserved" and infinite duration values
|
||||
// test hw or copy mednafen instead?
|
||||
u32 cStep = 0x800000;
|
||||
|
||||
s32 shift = m_Shift - 11;
|
||||
if (shift > 0)
|
||||
cStep >>= shift;
|
||||
|
||||
s16 step = static_cast<s16>(m_Step << std::max(0, 11 - m_Shift));
|
||||
|
||||
if (m_Exp) {
|
||||
if (!m_Decrease && m_Level > 0x6000)
|
||||
cStep >>= 2;
|
||||
|
||||
if (m_Decrease)
|
||||
step = static_cast<s16>((step * m_Level) >> 15);
|
||||
}
|
||||
|
||||
m_Counter += cStep;
|
||||
|
||||
if (m_Counter >= 0x800000) {
|
||||
m_Counter = 0;
|
||||
m_Level = std::clamp<s32>(m_Level + step, 0, INT16_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
void ADSR::Run() {
|
||||
// Let's not waste time calculating silent voices
|
||||
if (m_Phase == Phase::Stopped)
|
||||
return;
|
||||
|
||||
Step();
|
||||
|
||||
if (m_Phase == Phase::Sustain)
|
||||
return;
|
||||
|
||||
if ((!m_Decrease && m_Level >= m_Target) || (m_Decrease && m_Level <= m_Target)) {
|
||||
switch (m_Phase) {
|
||||
case Phase::Attack:
|
||||
m_Phase = Phase::Decay;
|
||||
break;
|
||||
case Phase::Decay:
|
||||
m_Phase = Phase::Sustain;
|
||||
break;
|
||||
case Phase::Release:
|
||||
m_Phase = Phase::Stopped;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateSettings();
|
||||
}
|
||||
}
|
||||
|
||||
void ADSR::UpdateSettings() {
|
||||
switch (m_Phase) {
|
||||
case Phase::Attack:
|
||||
m_Exp = m_Reg.AttackExp.get();
|
||||
m_Decrease = false;
|
||||
m_Shift = m_Reg.AttackShift.get();
|
||||
m_Step = static_cast<s8>(7 - m_Reg.AttackStep.get());
|
||||
m_Target = 0x7FFF;
|
||||
break;
|
||||
case Phase::Decay:
|
||||
m_Exp = true;
|
||||
m_Decrease = true;
|
||||
m_Shift = m_Reg.DecayShift.get();
|
||||
m_Step = -8;
|
||||
m_Target = (m_Reg.SustainLevel.get() + 1) << 11;
|
||||
break;
|
||||
case Phase::Sustain:
|
||||
m_Exp = m_Reg.SustainExp.get();
|
||||
m_Decrease = m_Reg.SustainDecr.get();
|
||||
m_Shift = m_Reg.SustainShift.get();
|
||||
m_Step = m_Decrease ? static_cast<s8>(-8 + m_Reg.SustainStep.get())
|
||||
: static_cast<s8>(7 - m_Reg.SustainStep.get());
|
||||
m_Target = 0; // unused for sustain
|
||||
break;
|
||||
case Phase::Release:
|
||||
m_Exp = m_Reg.ReleaseExp.get();
|
||||
m_Decrease = true;
|
||||
m_Shift = m_Reg.ReleaseShift.get();
|
||||
m_Step = -8;
|
||||
m_Target = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ADSR::Attack() {
|
||||
m_Phase = Phase::Attack;
|
||||
m_Level = 0;
|
||||
m_Counter = 0;
|
||||
UpdateSettings();
|
||||
}
|
||||
|
||||
void ADSR::Release() {
|
||||
m_Phase = Phase::Release;
|
||||
m_Counter = 0;
|
||||
UpdateSettings();
|
||||
}
|
||||
|
||||
void ADSR::Stop() {
|
||||
m_Phase = Phase::Stopped;
|
||||
m_Level = 0;
|
||||
}
|
||||
|
||||
s16 ADSR::Level() const {
|
||||
return static_cast<u16>(m_Level);
|
||||
}
|
||||
|
||||
void Volume::Run() {
|
||||
if (!m_Sweep.EnableSweep.get())
|
||||
return;
|
||||
|
||||
Step();
|
||||
}
|
||||
|
||||
void Volume::Set(u16 volume) {
|
||||
m_Sweep.bits = volume;
|
||||
|
||||
if (!m_Sweep.EnableSweep.get()) {
|
||||
m_Level = static_cast<s16>(m_Sweep.bits << 1);
|
||||
return;
|
||||
}
|
||||
|
||||
m_Exp = m_Sweep.SweepExp.get();
|
||||
m_Decrease = m_Sweep.SweepDecrease.get();
|
||||
m_Shift = m_Sweep.SweepShift.get();
|
||||
m_Step = m_Decrease ? static_cast<s8>(-8 + m_Sweep.SweepStep.get())
|
||||
: static_cast<s8>(7 - m_Sweep.SweepStep.get());
|
||||
|
||||
if (m_Exp && m_Decrease) {
|
||||
// if (m_Sweep.NegativePhase)
|
||||
// Console.WriteLn("Disqualified from inv");
|
||||
m_Inv = false;
|
||||
} else {
|
||||
m_Inv = m_Sweep.NegativePhase.get();
|
||||
}
|
||||
|
||||
// Console.WriteLn(Color_Red, "start sweep, e:%d d:%d sh:%d st:%d inv:%d", m_Exp, m_Decrease,
|
||||
// m_Shift, m_Step, m_Inv); Console.WriteLn(Color_Red, "Current level %08x", m_Level);
|
||||
}
|
||||
|
||||
u16 Volume::Get() const {
|
||||
return m_Sweep.bits;
|
||||
}
|
||||
|
||||
s16 Volume::GetCurrent() const {
|
||||
return static_cast<s16>(m_Level);
|
||||
}
|
||||
} // namespace snd
|
130
game/sound/common/envelope.h
Normal file
130
game/sound/common/envelope.h
Normal file
@ -0,0 +1,130 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#pragma once
|
||||
|
||||
#include "bitfield.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace snd {
|
||||
union ADSRReg {
|
||||
u32 bits;
|
||||
|
||||
bitfield<u32, u16, 16, 16> hi;
|
||||
bitfield<u32, u16, 0, 16> lo;
|
||||
|
||||
bitfield<u32, bool, 31, 1> SustainExp;
|
||||
bitfield<u32, bool, 30, 1> SustainDecr;
|
||||
bitfield<u32, u8, 29, 1> Unused;
|
||||
bitfield<u32, u8, 24, 5> SustainShift;
|
||||
bitfield<u32, u8, 22, 2> SustainStep;
|
||||
bitfield<u32, bool, 21, 1> ReleaseExp;
|
||||
bitfield<u32, u8, 16, 5> ReleaseShift;
|
||||
|
||||
bitfield<u32, bool, 15, 1> AttackExp;
|
||||
bitfield<u32, u8, 10, 5> AttackShift;
|
||||
bitfield<u32, u8, 8, 2> AttackStep;
|
||||
bitfield<u32, u8, 4, 4> DecayShift;
|
||||
bitfield<u32, u8, 0, 4> SustainLevel;
|
||||
};
|
||||
|
||||
union VolReg {
|
||||
u16 bits;
|
||||
|
||||
bitfield<u16, bool, 15, 1> EnableSweep;
|
||||
bitfield<u16, bool, 14, 1> SweepExp;
|
||||
bitfield<u16, bool, 13, 1> SweepDecrease;
|
||||
bitfield<u16, bool, 12, 1> NegativePhase;
|
||||
bitfield<u16, u8, 2, 5> SweepShift;
|
||||
bitfield<u16, u8, 0, 2> SweepStep;
|
||||
};
|
||||
|
||||
class Envelope {
|
||||
public:
|
||||
void Step();
|
||||
|
||||
protected:
|
||||
u8 m_Shift{0};
|
||||
s8 m_Step{0};
|
||||
bool m_Inv{false};
|
||||
bool m_Exp{false};
|
||||
bool m_Decrease{false};
|
||||
|
||||
u32 m_Counter{0};
|
||||
s32 m_Level{0};
|
||||
};
|
||||
|
||||
class ADSR : Envelope {
|
||||
public:
|
||||
enum class Phase {
|
||||
Attack,
|
||||
Decay,
|
||||
Sustain,
|
||||
Release,
|
||||
Stopped,
|
||||
};
|
||||
|
||||
void Run();
|
||||
void Attack();
|
||||
void Release();
|
||||
void Stop();
|
||||
[[nodiscard]] s16 Level() const;
|
||||
void SetLevel(s16 value) { m_Level = value; }
|
||||
void UpdateSettings();
|
||||
ADSRReg m_Reg{0};
|
||||
[[nodiscard]] Phase GetPhase() const { return m_Phase; }
|
||||
|
||||
void Reset() {
|
||||
m_Phase = Phase::Stopped;
|
||||
m_Target = 0;
|
||||
m_Counter = 0;
|
||||
m_Level = 0;
|
||||
m_Exp = false;
|
||||
m_Decrease = false;
|
||||
m_Inv = false;
|
||||
m_Step = 0;
|
||||
m_Shift = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
Phase m_Phase{Phase::Stopped};
|
||||
s32 m_Target{0};
|
||||
};
|
||||
|
||||
class Volume : Envelope {
|
||||
public:
|
||||
void Run();
|
||||
void Set(u16 volume);
|
||||
[[nodiscard]] u16 Get() const;
|
||||
[[nodiscard]] s16 GetCurrent() const;
|
||||
|
||||
void Reset() {
|
||||
m_Sweep.bits = 0;
|
||||
|
||||
m_Counter = 0;
|
||||
m_Level = 0;
|
||||
m_Exp = false;
|
||||
m_Decrease = false;
|
||||
m_Inv = false;
|
||||
m_Step = 0;
|
||||
m_Shift = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
VolReg m_Sweep{0};
|
||||
};
|
||||
|
||||
struct VolumePair {
|
||||
Volume left{};
|
||||
Volume right{};
|
||||
|
||||
void Run() {
|
||||
left.Run();
|
||||
right.Run();
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
left.Reset();
|
||||
right.Reset();
|
||||
}
|
||||
};
|
||||
} // namespace snd
|
41
game/sound/common/fifo.h
Normal file
41
game/sound/common/fifo.h
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
// This class is only valid for sizes that are power of two
|
||||
template <typename Tp, size_t Nm>
|
||||
class fifo {
|
||||
public:
|
||||
Tp Pop() { return array[Mask(read++)]; }
|
||||
void Push(Tp val) { array[Mask(write++)] = val; }
|
||||
|
||||
Tp& Front() { return array[Mask(read)]; }
|
||||
Tp& Back() { return array[Mask(write)]; }
|
||||
|
||||
Tp Peek() { return array[Mask(read + 1)]; }
|
||||
Tp Peek(size_t offset) { return array[Mask(read + offset)]; }
|
||||
|
||||
size_t Size() { return write - read; }
|
||||
bool Full() { return Size() == capacity; }
|
||||
bool Empty() { return read == write; }
|
||||
|
||||
void Reset() {
|
||||
array.fill(Tp{});
|
||||
read = 0;
|
||||
write = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr bool is_power_of_two(int v) { return v && ((v & (v - 1)) == 0); }
|
||||
static_assert(is_power_of_two(Nm), "FIFO size must be power of 2 for correct operation");
|
||||
|
||||
size_t Mask(size_t val) { return val & (capacity - 1); }
|
||||
|
||||
std::array<Tp, Nm> array = {};
|
||||
size_t capacity = Nm;
|
||||
size_t read = {};
|
||||
size_t write = {};
|
||||
};
|
258
game/sound/common/interp_table.inc
Normal file
258
game/sound/common/interp_table.inc
Normal file
@ -0,0 +1,258 @@
|
||||
std::array<std::array<s16, 4>, 256> interp_table = { {
|
||||
{ 0x12C7, 0x59B3, 0x1307, -0x0001 },
|
||||
{ 0x1288, 0x59B2, 0x1347, -0x0001 },
|
||||
{ 0x1249, 0x59B0, 0x1388, -0x0001 },
|
||||
{ 0x120B, 0x59AD, 0x13C9, -0x0001 },
|
||||
{ 0x11CD, 0x59A9, 0x140B, -0x0001 },
|
||||
{ 0x118F, 0x59A4, 0x144D, -0x0001 },
|
||||
{ 0x1153, 0x599E, 0x1490, -0x0001 },
|
||||
{ 0x1116, 0x5997, 0x14D4, -0x0001 },
|
||||
{ 0x10DB, 0x598F, 0x1517, -0x0001 },
|
||||
{ 0x109F, 0x5986, 0x155C, -0x0001 },
|
||||
{ 0x1065, 0x597C, 0x15A0, -0x0001 },
|
||||
{ 0x102A, 0x5971, 0x15E6, -0x0001 },
|
||||
{ 0x0FF1, 0x5965, 0x162C, -0x0001 },
|
||||
{ 0x0FB7, 0x5958, 0x1672, -0x0001 },
|
||||
{ 0x0F7F, 0x5949, 0x16B9, -0x0001 },
|
||||
{ 0x0F46, 0x593A, 0x1700, -0x0001 },
|
||||
{ 0x0F0F, 0x592A, 0x1747, 0x0000 },
|
||||
{ 0x0ED7, 0x5919, 0x1790, 0x0000 },
|
||||
{ 0x0EA1, 0x5907, 0x17D8, 0x0000 },
|
||||
{ 0x0E6B, 0x58F4, 0x1821, 0x0000 },
|
||||
{ 0x0E35, 0x58E0, 0x186B, 0x0000 },
|
||||
{ 0x0E00, 0x58CB, 0x18B5, 0x0000 },
|
||||
{ 0x0DCB, 0x58B5, 0x1900, 0x0000 },
|
||||
{ 0x0D97, 0x589E, 0x194B, 0x0001 },
|
||||
{ 0x0D63, 0x5886, 0x1996, 0x0001 },
|
||||
{ 0x0D30, 0x586D, 0x19E2, 0x0001 },
|
||||
{ 0x0CFD, 0x5853, 0x1A2E, 0x0001 },
|
||||
{ 0x0CCB, 0x5838, 0x1A7B, 0x0002 },
|
||||
{ 0x0C99, 0x581C, 0x1AC8, 0x0002 },
|
||||
{ 0x0C68, 0x57FF, 0x1B16, 0x0002 },
|
||||
{ 0x0C38, 0x57E2, 0x1B64, 0x0003 },
|
||||
{ 0x0C07, 0x57C3, 0x1BB3, 0x0003 },
|
||||
{ 0x0BD8, 0x57A3, 0x1C02, 0x0003 },
|
||||
{ 0x0BA9, 0x5782, 0x1C51, 0x0004 },
|
||||
{ 0x0B7A, 0x5761, 0x1CA1, 0x0004 },
|
||||
{ 0x0B4C, 0x573E, 0x1CF1, 0x0005 },
|
||||
{ 0x0B1E, 0x571B, 0x1D42, 0x0005 },
|
||||
{ 0x0AF1, 0x56F6, 0x1D93, 0x0006 },
|
||||
{ 0x0AC4, 0x56D1, 0x1DE5, 0x0007 },
|
||||
{ 0x0A98, 0x56AB, 0x1E37, 0x0007 },
|
||||
{ 0x0A6C, 0x5684, 0x1E89, 0x0008 },
|
||||
{ 0x0A40, 0x565B, 0x1EDC, 0x0009 },
|
||||
{ 0x0A16, 0x5632, 0x1F2F, 0x0009 },
|
||||
{ 0x09EB, 0x5609, 0x1F82, 0x000A },
|
||||
{ 0x09C1, 0x55DE, 0x1FD6, 0x000B },
|
||||
{ 0x0998, 0x55B2, 0x202A, 0x000C },
|
||||
{ 0x096F, 0x5585, 0x207F, 0x000D },
|
||||
{ 0x0946, 0x5558, 0x20D4, 0x000E },
|
||||
{ 0x091E, 0x5529, 0x2129, 0x000F },
|
||||
{ 0x08F7, 0x54FA, 0x217F, 0x0010 },
|
||||
{ 0x08D0, 0x54CA, 0x21D5, 0x0011 },
|
||||
{ 0x08A9, 0x5499, 0x222C, 0x0012 },
|
||||
{ 0x0883, 0x5467, 0x2282, 0x0013 },
|
||||
{ 0x085D, 0x5434, 0x22DA, 0x0015 },
|
||||
{ 0x0838, 0x5401, 0x2331, 0x0016 },
|
||||
{ 0x0813, 0x53CC, 0x2389, 0x0018 },
|
||||
{ 0x07EF, 0x5397, 0x23E1, 0x0019 },
|
||||
{ 0x07CB, 0x5361, 0x2439, 0x001B },
|
||||
{ 0x07A7, 0x532A, 0x2492, 0x001C },
|
||||
{ 0x0784, 0x52F3, 0x24EB, 0x001E },
|
||||
{ 0x0762, 0x52BA, 0x2545, 0x0020 },
|
||||
{ 0x0740, 0x5281, 0x259E, 0x0021 },
|
||||
{ 0x071E, 0x5247, 0x25F8, 0x0023 },
|
||||
{ 0x06FD, 0x520C, 0x2653, 0x0025 },
|
||||
{ 0x06DC, 0x51D0, 0x26AD, 0x0027 },
|
||||
{ 0x06BB, 0x5194, 0x2708, 0x0029 },
|
||||
{ 0x069B, 0x5156, 0x2763, 0x002C },
|
||||
{ 0x067C, 0x5118, 0x27BE, 0x002E },
|
||||
{ 0x065C, 0x50DA, 0x281A, 0x0030 },
|
||||
{ 0x063E, 0x509A, 0x2876, 0x0033 },
|
||||
{ 0x061F, 0x505A, 0x28D2, 0x0035 },
|
||||
{ 0x0601, 0x5019, 0x292E, 0x0038 },
|
||||
{ 0x05E4, 0x4FD7, 0x298B, 0x003A },
|
||||
{ 0x05C7, 0x4F95, 0x29E7, 0x003D },
|
||||
{ 0x05AA, 0x4F52, 0x2A44, 0x0040 },
|
||||
{ 0x058E, 0x4F0E, 0x2AA1, 0x0043 },
|
||||
{ 0x0572, 0x4EC9, 0x2AFF, 0x0046 },
|
||||
{ 0x0556, 0x4E84, 0x2B5C, 0x0049 },
|
||||
{ 0x053B, 0x4E3E, 0x2BBA, 0x004D },
|
||||
{ 0x0520, 0x4DF7, 0x2C18, 0x0050 },
|
||||
{ 0x0506, 0x4DB0, 0x2C76, 0x0054 },
|
||||
{ 0x04EC, 0x4D68, 0x2CD4, 0x0057 },
|
||||
{ 0x04D2, 0x4D20, 0x2D33, 0x005B },
|
||||
{ 0x04B9, 0x4CD7, 0x2D91, 0x005F },
|
||||
{ 0x04A0, 0x4C8D, 0x2DF0, 0x0063 },
|
||||
{ 0x0488, 0x4C42, 0x2E4F, 0x0067 },
|
||||
{ 0x0470, 0x4BF7, 0x2EAE, 0x006B },
|
||||
{ 0x0458, 0x4BAC, 0x2F0D, 0x006F },
|
||||
{ 0x0441, 0x4B5F, 0x2F6C, 0x0074 },
|
||||
{ 0x042A, 0x4B13, 0x2FCC, 0x0078 },
|
||||
{ 0x0413, 0x4AC5, 0x302B, 0x007D },
|
||||
{ 0x03FC, 0x4A77, 0x308B, 0x0082 },
|
||||
{ 0x03E7, 0x4A29, 0x30EA, 0x0087 },
|
||||
{ 0x03D1, 0x49D9, 0x314A, 0x008C },
|
||||
{ 0x03BC, 0x498A, 0x31AA, 0x0091 },
|
||||
{ 0x03A7, 0x493A, 0x3209, 0x0096 },
|
||||
{ 0x0392, 0x48E9, 0x3269, 0x009C },
|
||||
{ 0x037E, 0x4898, 0x32C9, 0x00A1 },
|
||||
{ 0x036A, 0x4846, 0x3329, 0x00A7 },
|
||||
{ 0x0356, 0x47F4, 0x3389, 0x00AD },
|
||||
{ 0x0343, 0x47A1, 0x33E9, 0x00B3 },
|
||||
{ 0x0330, 0x474E, 0x3449, 0x00BA },
|
||||
{ 0x031D, 0x46FA, 0x34A9, 0x00C0 },
|
||||
{ 0x030B, 0x46A6, 0x3509, 0x00C7 },
|
||||
{ 0x02F9, 0x4651, 0x3569, 0x00CD },
|
||||
{ 0x02E7, 0x45FC, 0x35C9, 0x00D4 },
|
||||
{ 0x02D6, 0x45A6, 0x3629, 0x00DB },
|
||||
{ 0x02C4, 0x4550, 0x3689, 0x00E3 },
|
||||
{ 0x02B4, 0x44FA, 0x36E8, 0x00EA },
|
||||
{ 0x02A3, 0x44A3, 0x3748, 0x00F2 },
|
||||
{ 0x0293, 0x444C, 0x37A8, 0x00FA },
|
||||
{ 0x0283, 0x43F4, 0x3807, 0x0101 },
|
||||
{ 0x0273, 0x439C, 0x3867, 0x010A },
|
||||
{ 0x0264, 0x4344, 0x38C6, 0x0112 },
|
||||
{ 0x0255, 0x42EB, 0x3926, 0x011B },
|
||||
{ 0x0246, 0x4292, 0x3985, 0x0123 },
|
||||
{ 0x0237, 0x4239, 0x39E4, 0x012C },
|
||||
{ 0x0229, 0x41DF, 0x3A43, 0x0135 },
|
||||
{ 0x021B, 0x4185, 0x3AA2, 0x013F },
|
||||
{ 0x020D, 0x412A, 0x3B00, 0x0148 },
|
||||
{ 0x0200, 0x40D0, 0x3B5F, 0x0152 },
|
||||
{ 0x01F2, 0x4074, 0x3BBD, 0x015C },
|
||||
{ 0x01E5, 0x4019, 0x3C1B, 0x0166 },
|
||||
{ 0x01D9, 0x3FBD, 0x3C79, 0x0171 },
|
||||
{ 0x01CC, 0x3F62, 0x3CD7, 0x017B },
|
||||
{ 0x01C0, 0x3F05, 0x3D35, 0x0186 },
|
||||
{ 0x01B4, 0x3EA9, 0x3D92, 0x0191 },
|
||||
{ 0x01A8, 0x3E4C, 0x3DEF, 0x019C },
|
||||
{ 0x019C, 0x3DEF, 0x3E4C, 0x01A8 },
|
||||
{ 0x0191, 0x3D92, 0x3EA9, 0x01B4 },
|
||||
{ 0x0186, 0x3D35, 0x3F05, 0x01C0 },
|
||||
{ 0x017B, 0x3CD7, 0x3F62, 0x01CC },
|
||||
{ 0x0171, 0x3C79, 0x3FBD, 0x01D9 },
|
||||
{ 0x0166, 0x3C1B, 0x4019, 0x01E5 },
|
||||
{ 0x015C, 0x3BBD, 0x4074, 0x01F2 },
|
||||
{ 0x0152, 0x3B5F, 0x40D0, 0x0200 },
|
||||
{ 0x0148, 0x3B00, 0x412A, 0x020D },
|
||||
{ 0x013F, 0x3AA2, 0x4185, 0x021B },
|
||||
{ 0x0135, 0x3A43, 0x41DF, 0x0229 },
|
||||
{ 0x012C, 0x39E4, 0x4239, 0x0237 },
|
||||
{ 0x0123, 0x3985, 0x4292, 0x0246 },
|
||||
{ 0x011B, 0x3926, 0x42EB, 0x0255 },
|
||||
{ 0x0112, 0x38C6, 0x4344, 0x0264 },
|
||||
{ 0x010A, 0x3867, 0x439C, 0x0273 },
|
||||
{ 0x0101, 0x3807, 0x43F4, 0x0283 },
|
||||
{ 0x00FA, 0x37A8, 0x444C, 0x0293 },
|
||||
{ 0x00F2, 0x3748, 0x44A3, 0x02A3 },
|
||||
{ 0x00EA, 0x36E8, 0x44FA, 0x02B4 },
|
||||
{ 0x00E3, 0x3689, 0x4550, 0x02C4 },
|
||||
{ 0x00DB, 0x3629, 0x45A6, 0x02D6 },
|
||||
{ 0x00D4, 0x35C9, 0x45FC, 0x02E7 },
|
||||
{ 0x00CD, 0x3569, 0x4651, 0x02F9 },
|
||||
{ 0x00C7, 0x3509, 0x46A6, 0x030B },
|
||||
{ 0x00C0, 0x34A9, 0x46FA, 0x031D },
|
||||
{ 0x00BA, 0x3449, 0x474E, 0x0330 },
|
||||
{ 0x00B3, 0x33E9, 0x47A1, 0x0343 },
|
||||
{ 0x00AD, 0x3389, 0x47F4, 0x0356 },
|
||||
{ 0x00A7, 0x3329, 0x4846, 0x036A },
|
||||
{ 0x00A1, 0x32C9, 0x4898, 0x037E },
|
||||
{ 0x009C, 0x3269, 0x48E9, 0x0392 },
|
||||
{ 0x0096, 0x3209, 0x493A, 0x03A7 },
|
||||
{ 0x0091, 0x31AA, 0x498A, 0x03BC },
|
||||
{ 0x008C, 0x314A, 0x49D9, 0x03D1 },
|
||||
{ 0x0087, 0x30EA, 0x4A29, 0x03E7 },
|
||||
{ 0x0082, 0x308B, 0x4A77, 0x03FC },
|
||||
{ 0x007D, 0x302B, 0x4AC5, 0x0413 },
|
||||
{ 0x0078, 0x2FCC, 0x4B13, 0x042A },
|
||||
{ 0x0074, 0x2F6C, 0x4B5F, 0x0441 },
|
||||
{ 0x006F, 0x2F0D, 0x4BAC, 0x0458 },
|
||||
{ 0x006B, 0x2EAE, 0x4BF7, 0x0470 },
|
||||
{ 0x0067, 0x2E4F, 0x4C42, 0x0488 },
|
||||
{ 0x0063, 0x2DF0, 0x4C8D, 0x04A0 },
|
||||
{ 0x005F, 0x2D91, 0x4CD7, 0x04B9 },
|
||||
{ 0x005B, 0x2D33, 0x4D20, 0x04D2 },
|
||||
{ 0x0057, 0x2CD4, 0x4D68, 0x04EC },
|
||||
{ 0x0054, 0x2C76, 0x4DB0, 0x0506 },
|
||||
{ 0x0050, 0x2C18, 0x4DF7, 0x0520 },
|
||||
{ 0x004D, 0x2BBA, 0x4E3E, 0x053B },
|
||||
{ 0x0049, 0x2B5C, 0x4E84, 0x0556 },
|
||||
{ 0x0046, 0x2AFF, 0x4EC9, 0x0572 },
|
||||
{ 0x0043, 0x2AA1, 0x4F0E, 0x058E },
|
||||
{ 0x0040, 0x2A44, 0x4F52, 0x05AA },
|
||||
{ 0x003D, 0x29E7, 0x4F95, 0x05C7 },
|
||||
{ 0x003A, 0x298B, 0x4FD7, 0x05E4 },
|
||||
{ 0x0038, 0x292E, 0x5019, 0x0601 },
|
||||
{ 0x0035, 0x28D2, 0x505A, 0x061F },
|
||||
{ 0x0033, 0x2876, 0x509A, 0x063E },
|
||||
{ 0x0030, 0x281A, 0x50DA, 0x065C },
|
||||
{ 0x002E, 0x27BE, 0x5118, 0x067C },
|
||||
{ 0x002C, 0x2763, 0x5156, 0x069B },
|
||||
{ 0x0029, 0x2708, 0x5194, 0x06BB },
|
||||
{ 0x0027, 0x26AD, 0x51D0, 0x06DC },
|
||||
{ 0x0025, 0x2653, 0x520C, 0x06FD },
|
||||
{ 0x0023, 0x25F8, 0x5247, 0x071E },
|
||||
{ 0x0021, 0x259E, 0x5281, 0x0740 },
|
||||
{ 0x0020, 0x2545, 0x52BA, 0x0762 },
|
||||
{ 0x001E, 0x24EB, 0x52F3, 0x0784 },
|
||||
{ 0x001C, 0x2492, 0x532A, 0x07A7 },
|
||||
{ 0x001B, 0x2439, 0x5361, 0x07CB },
|
||||
{ 0x0019, 0x23E1, 0x5397, 0x07EF },
|
||||
{ 0x0018, 0x2389, 0x53CC, 0x0813 },
|
||||
{ 0x0016, 0x2331, 0x5401, 0x0838 },
|
||||
{ 0x0015, 0x22DA, 0x5434, 0x085D },
|
||||
{ 0x0013, 0x2282, 0x5467, 0x0883 },
|
||||
{ 0x0012, 0x222C, 0x5499, 0x08A9 },
|
||||
{ 0x0011, 0x21D5, 0x54CA, 0x08D0 },
|
||||
{ 0x0010, 0x217F, 0x54FA, 0x08F7 },
|
||||
{ 0x000F, 0x2129, 0x5529, 0x091E },
|
||||
{ 0x000E, 0x20D4, 0x5558, 0x0946 },
|
||||
{ 0x000D, 0x207F, 0x5585, 0x096F },
|
||||
{ 0x000C, 0x202A, 0x55B2, 0x0998 },
|
||||
{ 0x000B, 0x1FD6, 0x55DE, 0x09C1 },
|
||||
{ 0x000A, 0x1F82, 0x5609, 0x09EB },
|
||||
{ 0x0009, 0x1F2F, 0x5632, 0x0A16 },
|
||||
{ 0x0009, 0x1EDC, 0x565B, 0x0A40 },
|
||||
{ 0x0008, 0x1E89, 0x5684, 0x0A6C },
|
||||
{ 0x0007, 0x1E37, 0x56AB, 0x0A98 },
|
||||
{ 0x0007, 0x1DE5, 0x56D1, 0x0AC4 },
|
||||
{ 0x0006, 0x1D93, 0x56F6, 0x0AF1 },
|
||||
{ 0x0005, 0x1D42, 0x571B, 0x0B1E },
|
||||
{ 0x0005, 0x1CF1, 0x573E, 0x0B4C },
|
||||
{ 0x0004, 0x1CA1, 0x5761, 0x0B7A },
|
||||
{ 0x0004, 0x1C51, 0x5782, 0x0BA9 },
|
||||
{ 0x0003, 0x1C02, 0x57A3, 0x0BD8 },
|
||||
{ 0x0003, 0x1BB3, 0x57C3, 0x0C07 },
|
||||
{ 0x0003, 0x1B64, 0x57E2, 0x0C38 },
|
||||
{ 0x0002, 0x1B16, 0x57FF, 0x0C68 },
|
||||
{ 0x0002, 0x1AC8, 0x581C, 0x0C99 },
|
||||
{ 0x0002, 0x1A7B, 0x5838, 0x0CCB },
|
||||
{ 0x0001, 0x1A2E, 0x5853, 0x0CFD },
|
||||
{ 0x0001, 0x19E2, 0x586D, 0x0D30 },
|
||||
{ 0x0001, 0x1996, 0x5886, 0x0D63 },
|
||||
{ 0x0001, 0x194B, 0x589E, 0x0D97 },
|
||||
{ 0x0000, 0x1900, 0x58B5, 0x0DCB },
|
||||
{ 0x0000, 0x18B5, 0x58CB, 0x0E00 },
|
||||
{ 0x0000, 0x186B, 0x58E0, 0x0E35 },
|
||||
{ 0x0000, 0x1821, 0x58F4, 0x0E6B },
|
||||
{ 0x0000, 0x17D8, 0x5907, 0x0EA1 },
|
||||
{ 0x0000, 0x1790, 0x5919, 0x0ED7 },
|
||||
{ 0x0000, 0x1747, 0x592A, 0x0F0F },
|
||||
{ -0x0001, 0x1700, 0x593A, 0x0F46 },
|
||||
{ -0x0001, 0x16B9, 0x5949, 0x0F7F },
|
||||
{ -0x0001, 0x1672, 0x5958, 0x0FB7 },
|
||||
{ -0x0001, 0x162C, 0x5965, 0x0FF1 },
|
||||
{ -0x0001, 0x15E6, 0x5971, 0x102A },
|
||||
{ -0x0001, 0x15A0, 0x597C, 0x1065 },
|
||||
{ -0x0001, 0x155C, 0x5986, 0x109F },
|
||||
{ -0x0001, 0x1517, 0x598F, 0x10DB },
|
||||
{ -0x0001, 0x14D4, 0x5997, 0x1116 },
|
||||
{ -0x0001, 0x1490, 0x599E, 0x1153 },
|
||||
{ -0x0001, 0x144D, 0x59A4, 0x118F },
|
||||
{ -0x0001, 0x140B, 0x59A9, 0x11CD },
|
||||
{ -0x0001, 0x13C9, 0x59AD, 0x120B },
|
||||
{ -0x0001, 0x1388, 0x59B0, 0x1249 },
|
||||
{ -0x0001, 0x1347, 0x59B2, 0x1288 },
|
||||
{ -0x0001, 0x1307, 0x59B3, 0x12C7 },
|
||||
} };
|
22
game/sound/common/sound_types.h
Normal file
22
game/sound/common/sound_types.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "common/common_types.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace snd {
|
||||
|
||||
struct vol_pair {
|
||||
s16 left;
|
||||
s16 right;
|
||||
};
|
||||
|
||||
struct s16_output {
|
||||
s16 left{0}, right{0};
|
||||
|
||||
s16_output& operator+=(const s16_output& rhs) {
|
||||
left = static_cast<s16>(std::clamp<s32>(left + rhs.left, INT16_MIN, INT16_MAX));
|
||||
right = static_cast<s16>(std::clamp<s32>(right + rhs.right, INT16_MIN, INT16_MAX));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace snd
|
36
game/sound/common/synth.cpp
Normal file
36
game/sound/common/synth.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#include "synth.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace snd {
|
||||
|
||||
static s16 ApplyVolume(s16 sample, s32 volume) {
|
||||
return (sample * volume) >> 15;
|
||||
}
|
||||
|
||||
s16_output synth::tick() {
|
||||
s16_output out{};
|
||||
|
||||
m_voices.remove_if([](std::shared_ptr<voice>& v) { return v->dead(); });
|
||||
for (auto& v : m_voices) {
|
||||
out += v->run();
|
||||
}
|
||||
|
||||
out.left = ApplyVolume(out.left, m_Volume.left.Get());
|
||||
out.right = ApplyVolume(out.right, m_Volume.right.Get());
|
||||
|
||||
m_Volume.Run();
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void synth::add_voice(std::shared_ptr<voice> voice) {
|
||||
m_voices.emplace_front(voice);
|
||||
}
|
||||
|
||||
void synth::set_master_vol(u32 volume) {
|
||||
m_Volume.left.Set(volume);
|
||||
m_Volume.right.Set(volume);
|
||||
}
|
||||
} // namespace snd
|
35
game/sound/common/synth.h
Normal file
35
game/sound/common/synth.h
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#pragma once
|
||||
#include "common/common_types.h"
|
||||
#include "sound_types.h"
|
||||
#include "voice.h"
|
||||
#include "envelope.h"
|
||||
#include <forward_list>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace snd {
|
||||
struct SpuVolume {
|
||||
/* 0 */ s16 left;
|
||||
/* 2 */ s16 right;
|
||||
};
|
||||
|
||||
class synth {
|
||||
public:
|
||||
synth() {
|
||||
m_Volume.left.Set(0x3FFF);
|
||||
m_Volume.right.Set(0x3FFF);
|
||||
}
|
||||
|
||||
s16_output tick();
|
||||
void add_voice(std::shared_ptr<voice> voice);
|
||||
void set_master_vol(u32 volume);
|
||||
|
||||
private:
|
||||
std::forward_list<std::shared_ptr<voice>> m_voices;
|
||||
|
||||
VolumePair m_Volume{};
|
||||
};
|
||||
} // namespace snd
|
138
game/sound/common/voice.cpp
Normal file
138
game/sound/common/voice.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#include "voice.h"
|
||||
#include <array>
|
||||
#include "third-party/fmt/core.h"
|
||||
|
||||
namespace snd {
|
||||
#include "interp_table.inc"
|
||||
|
||||
// Integer math version of ps-adpcm coefs
|
||||
static constexpr std::array<std::array<s16, 2>, 5> adpcm_coefs = {{
|
||||
{0, 0},
|
||||
{60, 0},
|
||||
{115, -52},
|
||||
{98, -55},
|
||||
{122, -60},
|
||||
}};
|
||||
|
||||
void voice::DecodeSamples() {
|
||||
// This doesn't exactly match the real behaviour,
|
||||
// it seems to initially decode a bigger chunk
|
||||
// and then decode more data after a bit has drained
|
||||
if (m_DecodeBuf.Size() >= 16) {
|
||||
// sufficient data buffered
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip decoding for stopped voices.
|
||||
if (m_ADSR.GetPhase() == ADSR::Phase::Stopped) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
m_DecodeBuf.Push(0);
|
||||
} else {
|
||||
u32 data = m_sample[m_NAX];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
s32 sample = (s16)((data & 0xF) << 12);
|
||||
sample >>= m_CurHeader.Shift.get();
|
||||
|
||||
// TODO do the right thing for invalid shift/filter values
|
||||
sample += (adpcm_coefs[m_CurHeader.Filter.get()][0] * m_DecodeHist1) >> 6;
|
||||
sample += (adpcm_coefs[m_CurHeader.Filter.get()][1] * m_DecodeHist2) >> 6;
|
||||
|
||||
// We do get overflow here otherwise, should we?
|
||||
sample = std::clamp<s32>(sample, INT16_MIN, INT16_MAX);
|
||||
|
||||
m_DecodeHist2 = m_DecodeHist1;
|
||||
m_DecodeHist1 = static_cast<s16>(sample);
|
||||
|
||||
m_DecodeBuf.Push(static_cast<s16>(sample));
|
||||
data >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
m_NAX++;
|
||||
|
||||
if ((m_NAX & 0x7) == 0) {
|
||||
if (m_CurHeader.LoopEnd.get()) {
|
||||
m_NAX = m_LSA;
|
||||
m_ENDX = true;
|
||||
|
||||
if (!m_CurHeader.LoopRepeat.get()) {
|
||||
// Need to inhibit stopping here in noise is on
|
||||
// seems to result in the right thing but would like to verify
|
||||
if (!m_Noise)
|
||||
m_ADSR.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
UpdateBlockHeader();
|
||||
|
||||
m_NAX++;
|
||||
}
|
||||
}
|
||||
|
||||
void voice::UpdateBlockHeader() {
|
||||
m_CurHeader.bits = m_sample[m_NAX & ~0x7];
|
||||
if (m_CurHeader.LoopStart.get() && !m_CustomLoop)
|
||||
m_LSA = m_NAX & ~0x7;
|
||||
}
|
||||
|
||||
static s16 ApplyVolume(s16 sample, s32 volume) {
|
||||
return (sample * volume) >> 15;
|
||||
}
|
||||
|
||||
void voice::key_on() {
|
||||
m_NAX = m_SSA;
|
||||
m_NAX++;
|
||||
|
||||
UpdateBlockHeader();
|
||||
|
||||
m_ENDX = false;
|
||||
m_ADSR.Attack();
|
||||
m_Counter = 0;
|
||||
m_DecodeHist1 = 0;
|
||||
m_DecodeHist2 = 0;
|
||||
m_DecodeBuf.Reset();
|
||||
m_CustomLoop = false;
|
||||
// Console.WriteLn("SPU[%d]:VOICE[%d] Key On, SSA %08x", m_SPU.m_Id, m_Id, m_SSA);
|
||||
// fmt::print("Key On {} {} {} {:x}\n",(void*)m_sample, m_Volume.left.Get(), m_Volume.right.Get(),
|
||||
// m_ADSR.m_Reg.bits);
|
||||
}
|
||||
void voice::key_off() {
|
||||
m_ADSR.Release();
|
||||
// fmt::print("Key Off\n");
|
||||
}
|
||||
|
||||
s16_output voice::run() {
|
||||
DecodeSamples();
|
||||
|
||||
u32 index = (m_Counter & 0x0FF0) >> 4;
|
||||
|
||||
s16 sample = 0;
|
||||
sample = static_cast<s16>(sample + ((m_DecodeBuf.Peek(0) * interp_table[index][0]) >> 15));
|
||||
sample = static_cast<s16>(sample + ((m_DecodeBuf.Peek(1) * interp_table[index][1]) >> 15));
|
||||
sample = static_cast<s16>(sample + ((m_DecodeBuf.Peek(2) * interp_table[index][2]) >> 15));
|
||||
sample = static_cast<s16>(sample + ((m_DecodeBuf.Peek(3) * interp_table[index][3]) >> 15));
|
||||
|
||||
s32 step = m_Pitch;
|
||||
step = std::min(step, 0x3FFF);
|
||||
m_Counter += step;
|
||||
|
||||
auto steps = m_Counter >> 12;
|
||||
m_Counter &= 0xFFF;
|
||||
|
||||
while (steps > 0) {
|
||||
steps--;
|
||||
m_DecodeBuf.Pop();
|
||||
}
|
||||
|
||||
sample = ApplyVolume(sample, m_ADSR.Level());
|
||||
s16 left = ApplyVolume(sample, m_Volume.left.GetCurrent());
|
||||
s16 right = ApplyVolume(sample, m_Volume.right.GetCurrent());
|
||||
|
||||
m_ADSR.Run();
|
||||
m_Volume.Run();
|
||||
|
||||
return s16_output{left, right};
|
||||
}
|
||||
} // namespace snd
|
114
game/sound/common/voice.h
Normal file
114
game/sound/common/voice.h
Normal file
@ -0,0 +1,114 @@
|
||||
// Copyright: 2021 - 2022, Ziemas
|
||||
// SPDX-License-Identifier: ISC
|
||||
#pragma once
|
||||
#include "bitfield.h"
|
||||
#include "envelope.h"
|
||||
#include "fifo.h"
|
||||
#include "sound_types.h"
|
||||
#include "common/common_types.h"
|
||||
#include "third-party/fmt/core.h"
|
||||
|
||||
namespace snd {
|
||||
|
||||
class voice {
|
||||
public:
|
||||
enum class AllocationType {
|
||||
managed,
|
||||
permanent,
|
||||
};
|
||||
|
||||
voice(AllocationType alloc = AllocationType::managed) : m_Alloc(alloc) {}
|
||||
s16_output run();
|
||||
|
||||
void key_on();
|
||||
void key_off();
|
||||
|
||||
bool dead() {
|
||||
if (m_Alloc == AllocationType::permanent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_ADSR.GetPhase() == ADSR::Phase::Stopped;
|
||||
}
|
||||
|
||||
void set_pitch(u16 reg) {
|
||||
// fmt::print("VOICE[{}] PITCH WRITE {:x}\n", m_channel, reg);
|
||||
m_Pitch = reg;
|
||||
}
|
||||
void set_asdr1(u16 reg) {
|
||||
// fmt::print("VOICE[{}] ADSR1 WRITE {:x}\n", m_channel, reg);
|
||||
m_ADSR.m_Reg.lo.set(reg);
|
||||
}
|
||||
void set_asdr2(u16 reg) {
|
||||
// fmt::print("VOICE[{}] ADSR2 WRITE {:x}\n", m_channel, reg);
|
||||
m_ADSR.m_Reg.hi.set(reg);
|
||||
}
|
||||
void set_volume(u16 left, u16 right) {
|
||||
// fmt::print("VOICE[{}] VOLL WRITE {:x}\n", m_channel, left);
|
||||
// fmt::print("VOICE[{}] VOLR WRITE {:x}\n", m_channel, right);
|
||||
m_Volume.left.Set(left);
|
||||
m_Volume.right.Set(right);
|
||||
}
|
||||
|
||||
void set_volume_l(u16 vol) { m_Volume.left.Set(vol); }
|
||||
|
||||
void set_volume_r(u16 vol) { m_Volume.right.Set(vol); }
|
||||
|
||||
s16 get_envx() { return m_ADSR.Level(); }
|
||||
|
||||
void set_sample(u16* sample) {
|
||||
m_sample = sample;
|
||||
m_SSA = 0;
|
||||
}
|
||||
|
||||
u32 get_nax() { return m_NAX; }
|
||||
|
||||
void set_ssa(u32 addr) { m_SSA = addr; }
|
||||
|
||||
void set_lsa(u32 addr) {
|
||||
m_LSA = addr;
|
||||
m_CustomLoop = true;
|
||||
}
|
||||
|
||||
void stop() { m_ADSR.Stop(); }
|
||||
|
||||
private:
|
||||
union ADPCMHeader {
|
||||
u16 bits;
|
||||
bitfield<u16, bool, 10, 1> LoopStart;
|
||||
bitfield<u16, bool, 9, 1> LoopRepeat;
|
||||
bitfield<u16, bool, 8, 1> LoopEnd;
|
||||
bitfield<u16, u8, 4, 3> Filter;
|
||||
bitfield<u16, u8, 0, 4> Shift;
|
||||
};
|
||||
|
||||
AllocationType m_Alloc;
|
||||
bool m_Noise{false};
|
||||
bool m_PitchMod{false};
|
||||
bool m_KeyOn{false};
|
||||
bool m_KeyOff{false};
|
||||
bool m_ENDX{false};
|
||||
|
||||
void DecodeSamples();
|
||||
void UpdateBlockHeader();
|
||||
|
||||
fifo<s16, 0x20> m_DecodeBuf{};
|
||||
s16 m_DecodeHist1{0};
|
||||
s16 m_DecodeHist2{0};
|
||||
u32 m_Counter{0};
|
||||
|
||||
u16 m_Pitch{0};
|
||||
s16 m_Out{0};
|
||||
|
||||
u16* m_sample{nullptr};
|
||||
u32 m_SSA{0};
|
||||
u32 m_NAX{0};
|
||||
u32 m_LSA{0};
|
||||
bool m_CustomLoop{false};
|
||||
|
||||
ADPCMHeader m_CurHeader{};
|
||||
|
||||
ADSR m_ADSR{};
|
||||
VolumePair m_Volume{};
|
||||
};
|
||||
} // namespace snd
|
84
game/sound/sdshim.cpp
Normal file
84
game/sound/sdshim.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
#include "sdshim.h"
|
||||
#include <cstring>
|
||||
#include "common/common_types.h"
|
||||
#include "game/sound/common/voice.h"
|
||||
#include "third-party/fmt/core.h"
|
||||
|
||||
std::shared_ptr<snd::voice> voice;
|
||||
u8 spu_memory[0xc060];
|
||||
|
||||
static sceSdTransIntrHandler trans_handler[2] = {nullptr, nullptr};
|
||||
static void* userdata[2] = {nullptr, nullptr};
|
||||
|
||||
u32 sceSdGetSwitch(u32 entry) {
|
||||
// we can ignore this, only used for getting vmix
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 sceSdGetAddr(u32 entry) {
|
||||
// u32 core = entry & 1;
|
||||
// u32 voice->id = (entry >> 1) & 0x1f;
|
||||
// u32 reg = entry & ~0x3f;
|
||||
|
||||
// Only ever used for getting NAX
|
||||
|
||||
return voice->get_nax() << 1;
|
||||
}
|
||||
|
||||
void sceSdSetSwitch(u32 entry, u32 value) {
|
||||
// we can ignore this, only used for vmix
|
||||
}
|
||||
|
||||
void sceSdSetAddr(u32 entry, u32 value) {
|
||||
[[maybe_unused]] u32 core = entry & 1;
|
||||
[[maybe_unused]] u32 voice_id = (entry >> 1) & 0x1f;
|
||||
u32 reg = entry & ~0x3f;
|
||||
|
||||
switch (reg) {
|
||||
case SD_VA_SSA: {
|
||||
voice->set_ssa(value >> 1);
|
||||
} break;
|
||||
case SD_VA_LSAX: {
|
||||
voice->set_lsa(value >> 1);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void sceSdSetParam(u32 entry, u32 value) {
|
||||
[[maybe_unused]] u32 core = entry & 1;
|
||||
[[maybe_unused]] u32 voice_id = (entry >> 1) & 0x1f;
|
||||
u32 reg = entry & ~0x3f;
|
||||
|
||||
switch (reg) {
|
||||
case SD_VP_VOLL: {
|
||||
voice->set_volume_l(value);
|
||||
} break;
|
||||
case SD_VP_VOLR: {
|
||||
voice->set_volume_r(value);
|
||||
} break;
|
||||
case SD_VP_PITCH: {
|
||||
voice->set_pitch(value);
|
||||
} break;
|
||||
case SD_VP_ADSR1: {
|
||||
voice->set_asdr1(value);
|
||||
} break;
|
||||
case SD_VP_ADSR2: {
|
||||
voice->set_asdr2(value);
|
||||
} break;
|
||||
default: {
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void sceSdSetTransIntrHandler(s32 channel, sceSdTransIntrHandler handler, void* data) {
|
||||
trans_handler[channel] = handler;
|
||||
userdata[channel] = data;
|
||||
}
|
||||
|
||||
u32 sceSdVoiceTrans(s32 channel, s32 mode, void* iop_addr, u32 spu_addr, u32 size) {
|
||||
memcpy(&spu_memory[spu_addr], iop_addr, size);
|
||||
if (trans_handler[channel] != nullptr) {
|
||||
trans_handler[channel](channel, userdata);
|
||||
}
|
||||
return size;
|
||||
}
|
27
game/sound/sdshim.h
Normal file
27
game/sound/sdshim.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "common/common_types.h"
|
||||
#include "game/sound/common/voice.h"
|
||||
|
||||
#define SD_VA_SSA ((0x20 << 8) + (0x01 << 6))
|
||||
#define SD_VA_LSAX ((0x21 << 8) + (0x01 << 6))
|
||||
#define SD_S_VMIXL (0x18 << 8)
|
||||
#define SD_S_VMIXR (0x1a << 8)
|
||||
#define SD_VP_VOLL (0x00 << 8)
|
||||
#define SD_VP_VOLR (0x01 << 8)
|
||||
#define SD_VP_PITCH (0x02 << 8)
|
||||
#define SD_VP_ADSR1 (0x03 << 8)
|
||||
#define SD_VP_ADSR2 (0x04 << 8)
|
||||
#define SD_VA_NAX ((0x22 << 8) + (0x01 << 6))
|
||||
|
||||
extern std::shared_ptr<snd::voice> voice;
|
||||
extern u8 spu_memory[0xc060];
|
||||
|
||||
using sceSdTransIntrHandler = int (*)(int, void*);
|
||||
|
||||
u32 sceSdGetSwitch(u32 entry);
|
||||
u32 sceSdGetAddr(u32 entry);
|
||||
void sceSdSetSwitch(u32 entry, u32 value);
|
||||
void sceSdSetAddr(u32 entry, u32 value);
|
||||
void sceSdSetParam(u32 entry, u32 value);
|
||||
void sceSdSetTransIntrHandler(s32 channel, sceSdTransIntrHandler, void* data);
|
||||
u32 sceSdVoiceTrans(s32 channel, s32 mode, void* iop_addr, u32 spu_addr, u32 size);
|
160
game/sound/sndshim.cpp
Normal file
160
game/sound/sndshim.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
#include "sndshim.h"
|
||||
#include "989snd/player.h"
|
||||
#include "sdshim.h"
|
||||
#include <cstdio>
|
||||
|
||||
std::unique_ptr<snd::player> player;
|
||||
|
||||
void snd_StartSoundSystem() {
|
||||
player = std::make_unique<snd::player>();
|
||||
|
||||
voice = std::make_shared<snd::voice>(snd::voice::AllocationType::permanent);
|
||||
voice->set_sample((u16*)spu_memory);
|
||||
player->submit_voice(voice);
|
||||
}
|
||||
|
||||
void snd_StopSoundSystem() {
|
||||
player.reset();
|
||||
}
|
||||
|
||||
// dma is always instant, allocation not required
|
||||
s32 snd_GetFreeSPUDMA() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void snd_FreeSPUDMA([[maybe_unused]] s32 channel) {}
|
||||
|
||||
s32 snd_GetTick() {
|
||||
return player->get_tick();
|
||||
}
|
||||
|
||||
void snd_RegisterIOPMemAllocator(AllocFun, FreeFun) {
|
||||
// printf("snd_RegisterIOPMemAllocator\n");
|
||||
}
|
||||
|
||||
void snd_LockVoiceAllocator(s32) {
|
||||
// printf("snd_LockVoiceAllocator\n");
|
||||
}
|
||||
|
||||
void snd_UnlockVoiceAllocator() {
|
||||
// printf("snd_UnlockVoiceAllocator\n");
|
||||
}
|
||||
|
||||
s32 snd_ExternVoiceVoiceAlloc(s32, s32) {
|
||||
// printf("snd_ExternVoiceVoiceAlloc\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 snd_SRAMMalloc(u32) {
|
||||
// spu memory currently hardcoded
|
||||
return 0;
|
||||
}
|
||||
|
||||
void snd_SetMixerMode(s32, s32) {}
|
||||
|
||||
void snd_SetGroupVoiceRange(s32, s32, s32) {}
|
||||
|
||||
void snd_SetReverbDepth(s32, s32, s32) {}
|
||||
|
||||
void snd_SetReverbType(s32, s32) {}
|
||||
|
||||
void snd_SetPanTable(s16* table) {
|
||||
player->set_pan_table((snd::vol_pair*)table);
|
||||
}
|
||||
|
||||
void snd_SetPlayBackMode(s32 mode) {
|
||||
player->set_playback_mode(mode);
|
||||
}
|
||||
|
||||
s32 snd_SoundIsStillPlaying(s32 sound_handle) {
|
||||
if (player->sound_still_active(sound_handle)) {
|
||||
return sound_handle;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void snd_StopSound(s32 handle) {
|
||||
player->stop_sound(handle);
|
||||
}
|
||||
|
||||
void snd_SetSoundVolPan(s32 sound_handle, s32 vol, s32 pan) {
|
||||
player->set_sound_vol_pan(sound_handle, vol, pan);
|
||||
}
|
||||
|
||||
void snd_SetMasterVolume(s32 group, s32 volume) {
|
||||
player->set_master_volume(group, volume);
|
||||
}
|
||||
|
||||
void snd_UnloadBank(s32 bank_handle) {
|
||||
player->unload_bank(bank_handle);
|
||||
}
|
||||
|
||||
void snd_ResolveBankXREFS() {
|
||||
// Currently no-op, idk if we'd ever need it
|
||||
}
|
||||
|
||||
void snd_ContinueAllSoundsInGroup(u8 group) {
|
||||
player->continue_all_sounds_in_group(group);
|
||||
}
|
||||
|
||||
void snd_PauseAllSoundsInGroup(u8 group) {
|
||||
player->pause_all_sounds_in_group(group);
|
||||
}
|
||||
|
||||
void snd_SetMIDIRegister(s32 sound_handle, u8 reg, u8 value) {
|
||||
player->set_midi_reg(sound_handle, reg, value);
|
||||
}
|
||||
|
||||
s32 snd_PlaySoundVolPanPMPB(s32 bank, s32 sound, s32 vol, s32 pan, s32 pm, s32 pb) {
|
||||
return player->play_sound(bank, sound, vol, pan, pm, pb);
|
||||
}
|
||||
|
||||
void snd_SetSoundPitchModifier(s32 sound, s32 mod) {
|
||||
player->set_sound_pmod(sound, mod);
|
||||
}
|
||||
|
||||
void snd_SetSoundPitchBend(s32 sound, s32 bend) {
|
||||
if (bend != 0) {
|
||||
}
|
||||
}
|
||||
|
||||
void snd_PauseSound(s32 sound_handle) {
|
||||
player->pause_sound(sound_handle);
|
||||
}
|
||||
|
||||
void snd_ContinueSound(s32 sound_handle) {
|
||||
player->continue_sound(sound_handle);
|
||||
}
|
||||
|
||||
void snd_AutoPitch(s32, s32, s32, s32) {
|
||||
// TODO
|
||||
printf("snd_AutoPitch\n");
|
||||
}
|
||||
void snd_AutoPitchBend(s32, s32, s32, s32) {
|
||||
// TODO
|
||||
printf("snd_AutoPitchBend\n");
|
||||
}
|
||||
|
||||
s32 snd_BankLoadEx(const char* filename, s32 offset, s32, s32) {
|
||||
// printf("snd_BankLoadEx\n");
|
||||
std::filesystem::path path = filename;
|
||||
return player->load_bank(path, offset);
|
||||
}
|
||||
|
||||
s32 snd_GetVoiceStatus(s32 voice) {
|
||||
// hacky thincg to say that voice 0 is uses allocated
|
||||
if (voice == 0) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void snd_keyOnVoiceRaw(u32 core, u32 voice_id) {
|
||||
voice->key_on();
|
||||
}
|
||||
|
||||
void snd_keyOffVoiceRaw(u32 core, u32 voice_id) {
|
||||
voice->key_off();
|
||||
}
|
@ -3,11 +3,16 @@
|
||||
#pragma once
|
||||
#include "common/common_types.h"
|
||||
|
||||
constexpr int SND_CORE_0 = 1;
|
||||
constexpr int SND_CORE_1 = 2;
|
||||
constexpr int SD_REV_MODE_OFF = 0;
|
||||
|
||||
typedef void* (*AllocFun)();
|
||||
typedef void (*FreeFun)(void*);
|
||||
|
||||
void snd_StartSoundSystem();
|
||||
void snd_StopSoundSystem();
|
||||
s32 snd_GetTick();
|
||||
void snd_RegisterIOPMemAllocator(AllocFun, FreeFun);
|
||||
void snd_LockVoiceAllocator(s32);
|
||||
void snd_UnlockVoiceAllocator();
|
||||
@ -36,5 +41,10 @@ void snd_ContinueSound(s32);
|
||||
void snd_AutoPitch(s32, s32, s32, s32);
|
||||
void snd_AutoPitchBend(s32, s32, s32, s32);
|
||||
s32 snd_BankLoadEx(const char* filepath, s32 data_offset, s32 unk1, s32 unk2);
|
||||
s32 snd_GetVoiceStatus(s32 voice);
|
||||
s32 snd_GetFreeSPUDMA();
|
||||
void snd_FreeSPUDMA(s32 channel);
|
||||
void snd_keyOnVoiceRaw(u32, u32);
|
||||
void snd_keyOffVoiceRaw(u32, u32);
|
||||
|
||||
#endif // SNDSHIM_H_
|
@ -12,6 +12,7 @@
|
||||
#include <atomic>
|
||||
#include "common/common_types.h"
|
||||
#include "common/util/Assert.h"
|
||||
#include "game/sce/iop.h"
|
||||
|
||||
class IOP_Kernel;
|
||||
namespace iop {
|
||||
@ -124,7 +125,7 @@ class IOP_Kernel {
|
||||
s32 PollMbx(void** msg, s32 mbx) {
|
||||
if (_currentThread != -1 && threads.at(_currentThread).wantExit) {
|
||||
// total hack - returning this value causes the ISO thread to error out and quit.
|
||||
return -0x1a9;
|
||||
return KE_WAIT_DELETE;
|
||||
}
|
||||
|
||||
ASSERT(mbx < (s32)mbxs.size());
|
||||
@ -139,7 +140,7 @@ class IOP_Kernel {
|
||||
mbxs[mbx].pop();
|
||||
}
|
||||
|
||||
return gotSomething ? 0 : -424;
|
||||
return gotSomething ? KE_OK : KE_MBOX_NOMSG;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -869,9 +869,6 @@
|
||||
(define-extern joint-control-channel-group! (function joint-control-channel art-joint-anim (function joint-control-channel float float float) int))
|
||||
(define-extern ja-aframe-num (function int float :behavior process-drawable))
|
||||
|
||||
;; this function is modified to work without sound.
|
||||
(define *str-pos-hack* 0)
|
||||
(define *str-play-speed* 17)
|
||||
(define-extern ja-abort-spooled-anim (function spool-anim art-joint-anim int int :behavior process-drawable))
|
||||
(defbehavior ja-play-spooled-anim process-drawable ((arg0 spool-anim) (arg1 art-joint-anim) (arg2 art-joint-anim) (arg3 (function process-drawable symbol)))
|
||||
(local-vars
|
||||
@ -886,7 +883,6 @@
|
||||
(spool-sound sound-id)
|
||||
(sv-72 int)
|
||||
)
|
||||
(set! *str-pos-hack* 0)
|
||||
(set! spool-part 0)
|
||||
(set! sv-24 -17.0)
|
||||
(set! old-skel-status (-> self skel status))
|
||||
@ -993,21 +989,14 @@
|
||||
)
|
||||
(when (zero? spool-part)
|
||||
(str-play-async (-> arg0 name) spool-sound)
|
||||
;; hack!
|
||||
;;(set! *str-pos-hack* 0)
|
||||
;;
|
||||
(set! (-> *art-control* active-stream) (-> arg0 name))
|
||||
)
|
||||
(let* ((f30-0 (* 0.05859375 (-> s2-4 speed)))
|
||||
(f28-0 (+ sv-24 (/ (the float (+ (-> s2-4 data 0 length) -1)) f30-0)))
|
||||
)
|
||||
;;(set! sv-72 (current-str-pos spool-sound))
|
||||
(set! sv-72 *str-pos-hack*)
|
||||
|
||||
|
||||
(set! sv-72 (current-str-pos spool-sound))
|
||||
(set! sv-40 (-> *display* base-frame-counter))
|
||||
(until (>= (the float v0-39) f28-0)
|
||||
(+! *str-pos-hack* *str-play-speed*)
|
||||
(if (= (-> self skel root-channel 0) (-> self skel channel))
|
||||
(logior! (-> self skel status) (janim-status spool))
|
||||
)
|
||||
@ -1024,7 +1013,7 @@
|
||||
)
|
||||
(execute-commands-up-to *load-state* (ja-aframe-num 0))
|
||||
(cond
|
||||
((and (< sv-32 sv-72) #|(= (current-str-id) spool-sound)|#)
|
||||
((and (< sv-32 sv-72) (= (current-str-id) spool-sound))
|
||||
(set! sv-56 (+ sv-56 (- (-> *display* base-frame-counter) (-> *display* old-base-frame-counter))))
|
||||
(set! sv-40 (-> *display* base-frame-counter))
|
||||
)
|
||||
@ -1035,7 +1024,7 @@
|
||||
(set! sv-32 sv-72)
|
||||
(set! sv-48 (-> *display* base-frame-counter))
|
||||
(suspend)
|
||||
(let ((f0-14 (* (- (the float *str-pos-hack* #|(current-str-pos spool-sound)|#) sv-24) f30-0))
|
||||
(let ((f0-14 (* (- (the float (current-str-pos spool-sound)) sv-24) f30-0))
|
||||
(a0-69 (-> self skel root-channel 0))
|
||||
)
|
||||
(set! (-> a0-69 param 0) (the float (+ (-> a0-69 frame-group data 0 length) -1)))
|
||||
@ -1043,7 +1032,7 @@
|
||||
(set! (-> a0-69 frame-num) f0-14)
|
||||
(joint-control-channel-group! a0-69 (the-as art-joint-anim #f) num-func-seek!)
|
||||
)
|
||||
(set! v0-39 *str-pos-hack* #|(current-str-pos spool-sound)|#)
|
||||
(set! v0-39 (current-str-pos spool-sound))
|
||||
(set! sv-72 v0-39)
|
||||
)
|
||||
(set! sv-24 f28-0)
|
||||
|
16
third-party/cubeb/CMakeFiles/CMakeDirectoryInformation.cmake
generated
vendored
Normal file
16
third-party/cubeb/CMakeFiles/CMakeDirectoryInformation.cmake
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Generated by "Unix Makefiles" Generator, CMake Version 3.22
|
||||
|
||||
# Relative path conversion top directories.
|
||||
set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/ziemas/Development/jak-project")
|
||||
set(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/ziemas/Development/jak-project")
|
||||
|
||||
# Force unix paths in dependencies.
|
||||
set(CMAKE_FORCE_UNIX_PATHS 1)
|
||||
|
||||
|
||||
# The C and CXX include file regular expressions for this directory.
|
||||
set(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$")
|
||||
set(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$")
|
||||
set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN})
|
||||
set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN})
|
1
third-party/cubeb/CMakeFiles/progress.marks
generated
vendored
Normal file
1
third-party/cubeb/CMakeFiles/progress.marks
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
2
|
10
third-party/cubeb/CMakeLists.txt
generated
vendored
Normal file
10
third-party/cubeb/CMakeLists.txt
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
# Disable building the stuff we don't need.
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
set(BUILD_TESTS OFF)
|
||||
set(BUILD_RUST_LIBS OFF)
|
||||
set(BUILD_TOOLS OFF)
|
||||
set(BUNDLE_SPEEX ON)
|
||||
set(USE_SANITIZERS OFF)
|
||||
set(LAZY_LOAD_LIBS ON)
|
||||
|
||||
add_subdirectory(cubeb)
|
7
third-party/cubeb/CTestTestfile.cmake
generated
vendored
Normal file
7
third-party/cubeb/CTestTestfile.cmake
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# CMake generated Testfile for
|
||||
# Source directory: /home/ziemas/Development/jak-project/third-party/cubeb
|
||||
# Build directory: /home/ziemas/Development/jak-project/third-party/cubeb
|
||||
#
|
||||
# This file includes the relevant testing commands required for
|
||||
# testing this directory and lists subdirectories to be tested as well.
|
||||
subdirs("cubeb")
|
202
third-party/cubeb/Makefile
generated
vendored
Normal file
202
third-party/cubeb/Makefile
generated
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Generated by "Unix Makefiles" Generator, CMake Version 3.22
|
||||
|
||||
# Default target executed when no arguments are given to make.
|
||||
default_target: all
|
||||
.PHONY : default_target
|
||||
|
||||
# Allow only one "make -f Makefile2" at a time, but pass parallelism.
|
||||
.NOTPARALLEL:
|
||||
|
||||
#=============================================================================
|
||||
# Special targets provided by cmake.
|
||||
|
||||
# Disable implicit rules so canonical targets will work.
|
||||
.SUFFIXES:
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : %,v
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : RCS/%
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : RCS/%,v
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : SCCS/s.%
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : s.%
|
||||
|
||||
.SUFFIXES: .hpux_make_needs_suffix_list
|
||||
|
||||
# Command-line flag to silence nested $(MAKE).
|
||||
$(VERBOSE)MAKESILENT = -s
|
||||
|
||||
#Suppress display of executed commands.
|
||||
$(VERBOSE).SILENT:
|
||||
|
||||
# A target that is always out of date.
|
||||
cmake_force:
|
||||
.PHONY : cmake_force
|
||||
|
||||
#=============================================================================
|
||||
# Set environment variables for the build.
|
||||
|
||||
# The shell in which to execute make rules.
|
||||
SHELL = /bin/sh
|
||||
|
||||
# The CMake executable.
|
||||
CMAKE_COMMAND = /usr/bin/cmake
|
||||
|
||||
# The command to remove a file.
|
||||
RM = /usr/bin/cmake -E rm -f
|
||||
|
||||
# Escaping for special characters.
|
||||
EQUALS = =
|
||||
|
||||
# The top-level source directory on which CMake was run.
|
||||
CMAKE_SOURCE_DIR = /home/ziemas/Development/jak-project
|
||||
|
||||
# The top-level build directory on which CMake was run.
|
||||
CMAKE_BINARY_DIR = /home/ziemas/Development/jak-project
|
||||
|
||||
#=============================================================================
|
||||
# Targets provided globally by CMake.
|
||||
|
||||
# Special rule for the target test
|
||||
test:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running tests..."
|
||||
/usr/bin/ctest --force-new-ctest-process $(ARGS)
|
||||
.PHONY : test
|
||||
|
||||
# Special rule for the target test
|
||||
test/fast: test
|
||||
.PHONY : test/fast
|
||||
|
||||
# Special rule for the target edit_cache
|
||||
edit_cache:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."
|
||||
/usr/bin/ccmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
|
||||
.PHONY : edit_cache
|
||||
|
||||
# Special rule for the target edit_cache
|
||||
edit_cache/fast: edit_cache
|
||||
.PHONY : edit_cache/fast
|
||||
|
||||
# Special rule for the target rebuild_cache
|
||||
rebuild_cache:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
|
||||
/usr/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
|
||||
.PHONY : rebuild_cache
|
||||
|
||||
# Special rule for the target rebuild_cache
|
||||
rebuild_cache/fast: rebuild_cache
|
||||
.PHONY : rebuild_cache/fast
|
||||
|
||||
# Special rule for the target list_install_components
|
||||
list_install_components:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\""
|
||||
.PHONY : list_install_components
|
||||
|
||||
# Special rule for the target list_install_components
|
||||
list_install_components/fast: list_install_components
|
||||
.PHONY : list_install_components/fast
|
||||
|
||||
# Special rule for the target install
|
||||
install: preinstall
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
|
||||
/usr/bin/cmake -P cmake_install.cmake
|
||||
.PHONY : install
|
||||
|
||||
# Special rule for the target install
|
||||
install/fast: preinstall/fast
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
|
||||
/usr/bin/cmake -P cmake_install.cmake
|
||||
.PHONY : install/fast
|
||||
|
||||
# Special rule for the target install/local
|
||||
install/local: preinstall
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..."
|
||||
/usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
|
||||
.PHONY : install/local
|
||||
|
||||
# Special rule for the target install/local
|
||||
install/local/fast: preinstall/fast
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..."
|
||||
/usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
|
||||
.PHONY : install/local/fast
|
||||
|
||||
# Special rule for the target install/strip
|
||||
install/strip: preinstall
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..."
|
||||
/usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
|
||||
.PHONY : install/strip
|
||||
|
||||
# Special rule for the target install/strip
|
||||
install/strip/fast: preinstall/fast
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..."
|
||||
/usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
|
||||
.PHONY : install/strip/fast
|
||||
|
||||
# The main all target
|
||||
all: cmake_check_build_system
|
||||
cd /home/ziemas/Development/jak-project && $(CMAKE_COMMAND) -E cmake_progress_start /home/ziemas/Development/jak-project/CMakeFiles /home/ziemas/Development/jak-project/third-party/cubeb//CMakeFiles/progress.marks
|
||||
cd /home/ziemas/Development/jak-project && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 third-party/cubeb/all
|
||||
$(CMAKE_COMMAND) -E cmake_progress_start /home/ziemas/Development/jak-project/CMakeFiles 0
|
||||
.PHONY : all
|
||||
|
||||
# The main clean target
|
||||
clean:
|
||||
cd /home/ziemas/Development/jak-project && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 third-party/cubeb/clean
|
||||
.PHONY : clean
|
||||
|
||||
# The main clean target
|
||||
clean/fast: clean
|
||||
.PHONY : clean/fast
|
||||
|
||||
# Prepare targets for installation.
|
||||
preinstall: all
|
||||
cd /home/ziemas/Development/jak-project && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 third-party/cubeb/preinstall
|
||||
.PHONY : preinstall
|
||||
|
||||
# Prepare targets for installation.
|
||||
preinstall/fast:
|
||||
cd /home/ziemas/Development/jak-project && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 third-party/cubeb/preinstall
|
||||
.PHONY : preinstall/fast
|
||||
|
||||
# clear depends
|
||||
depend:
|
||||
cd /home/ziemas/Development/jak-project && $(CMAKE_COMMAND) -P /home/ziemas/Development/jak-project/CMakeFiles/VerifyGlobs.cmake
|
||||
cd /home/ziemas/Development/jak-project && $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
|
||||
.PHONY : depend
|
||||
|
||||
# Help Target
|
||||
help:
|
||||
@echo "The following are some of the valid targets for this Makefile:"
|
||||
@echo "... all (the default if no target is provided)"
|
||||
@echo "... clean"
|
||||
@echo "... depend"
|
||||
@echo "... edit_cache"
|
||||
@echo "... install"
|
||||
@echo "... install/local"
|
||||
@echo "... install/strip"
|
||||
@echo "... list_install_components"
|
||||
@echo "... rebuild_cache"
|
||||
@echo "... test"
|
||||
.PHONY : help
|
||||
|
||||
|
||||
|
||||
#=============================================================================
|
||||
# Special targets to cleanup operation of make.
|
||||
|
||||
# Special rule to run CMake to check the build system integrity.
|
||||
# No rule that depends on this can have commands that come from listfiles
|
||||
# because they might be regenerated.
|
||||
cmake_check_build_system:
|
||||
cd /home/ziemas/Development/jak-project && $(CMAKE_COMMAND) -P /home/ziemas/Development/jak-project/CMakeFiles/VerifyGlobs.cmake
|
||||
cd /home/ziemas/Development/jak-project && $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
|
||||
.PHONY : cmake_check_build_system
|
||||
|
50
third-party/cubeb/cmake_install.cmake
generated
vendored
Normal file
50
third-party/cubeb/cmake_install.cmake
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
# Install script for directory: /home/ziemas/Development/jak-project/third-party/cubeb
|
||||
|
||||
# Set the install prefix
|
||||
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
set(CMAKE_INSTALL_PREFIX "/usr/local")
|
||||
endif()
|
||||
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
# Set the install configuration name.
|
||||
if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
if(BUILD_TYPE)
|
||||
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
||||
else()
|
||||
set(CMAKE_INSTALL_CONFIG_NAME "Release")
|
||||
endif()
|
||||
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
||||
endif()
|
||||
|
||||
# Set the component getting installed.
|
||||
if(NOT CMAKE_INSTALL_COMPONENT)
|
||||
if(COMPONENT)
|
||||
message(STATUS "Install component: \"${COMPONENT}\"")
|
||||
set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
||||
else()
|
||||
set(CMAKE_INSTALL_COMPONENT)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Install shared libraries without execute permission?
|
||||
if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
||||
set(CMAKE_INSTALL_SO_NO_EXE "0")
|
||||
endif()
|
||||
|
||||
# Is this installation the result of a crosscompile?
|
||||
if(NOT DEFINED CMAKE_CROSSCOMPILING)
|
||||
set(CMAKE_CROSSCOMPILING "FALSE")
|
||||
endif()
|
||||
|
||||
# Set default install directory permissions.
|
||||
if(NOT DEFINED CMAKE_OBJDUMP)
|
||||
set(CMAKE_OBJDUMP "/usr/bin/objdump")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_LOCAL_ONLY)
|
||||
# Include the install script for each subdirectory.
|
||||
include("/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/cmake_install.cmake")
|
||||
|
||||
endif()
|
||||
|
77
third-party/cubeb/cubeb.vcxproj
generated
vendored
Normal file
77
third-party/cubeb/cubeb.vcxproj
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(SolutionDir)common\vsprops\BaseProjectConfig.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\WinSDK.props" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{BF74C473-DC04-44B3-92E8-4145F4E77342}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization Condition="$(Configuration.Contains(Release))">true</WholeProgramOptimization>
|
||||
<UseDebugLibraries Condition="$(Configuration.Contains(Debug))">true</UseDebugLibraries>
|
||||
<UseDebugLibraries Condition="!$(Configuration.Contains(Debug))">false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="..\DefaultProjectRootDir.props" />
|
||||
<Import Project="..\3rdparty.props" />
|
||||
<Import Condition="$(Configuration.Contains(Debug))" Project="..\..\common\vsprops\CodeGen_Debug.props" />
|
||||
<Import Condition="$(Configuration.Contains(Devel))" Project="..\..\common\vsprops\CodeGen_Devel.props" />
|
||||
<Import Condition="$(Configuration.Contains(Release))" Project="..\..\common\vsprops\CodeGen_Release.props" />
|
||||
<Import Condition="!$(Configuration.Contains(Release))" Project="..\..\common\vsprops\IncrementalLinking.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<PreprocessorDefinitions>USE_WASAPI;USE_WINMM;OUTSIDE_SPEEX;FLOATING_POINT;RANDOM_PREFIX=speex;EXPORT=;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)include;$(ProjectDir)cubeb\include;$(ProjectDir)cubeb\src;$(ProjectDir)cubeb\subprojects;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp14</LanguageStandard>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="cubeb\include\cubeb\cubeb.h" />
|
||||
<ClInclude Include="cubeb\subprojects\speex\arch.h" />
|
||||
<ClInclude Include="cubeb\subprojects\speex\fixed_generic.h" />
|
||||
<ClInclude Include="cubeb\subprojects\speex\resample_neon.h" />
|
||||
<ClInclude Include="cubeb\subprojects\speex\resample_sse.h" />
|
||||
<ClInclude Include="cubeb\subprojects\speex\speex_config_types.h" />
|
||||
<ClInclude Include="cubeb\subprojects\speex\speex_resampler.h" />
|
||||
<ClInclude Include="cubeb\subprojects\speex\stack_alloc.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb-internal.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb-speex-resampler.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_array_queue.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_assert.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_log.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_mixer.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_resampler.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_resampler_internal.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_ringbuffer.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_ring_array.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_strings.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_utils.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_utils_win.h" />
|
||||
<ClInclude Include="include\cubeb_export.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="cubeb\src\cubeb.c" />
|
||||
<ClCompile Include="cubeb\src\cubeb_log.cpp" />
|
||||
<ClCompile Include="cubeb\src\cubeb_mixer.cpp" />
|
||||
<ClCompile Include="cubeb\src\cubeb_resampler.cpp" />
|
||||
<ClCompile Include="cubeb\src\cubeb_strings.c" />
|
||||
<ClCompile Include="cubeb\src\cubeb_utils.cpp" />
|
||||
<ClCompile Include="cubeb\src\cubeb_wasapi.cpp" />
|
||||
<ClCompile Include="cubeb\src\cubeb_winmm.c" />
|
||||
<ClCompile Include="cubeb\subprojects\speex\resample.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
59
third-party/cubeb/cubeb.vcxproj.filters
generated
vendored
Normal file
59
third-party/cubeb/cubeb.vcxproj.filters
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClInclude Include="cubeb\src\cubeb-internal.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb-speex-resampler.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_array_queue.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_assert.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_log.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_mixer.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_resampler.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_resampler_internal.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_ring_array.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_ringbuffer.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_strings.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_utils.h" />
|
||||
<ClInclude Include="cubeb\src\cubeb_utils_win.h" />
|
||||
<ClInclude Include="cubeb\subprojects\speex\fixed_generic.h">
|
||||
<Filter>speex</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="cubeb\subprojects\speex\resample_neon.h">
|
||||
<Filter>speex</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="cubeb\subprojects\speex\resample_sse.h">
|
||||
<Filter>speex</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="cubeb\subprojects\speex\speex_config_types.h">
|
||||
<Filter>speex</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="cubeb\subprojects\speex\speex_resampler.h">
|
||||
<Filter>speex</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="cubeb\subprojects\speex\stack_alloc.h">
|
||||
<Filter>speex</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="cubeb\subprojects\speex\arch.h">
|
||||
<Filter>speex</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="cubeb\include\cubeb\cubeb.h" />
|
||||
<ClInclude Include="include\cubeb_export.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="speex">
|
||||
<UniqueIdentifier>{a22ed8dc-2384-4a96-bd3b-2370d6d7cd62}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="cubeb\src\cubeb_wasapi.cpp" />
|
||||
<ClCompile Include="cubeb\src\cubeb_winmm.c" />
|
||||
<ClCompile Include="cubeb\src\cubeb.c" />
|
||||
<ClCompile Include="cubeb\src\cubeb_log.cpp" />
|
||||
<ClCompile Include="cubeb\src\cubeb_mixer.cpp" />
|
||||
<ClCompile Include="cubeb\src\cubeb_resampler.cpp" />
|
||||
<ClCompile Include="cubeb\src\cubeb_strings.c" />
|
||||
<ClCompile Include="cubeb\src\cubeb_utils.cpp" />
|
||||
<ClCompile Include="cubeb\subprojects\speex\resample.c">
|
||||
<Filter>speex</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
13
third-party/cubeb/cubeb/.clang-format
generated
vendored
Normal file
13
third-party/cubeb/cubeb/.clang-format
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
IndentWidth: 2
|
||||
UseTab: Never
|
||||
ReflowComments: true
|
||||
PointerAlignment: Middle
|
||||
AlignAfterOpenBracket: Align
|
||||
AlwaysBreakAfterReturnType: TopLevel
|
||||
ColumnLimit: 80
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterFunction: true
|
||||
AfterControlStatement: Never
|
||||
SpaceBeforeParens: ControlStatements
|
||||
BreakBeforeBinaryOperators: None
|
75
third-party/cubeb/cubeb/.github/workflows/build.yml
generated
vendored
Normal file
75
third-party/cubeb/cubeb/.github/workflows/build.yml
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
name: Build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
BUILD_TYPE: ${{ matrix.type }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, windows-2019, macos-10.15]
|
||||
type: [Release, Debug]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Install Dependencies (Linux)
|
||||
run: sudo apt-get update && sudo apt-get install libpulse-dev pulseaudio
|
||||
if: matrix.os == 'ubuntu-20.04'
|
||||
|
||||
- name: Start Sound Server (Linux)
|
||||
run: pulseaudio -D --start
|
||||
if: matrix.os == 'ubuntu-20.04'
|
||||
|
||||
- name: Configure CMake
|
||||
shell: bash
|
||||
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: cmake --build build
|
||||
|
||||
- name: Test
|
||||
shell: bash
|
||||
run: (cd build && ctest -V)
|
||||
if: ${{ matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-10.15' }}
|
||||
|
||||
build-android:
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
BUILD_TYPE: ${{ matrix.type }}
|
||||
strategy:
|
||||
matrix:
|
||||
type: [Release, Debug]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Configure CMake
|
||||
shell: bash
|
||||
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake -DANDROID_NATIVE_API_LEVEL=android-26
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: cmake --build build
|
||||
|
||||
check_format:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Configure CMake
|
||||
shell: bash
|
||||
run: cmake -S . -B build
|
||||
|
||||
- name: Check format
|
||||
shell: bash
|
||||
run: cmake --build build --target clang-format-check
|
||||
|
2
third-party/cubeb/cubeb/.gitignore
generated
vendored
Normal file
2
third-party/cubeb/cubeb/.gitignore
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.vscode/
|
||||
build/
|
6
third-party/cubeb/cubeb/.gitmodules
generated
vendored
Normal file
6
third-party/cubeb/cubeb/.gitmodules
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
[submodule "googletest"]
|
||||
path = googletest
|
||||
url = https://github.com/google/googletest
|
||||
[submodule "cmake/sanitizers-cmake"]
|
||||
path = cmake/sanitizers-cmake
|
||||
url = https://github.com/arsenm/sanitizers-cmake
|
16
third-party/cubeb/cubeb/AUTHORS
generated
vendored
Normal file
16
third-party/cubeb/cubeb/AUTHORS
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
Matthew Gregan <kinetik@flim.org>
|
||||
Alexandre Ratchov <alex@caoua.org>
|
||||
Michael Wu <mwu@mozilla.com>
|
||||
Paul Adenot <paul@paul.cx>
|
||||
David Richards <drichards@mozilla.com>
|
||||
Sebastien Alaiwan <sebastien.alaiwan@gmail.com>
|
||||
KO Myung-Hun <komh@chollian.net>
|
||||
Haakon Sporsheim <haakon.sporsheim@telenordigital.com>
|
||||
Alex Chronopoulos <achronop@gmail.com>
|
||||
Jan Beich <jbeich@FreeBSD.org>
|
||||
Vito Caputo <vito.caputo@coreos.com>
|
||||
Landry Breuil <landry@openbsd.org>
|
||||
Jacek Caban <jacek@codeweavers.com>
|
||||
Paul Hancock <Paul.Hancock.17041993@live.com>
|
||||
Ted Mielczarek <ted@mielczarek.org>
|
||||
Chun-Min Chang <chun.m.chang@gmail.com>
|
16
third-party/cubeb/cubeb/CMakeFiles/CMakeDirectoryInformation.cmake
generated
vendored
Normal file
16
third-party/cubeb/cubeb/CMakeFiles/CMakeDirectoryInformation.cmake
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Generated by "Unix Makefiles" Generator, CMake Version 3.22
|
||||
|
||||
# Relative path conversion top directories.
|
||||
set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/ziemas/Development/jak-project")
|
||||
set(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/ziemas/Development/jak-project")
|
||||
|
||||
# Force unix paths in dependencies.
|
||||
set(CMAKE_FORCE_UNIX_PATHS 1)
|
||||
|
||||
|
||||
# The C and CXX include file regular expressions for this directory.
|
||||
set(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$")
|
||||
set(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$")
|
||||
set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN})
|
||||
set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN})
|
19
third-party/cubeb/cubeb/CMakeFiles/Export/lib/cmake/cubeb/cubebTargets-release.cmake
generated
vendored
Normal file
19
third-party/cubeb/cubeb/CMakeFiles/Export/lib/cmake/cubeb/cubebTargets-release.cmake
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
#----------------------------------------------------------------
|
||||
# Generated CMake target import file for configuration "Release".
|
||||
#----------------------------------------------------------------
|
||||
|
||||
# Commands may need to know the format version.
|
||||
set(CMAKE_IMPORT_FILE_VERSION 1)
|
||||
|
||||
# Import target "cubeb::cubeb" for configuration "Release"
|
||||
set_property(TARGET cubeb::cubeb APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_target_properties(cubeb::cubeb PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C;CXX"
|
||||
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libcubeb.a"
|
||||
)
|
||||
|
||||
list(APPEND _IMPORT_CHECK_TARGETS cubeb::cubeb )
|
||||
list(APPEND _IMPORT_CHECK_FILES_FOR_cubeb::cubeb "${_IMPORT_PREFIX}/lib/libcubeb.a" )
|
||||
|
||||
# Commands beyond this point should not need to know the version.
|
||||
set(CMAKE_IMPORT_FILE_VERSION)
|
99
third-party/cubeb/cubeb/CMakeFiles/Export/lib/cmake/cubeb/cubebTargets.cmake
generated
vendored
Normal file
99
third-party/cubeb/cubeb/CMakeFiles/Export/lib/cmake/cubeb/cubebTargets.cmake
generated
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
# Generated by CMake
|
||||
|
||||
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.6)
|
||||
message(FATAL_ERROR "CMake >= 2.6.0 required")
|
||||
endif()
|
||||
cmake_policy(PUSH)
|
||||
cmake_policy(VERSION 2.6...3.20)
|
||||
#----------------------------------------------------------------
|
||||
# Generated CMake target import file.
|
||||
#----------------------------------------------------------------
|
||||
|
||||
# Commands may need to know the format version.
|
||||
set(CMAKE_IMPORT_FILE_VERSION 1)
|
||||
|
||||
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
|
||||
set(_targetsDefined)
|
||||
set(_targetsNotDefined)
|
||||
set(_expectedTargets)
|
||||
foreach(_expectedTarget cubeb::cubeb)
|
||||
list(APPEND _expectedTargets ${_expectedTarget})
|
||||
if(NOT TARGET ${_expectedTarget})
|
||||
list(APPEND _targetsNotDefined ${_expectedTarget})
|
||||
endif()
|
||||
if(TARGET ${_expectedTarget})
|
||||
list(APPEND _targetsDefined ${_expectedTarget})
|
||||
endif()
|
||||
endforeach()
|
||||
if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
|
||||
unset(_targetsDefined)
|
||||
unset(_targetsNotDefined)
|
||||
unset(_expectedTargets)
|
||||
set(CMAKE_IMPORT_FILE_VERSION)
|
||||
cmake_policy(POP)
|
||||
return()
|
||||
endif()
|
||||
if(NOT "${_targetsDefined}" STREQUAL "")
|
||||
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
|
||||
endif()
|
||||
unset(_targetsDefined)
|
||||
unset(_targetsNotDefined)
|
||||
unset(_expectedTargets)
|
||||
|
||||
|
||||
# Compute the installation prefix relative to this file.
|
||||
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
|
||||
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
|
||||
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
|
||||
if(_IMPORT_PREFIX STREQUAL "/")
|
||||
set(_IMPORT_PREFIX "")
|
||||
endif()
|
||||
|
||||
# Create imported target cubeb::cubeb
|
||||
add_library(cubeb::cubeb STATIC IMPORTED)
|
||||
|
||||
set_target_properties(cubeb::cubeb PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
|
||||
INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:>;\$<LINK_ONLY:Threads::Threads>;\$<LINK_ONLY:dl>"
|
||||
)
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 2.8.12)
|
||||
message(FATAL_ERROR "This file relies on consumers using CMake 2.8.12 or greater.")
|
||||
endif()
|
||||
|
||||
# Load information for each installed configuration.
|
||||
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
file(GLOB CONFIG_FILES "${_DIR}/cubebTargets-*.cmake")
|
||||
foreach(f ${CONFIG_FILES})
|
||||
include(${f})
|
||||
endforeach()
|
||||
|
||||
# Cleanup temporary variables.
|
||||
set(_IMPORT_PREFIX)
|
||||
|
||||
# Loop over all imported files and verify that they actually exist
|
||||
foreach(target ${_IMPORT_CHECK_TARGETS} )
|
||||
foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
|
||||
if(NOT EXISTS "${file}" )
|
||||
message(FATAL_ERROR "The imported target \"${target}\" references the file
|
||||
\"${file}\"
|
||||
but this file does not exist. Possible reasons include:
|
||||
* The file was deleted, renamed, or moved to another location.
|
||||
* An install or uninstall procedure did not complete successfully.
|
||||
* The installation package was faulty and contained
|
||||
\"${CMAKE_CURRENT_LIST_FILE}\"
|
||||
but not all the files it references.
|
||||
")
|
||||
endif()
|
||||
endforeach()
|
||||
unset(_IMPORT_CHECK_FILES_FOR_${target})
|
||||
endforeach()
|
||||
unset(_IMPORT_CHECK_TARGETS)
|
||||
|
||||
# This file does not depend on other imported targets which have
|
||||
# been exported from the same project but in a separate export set.
|
||||
|
||||
# Commands beyond this point should not need to know the version.
|
||||
set(CMAKE_IMPORT_FILE_VERSION)
|
||||
cmake_policy(POP)
|
18
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/DependInfo.cmake
generated
vendored
Normal file
18
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/DependInfo.cmake
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
# Consider dependencies only in project.
|
||||
set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
|
||||
|
||||
# The set of languages for which implicit dependencies are needed:
|
||||
set(CMAKE_DEPENDS_LANGUAGES
|
||||
)
|
||||
|
||||
# The set of dependency files which are needed:
|
||||
set(CMAKE_DEPENDS_DEPENDENCY_FILES
|
||||
)
|
||||
|
||||
# Targets to which this target links.
|
||||
set(CMAKE_TARGET_LINKED_INFO_FILES
|
||||
)
|
||||
|
||||
# Fortran module output directory.
|
||||
set(CMAKE_Fortran_TARGET_MODULE_DIR "")
|
88
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/build.make
generated
vendored
Normal file
88
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/build.make
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Generated by "Unix Makefiles" Generator, CMake Version 3.22
|
||||
|
||||
# Delete rule output on recipe failure.
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
#=============================================================================
|
||||
# Special targets provided by cmake.
|
||||
|
||||
# Disable implicit rules so canonical targets will work.
|
||||
.SUFFIXES:
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : %,v
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : RCS/%
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : RCS/%,v
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : SCCS/s.%
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : s.%
|
||||
|
||||
.SUFFIXES: .hpux_make_needs_suffix_list
|
||||
|
||||
# Command-line flag to silence nested $(MAKE).
|
||||
$(VERBOSE)MAKESILENT = -s
|
||||
|
||||
#Suppress display of executed commands.
|
||||
$(VERBOSE).SILENT:
|
||||
|
||||
# A target that is always out of date.
|
||||
cmake_force:
|
||||
.PHONY : cmake_force
|
||||
|
||||
#=============================================================================
|
||||
# Set environment variables for the build.
|
||||
|
||||
# The shell in which to execute make rules.
|
||||
SHELL = /bin/sh
|
||||
|
||||
# The CMake executable.
|
||||
CMAKE_COMMAND = /usr/bin/cmake
|
||||
|
||||
# The command to remove a file.
|
||||
RM = /usr/bin/cmake -E rm -f
|
||||
|
||||
# Escaping for special characters.
|
||||
EQUALS = =
|
||||
|
||||
# The top-level source directory on which CMake was run.
|
||||
CMAKE_SOURCE_DIR = /home/ziemas/Development/jak-project
|
||||
|
||||
# The top-level build directory on which CMake was run.
|
||||
CMAKE_BINARY_DIR = /home/ziemas/Development/jak-project
|
||||
|
||||
# Utility rule file for clang-format-check.
|
||||
|
||||
# Include any custom commands dependencies for this target.
|
||||
include third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/compiler_depend.make
|
||||
|
||||
# Include the progress variables for this target.
|
||||
include third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/progress.make
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/clang-format-check:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold --progress-dir=/home/ziemas/Development/jak-project/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Check formatting with clang-format"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && find /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/include -type f "(" -name "*.cpp" -o -name "*.c" -o -name "*.h" ")" -not -path "*/subprojects/speex/*" -print0 | xargs -0 clang-format -Werror -n
|
||||
|
||||
clang-format-check: third-party/cubeb/cubeb/CMakeFiles/clang-format-check
|
||||
clang-format-check: third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/build.make
|
||||
.PHONY : clang-format-check
|
||||
|
||||
# Rule to build all files generated by this target.
|
||||
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/build: clang-format-check
|
||||
.PHONY : third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/build
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/clean:
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && $(CMAKE_COMMAND) -P CMakeFiles/clang-format-check.dir/cmake_clean.cmake
|
||||
.PHONY : third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/clean
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/depend:
|
||||
cd /home/ziemas/Development/jak-project && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/ziemas/Development/jak-project /home/ziemas/Development/jak-project/third-party/cubeb/cubeb /home/ziemas/Development/jak-project /home/ziemas/Development/jak-project/third-party/cubeb/cubeb /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/DependInfo.cmake --color=$(COLOR)
|
||||
.PHONY : third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/depend
|
||||
|
8
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/cmake_clean.cmake
generated
vendored
Normal file
8
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/cmake_clean.cmake
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
file(REMOVE_RECURSE
|
||||
"CMakeFiles/clang-format-check"
|
||||
)
|
||||
|
||||
# Per-language clean rules from dependency scanning.
|
||||
foreach(lang )
|
||||
include(CMakeFiles/clang-format-check.dir/cmake_clean_${lang}.cmake OPTIONAL)
|
||||
endforeach()
|
2
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/compiler_depend.make
generated
vendored
Normal file
2
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/compiler_depend.make
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Empty custom commands generated dependencies file for clang-format-check.
|
||||
# This may be replaced when dependencies are built.
|
2
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/compiler_depend.ts
generated
vendored
Normal file
2
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/compiler_depend.ts
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Timestamp file for custom commands dependencies management for clang-format-check.
|
2
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/progress.make
generated
vendored
Normal file
2
third-party/cubeb/cubeb/CMakeFiles/clang-format-check.dir/progress.make
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
CMAKE_PROGRESS_1 =
|
||||
|
28
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/DependInfo.cmake
generated
vendored
Normal file
28
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/DependInfo.cmake
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
# Consider dependencies only in project.
|
||||
set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
|
||||
|
||||
# The set of languages for which implicit dependencies are needed:
|
||||
set(CMAKE_DEPENDS_LANGUAGES
|
||||
)
|
||||
|
||||
# The set of dependency files which are needed:
|
||||
set(CMAKE_DEPENDS_DEPENDENCY_FILES
|
||||
"/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb.c" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb.c.o" "gcc" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb.c.o.d"
|
||||
"/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_alsa.c" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_alsa.c.o" "gcc" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_alsa.c.o.d"
|
||||
"/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_pulse.c" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_pulse.c.o" "gcc" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_pulse.c.o.d"
|
||||
"/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_strings.c" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_strings.c.o" "gcc" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_strings.c.o.d"
|
||||
"/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_jack.cpp" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.o" "gcc" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.o.d"
|
||||
"/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_log.cpp" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_log.cpp.o" "gcc" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_log.cpp.o.d"
|
||||
"/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_mixer.cpp" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.o" "gcc" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.o.d"
|
||||
"/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_resampler.cpp" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.o" "gcc" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.o.d"
|
||||
"/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_utils.cpp" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.o" "gcc" "third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.o.d"
|
||||
)
|
||||
|
||||
# Targets to which this target links.
|
||||
set(CMAKE_TARGET_LINKED_INFO_FILES
|
||||
"/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/CMakeFiles/speex.dir/DependInfo.cmake"
|
||||
)
|
||||
|
||||
# Fortran module output directory.
|
||||
set(CMAKE_Fortran_TARGET_MODULE_DIR "")
|
239
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/build.make
generated
vendored
Normal file
239
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/build.make
generated
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Generated by "Unix Makefiles" Generator, CMake Version 3.22
|
||||
|
||||
# Delete rule output on recipe failure.
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
#=============================================================================
|
||||
# Special targets provided by cmake.
|
||||
|
||||
# Disable implicit rules so canonical targets will work.
|
||||
.SUFFIXES:
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : %,v
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : RCS/%
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : RCS/%,v
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : SCCS/s.%
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : s.%
|
||||
|
||||
.SUFFIXES: .hpux_make_needs_suffix_list
|
||||
|
||||
# Command-line flag to silence nested $(MAKE).
|
||||
$(VERBOSE)MAKESILENT = -s
|
||||
|
||||
#Suppress display of executed commands.
|
||||
$(VERBOSE).SILENT:
|
||||
|
||||
# A target that is always out of date.
|
||||
cmake_force:
|
||||
.PHONY : cmake_force
|
||||
|
||||
#=============================================================================
|
||||
# Set environment variables for the build.
|
||||
|
||||
# The shell in which to execute make rules.
|
||||
SHELL = /bin/sh
|
||||
|
||||
# The CMake executable.
|
||||
CMAKE_COMMAND = /usr/bin/cmake
|
||||
|
||||
# The command to remove a file.
|
||||
RM = /usr/bin/cmake -E rm -f
|
||||
|
||||
# Escaping for special characters.
|
||||
EQUALS = =
|
||||
|
||||
# The top-level source directory on which CMake was run.
|
||||
CMAKE_SOURCE_DIR = /home/ziemas/Development/jak-project
|
||||
|
||||
# The top-level build directory on which CMake was run.
|
||||
CMAKE_BINARY_DIR = /home/ziemas/Development/jak-project
|
||||
|
||||
# Include any dependencies generated for this target.
|
||||
include third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/depend.make
|
||||
# Include any dependencies generated by the compiler for this target.
|
||||
include third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/compiler_depend.make
|
||||
|
||||
# Include the progress variables for this target.
|
||||
include third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/progress.make
|
||||
|
||||
# Include the compile flags for this target's objects.
|
||||
include third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/flags.make
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb.c.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/flags.make
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb.c.o: third-party/cubeb/cubeb/src/cubeb.c
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb.c.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/ziemas/Development/jak-project/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building C object third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb.c.o"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -MD -MT third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb.c.o -MF CMakeFiles/cubeb.dir/src/cubeb.c.o.d -o CMakeFiles/cubeb.dir/src/cubeb.c.o -c /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb.c
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb.c.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/cubeb.dir/src/cubeb.c.i"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -E /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb.c > CMakeFiles/cubeb.dir/src/cubeb.c.i
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb.c.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/cubeb.dir/src/cubeb.c.s"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -S /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb.c -o CMakeFiles/cubeb.dir/src/cubeb.c.s
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/flags.make
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.o: third-party/cubeb/cubeb/src/cubeb_mixer.cpp
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/ziemas/Development/jak-project/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Building CXX object third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.o"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.o -MF CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.o.d -o CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.o -c /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_mixer.cpp
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.i"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_mixer.cpp > CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.i
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.s"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_mixer.cpp -o CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.s
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/flags.make
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.o: third-party/cubeb/cubeb/src/cubeb_resampler.cpp
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/ziemas/Development/jak-project/CMakeFiles --progress-num=$(CMAKE_PROGRESS_3) "Building CXX object third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.o"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.o -MF CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.o.d -o CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.o -c /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_resampler.cpp
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.i"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_resampler.cpp > CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.i
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.s"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_resampler.cpp -o CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.s
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_log.cpp.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/flags.make
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_log.cpp.o: third-party/cubeb/cubeb/src/cubeb_log.cpp
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_log.cpp.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/ziemas/Development/jak-project/CMakeFiles --progress-num=$(CMAKE_PROGRESS_4) "Building CXX object third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_log.cpp.o"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_log.cpp.o -MF CMakeFiles/cubeb.dir/src/cubeb_log.cpp.o.d -o CMakeFiles/cubeb.dir/src/cubeb_log.cpp.o -c /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_log.cpp
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_log.cpp.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/cubeb.dir/src/cubeb_log.cpp.i"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_log.cpp > CMakeFiles/cubeb.dir/src/cubeb_log.cpp.i
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_log.cpp.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/cubeb.dir/src/cubeb_log.cpp.s"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_log.cpp -o CMakeFiles/cubeb.dir/src/cubeb_log.cpp.s
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_strings.c.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/flags.make
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_strings.c.o: third-party/cubeb/cubeb/src/cubeb_strings.c
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_strings.c.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/ziemas/Development/jak-project/CMakeFiles --progress-num=$(CMAKE_PROGRESS_5) "Building C object third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_strings.c.o"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -MD -MT third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_strings.c.o -MF CMakeFiles/cubeb.dir/src/cubeb_strings.c.o.d -o CMakeFiles/cubeb.dir/src/cubeb_strings.c.o -c /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_strings.c
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_strings.c.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/cubeb.dir/src/cubeb_strings.c.i"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -E /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_strings.c > CMakeFiles/cubeb.dir/src/cubeb_strings.c.i
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_strings.c.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/cubeb.dir/src/cubeb_strings.c.s"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -S /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_strings.c -o CMakeFiles/cubeb.dir/src/cubeb_strings.c.s
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/flags.make
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.o: third-party/cubeb/cubeb/src/cubeb_utils.cpp
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/ziemas/Development/jak-project/CMakeFiles --progress-num=$(CMAKE_PROGRESS_6) "Building CXX object third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.o"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.o -MF CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.o.d -o CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.o -c /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_utils.cpp
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.i"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_utils.cpp > CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.i
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.s"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_utils.cpp -o CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.s
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_pulse.c.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/flags.make
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_pulse.c.o: third-party/cubeb/cubeb/src/cubeb_pulse.c
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_pulse.c.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/ziemas/Development/jak-project/CMakeFiles --progress-num=$(CMAKE_PROGRESS_7) "Building C object third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_pulse.c.o"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -MD -MT third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_pulse.c.o -MF CMakeFiles/cubeb.dir/src/cubeb_pulse.c.o.d -o CMakeFiles/cubeb.dir/src/cubeb_pulse.c.o -c /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_pulse.c
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_pulse.c.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/cubeb.dir/src/cubeb_pulse.c.i"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -E /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_pulse.c > CMakeFiles/cubeb.dir/src/cubeb_pulse.c.i
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_pulse.c.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/cubeb.dir/src/cubeb_pulse.c.s"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -S /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_pulse.c -o CMakeFiles/cubeb.dir/src/cubeb_pulse.c.s
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_alsa.c.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/flags.make
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_alsa.c.o: third-party/cubeb/cubeb/src/cubeb_alsa.c
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_alsa.c.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/ziemas/Development/jak-project/CMakeFiles --progress-num=$(CMAKE_PROGRESS_8) "Building C object third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_alsa.c.o"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -MD -MT third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_alsa.c.o -MF CMakeFiles/cubeb.dir/src/cubeb_alsa.c.o.d -o CMakeFiles/cubeb.dir/src/cubeb_alsa.c.o -c /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_alsa.c
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_alsa.c.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/cubeb.dir/src/cubeb_alsa.c.i"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -E /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_alsa.c > CMakeFiles/cubeb.dir/src/cubeb_alsa.c.i
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_alsa.c.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/cubeb.dir/src/cubeb_alsa.c.s"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/cc $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) -S /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_alsa.c -o CMakeFiles/cubeb.dir/src/cubeb_alsa.c.s
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/flags.make
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.o: third-party/cubeb/cubeb/src/cubeb_jack.cpp
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.o: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/compiler_depend.ts
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/ziemas/Development/jak-project/CMakeFiles --progress-num=$(CMAKE_PROGRESS_9) "Building CXX object third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.o"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.o -MF CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.o.d -o CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.o -c /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_jack.cpp
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.i: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing CXX source to CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.i"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_jack.cpp > CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.i
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.s: cmake_force
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling CXX source to assembly CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.s"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/src/cubeb_jack.cpp -o CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.s
|
||||
|
||||
# Object files for target cubeb
|
||||
cubeb_OBJECTS = \
|
||||
"CMakeFiles/cubeb.dir/src/cubeb.c.o" \
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.o" \
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.o" \
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_log.cpp.o" \
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_strings.c.o" \
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.o" \
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_pulse.c.o" \
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_alsa.c.o" \
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.o"
|
||||
|
||||
# External object files for target cubeb
|
||||
cubeb_EXTERNAL_OBJECTS =
|
||||
|
||||
third-party/cubeb/cubeb/libcubeb.a: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb.c.o
|
||||
third-party/cubeb/cubeb/libcubeb.a: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.o
|
||||
third-party/cubeb/cubeb/libcubeb.a: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.o
|
||||
third-party/cubeb/cubeb/libcubeb.a: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_log.cpp.o
|
||||
third-party/cubeb/cubeb/libcubeb.a: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_strings.c.o
|
||||
third-party/cubeb/cubeb/libcubeb.a: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.o
|
||||
third-party/cubeb/cubeb/libcubeb.a: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_pulse.c.o
|
||||
third-party/cubeb/cubeb/libcubeb.a: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_alsa.c.o
|
||||
third-party/cubeb/cubeb/libcubeb.a: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.o
|
||||
third-party/cubeb/cubeb/libcubeb.a: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/build.make
|
||||
third-party/cubeb/cubeb/libcubeb.a: third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/link.txt
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --bold --progress-dir=/home/ziemas/Development/jak-project/CMakeFiles --progress-num=$(CMAKE_PROGRESS_10) "Linking CXX static library libcubeb.a"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && $(CMAKE_COMMAND) -P CMakeFiles/cubeb.dir/cmake_clean_target.cmake
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/cubeb.dir/link.txt --verbose=$(VERBOSE)
|
||||
|
||||
# Rule to build all files generated by this target.
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/build: third-party/cubeb/cubeb/libcubeb.a
|
||||
.PHONY : third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/build
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/clean:
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && $(CMAKE_COMMAND) -P CMakeFiles/cubeb.dir/cmake_clean.cmake
|
||||
.PHONY : third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/clean
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/depend:
|
||||
cd /home/ziemas/Development/jak-project && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/ziemas/Development/jak-project /home/ziemas/Development/jak-project/third-party/cubeb/cubeb /home/ziemas/Development/jak-project /home/ziemas/Development/jak-project/third-party/cubeb/cubeb /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/DependInfo.cmake --color=$(COLOR)
|
||||
.PHONY : third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/depend
|
||||
|
27
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/cmake_clean.cmake
generated
vendored
Normal file
27
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/cmake_clean.cmake
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
file(REMOVE_RECURSE
|
||||
"CMakeFiles/cubeb.dir/src/cubeb.c.o"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb.c.o.d"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_alsa.c.o"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_alsa.c.o.d"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.o"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.o.d"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_log.cpp.o"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_log.cpp.o.d"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.o"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.o.d"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_pulse.c.o"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_pulse.c.o.d"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.o"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.o.d"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_strings.c.o"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_strings.c.o.d"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.o"
|
||||
"CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.o.d"
|
||||
"libcubeb.a"
|
||||
"libcubeb.pdb"
|
||||
)
|
||||
|
||||
# Per-language clean rules from dependency scanning.
|
||||
foreach(lang C CXX)
|
||||
include(CMakeFiles/cubeb.dir/cmake_clean_${lang}.cmake OPTIONAL)
|
||||
endforeach()
|
3
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/cmake_clean_target.cmake
generated
vendored
Normal file
3
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/cmake_clean_target.cmake
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
file(REMOVE_RECURSE
|
||||
"libcubeb.a"
|
||||
)
|
2
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/compiler_depend.make
generated
vendored
Normal file
2
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/compiler_depend.make
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Empty compiler generated dependencies file for cubeb.
|
||||
# This may be replaced when dependencies are built.
|
2
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/compiler_depend.ts
generated
vendored
Normal file
2
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/compiler_depend.ts
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Timestamp file for compiler generated dependencies management for cubeb.
|
2
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/depend.make
generated
vendored
Normal file
2
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/depend.make
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Empty dependencies file for cubeb.
|
||||
# This may be replaced when dependencies are built.
|
17
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/flags.make
generated
vendored
Normal file
17
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/flags.make
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Generated by "Unix Makefiles" Generator, CMake Version 3.22
|
||||
|
||||
# compile C with /usr/bin/cc
|
||||
# compile CXX with /usr/bin/c++
|
||||
C_DEFINES = -DEXPORT="" -DFLOATING_POINT -DOUTSIDE_SPEEX -DRANDOM_PREFIX=speex -DUSE_ALSA -DUSE_JACK -DUSE_PULSE
|
||||
|
||||
C_INCLUDES = -I/home/ziemas/Development/jak-project/. -I/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/include -I/home/ziemas/Development/jak-project/exports -I/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/subprojects -isystem /home/ziemas/Development/jak-project/third-party/inja
|
||||
|
||||
C_FLAGS = -Wall -Wextra -Wno-unused-parameter -O3 -DNDEBUG -fvisibility=hidden -std=gnu99
|
||||
|
||||
CXX_DEFINES = -DEXPORT="" -DFLOATING_POINT -DOUTSIDE_SPEEX -DRANDOM_PREFIX=speex -DUSE_ALSA -DUSE_JACK -DUSE_PULSE
|
||||
|
||||
CXX_INCLUDES = -I/home/ziemas/Development/jak-project/. -I/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/include -I/home/ziemas/Development/jak-project/exports -I/home/ziemas/Development/jak-project/third-party/cubeb/cubeb/subprojects -isystem /home/ziemas/Development/jak-project/third-party/inja
|
||||
|
||||
CXX_FLAGS = -Wall -Winit-self -ggdb -Wextra -Wno-cast-align -Wcast-qual -Wdisabled-optimization -Wformat -Wmissing-include-dirs -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-promo -fdiagnostics-color=always -mavx -O3 -Wall -Wextra -Wno-unused-parameter -fno-exceptions -fno-rtti -O3 -DNDEBUG -fvisibility=hidden -fvisibility-inlines-hidden -std=gnu++11
|
||||
|
2
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/link.txt
generated
vendored
Normal file
2
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/link.txt
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/usr/bin/ar qc libcubeb.a CMakeFiles/cubeb.dir/src/cubeb.c.o CMakeFiles/cubeb.dir/src/cubeb_mixer.cpp.o CMakeFiles/cubeb.dir/src/cubeb_resampler.cpp.o CMakeFiles/cubeb.dir/src/cubeb_log.cpp.o CMakeFiles/cubeb.dir/src/cubeb_strings.c.o CMakeFiles/cubeb.dir/src/cubeb_utils.cpp.o CMakeFiles/cubeb.dir/src/cubeb_pulse.c.o CMakeFiles/cubeb.dir/src/cubeb_alsa.c.o CMakeFiles/cubeb.dir/src/cubeb_jack.cpp.o
|
||||
/usr/bin/ranlib libcubeb.a
|
11
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/progress.make
generated
vendored
Normal file
11
third-party/cubeb/cubeb/CMakeFiles/cubeb.dir/progress.make
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
CMAKE_PROGRESS_1 =
|
||||
CMAKE_PROGRESS_2 =
|
||||
CMAKE_PROGRESS_3 =
|
||||
CMAKE_PROGRESS_4 = 26
|
||||
CMAKE_PROGRESS_5 =
|
||||
CMAKE_PROGRESS_6 =
|
||||
CMAKE_PROGRESS_7 =
|
||||
CMAKE_PROGRESS_8 =
|
||||
CMAKE_PROGRESS_9 = 27
|
||||
CMAKE_PROGRESS_10 =
|
||||
|
18
third-party/cubeb/cubeb/CMakeFiles/doc.dir/DependInfo.cmake
generated
vendored
Normal file
18
third-party/cubeb/cubeb/CMakeFiles/doc.dir/DependInfo.cmake
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
# Consider dependencies only in project.
|
||||
set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF)
|
||||
|
||||
# The set of languages for which implicit dependencies are needed:
|
||||
set(CMAKE_DEPENDS_LANGUAGES
|
||||
)
|
||||
|
||||
# The set of dependency files which are needed:
|
||||
set(CMAKE_DEPENDS_DEPENDENCY_FILES
|
||||
)
|
||||
|
||||
# Targets to which this target links.
|
||||
set(CMAKE_TARGET_LINKED_INFO_FILES
|
||||
)
|
||||
|
||||
# Fortran module output directory.
|
||||
set(CMAKE_Fortran_TARGET_MODULE_DIR "")
|
88
third-party/cubeb/cubeb/CMakeFiles/doc.dir/build.make
generated
vendored
Normal file
88
third-party/cubeb/cubeb/CMakeFiles/doc.dir/build.make
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Generated by "Unix Makefiles" Generator, CMake Version 3.22
|
||||
|
||||
# Delete rule output on recipe failure.
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
#=============================================================================
|
||||
# Special targets provided by cmake.
|
||||
|
||||
# Disable implicit rules so canonical targets will work.
|
||||
.SUFFIXES:
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : %,v
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : RCS/%
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : RCS/%,v
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : SCCS/s.%
|
||||
|
||||
# Disable VCS-based implicit rules.
|
||||
% : s.%
|
||||
|
||||
.SUFFIXES: .hpux_make_needs_suffix_list
|
||||
|
||||
# Command-line flag to silence nested $(MAKE).
|
||||
$(VERBOSE)MAKESILENT = -s
|
||||
|
||||
#Suppress display of executed commands.
|
||||
$(VERBOSE).SILENT:
|
||||
|
||||
# A target that is always out of date.
|
||||
cmake_force:
|
||||
.PHONY : cmake_force
|
||||
|
||||
#=============================================================================
|
||||
# Set environment variables for the build.
|
||||
|
||||
# The shell in which to execute make rules.
|
||||
SHELL = /bin/sh
|
||||
|
||||
# The CMake executable.
|
||||
CMAKE_COMMAND = /usr/bin/cmake
|
||||
|
||||
# The command to remove a file.
|
||||
RM = /usr/bin/cmake -E rm -f
|
||||
|
||||
# Escaping for special characters.
|
||||
EQUALS = =
|
||||
|
||||
# The top-level source directory on which CMake was run.
|
||||
CMAKE_SOURCE_DIR = /home/ziemas/Development/jak-project
|
||||
|
||||
# The top-level build directory on which CMake was run.
|
||||
CMAKE_BINARY_DIR = /home/ziemas/Development/jak-project
|
||||
|
||||
# Utility rule file for doc.
|
||||
|
||||
# Include any custom commands dependencies for this target.
|
||||
include third-party/cubeb/cubeb/CMakeFiles/doc.dir/compiler_depend.make
|
||||
|
||||
# Include the progress variables for this target.
|
||||
include third-party/cubeb/cubeb/CMakeFiles/doc.dir/progress.make
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/doc:
|
||||
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold --progress-dir=/home/ziemas/Development/jak-project/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Generating API documentation with Doxygen"
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/docs && /usr/bin/doxygen /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/docs/Doxyfile
|
||||
|
||||
doc: third-party/cubeb/cubeb/CMakeFiles/doc
|
||||
doc: third-party/cubeb/cubeb/CMakeFiles/doc.dir/build.make
|
||||
.PHONY : doc
|
||||
|
||||
# Rule to build all files generated by this target.
|
||||
third-party/cubeb/cubeb/CMakeFiles/doc.dir/build: doc
|
||||
.PHONY : third-party/cubeb/cubeb/CMakeFiles/doc.dir/build
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/doc.dir/clean:
|
||||
cd /home/ziemas/Development/jak-project/third-party/cubeb/cubeb && $(CMAKE_COMMAND) -P CMakeFiles/doc.dir/cmake_clean.cmake
|
||||
.PHONY : third-party/cubeb/cubeb/CMakeFiles/doc.dir/clean
|
||||
|
||||
third-party/cubeb/cubeb/CMakeFiles/doc.dir/depend:
|
||||
cd /home/ziemas/Development/jak-project && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/ziemas/Development/jak-project /home/ziemas/Development/jak-project/third-party/cubeb/cubeb /home/ziemas/Development/jak-project /home/ziemas/Development/jak-project/third-party/cubeb/cubeb /home/ziemas/Development/jak-project/third-party/cubeb/cubeb/CMakeFiles/doc.dir/DependInfo.cmake --color=$(COLOR)
|
||||
.PHONY : third-party/cubeb/cubeb/CMakeFiles/doc.dir/depend
|
||||
|
8
third-party/cubeb/cubeb/CMakeFiles/doc.dir/cmake_clean.cmake
generated
vendored
Normal file
8
third-party/cubeb/cubeb/CMakeFiles/doc.dir/cmake_clean.cmake
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
file(REMOVE_RECURSE
|
||||
"CMakeFiles/doc"
|
||||
)
|
||||
|
||||
# Per-language clean rules from dependency scanning.
|
||||
foreach(lang )
|
||||
include(CMakeFiles/doc.dir/cmake_clean_${lang}.cmake OPTIONAL)
|
||||
endforeach()
|
2
third-party/cubeb/cubeb/CMakeFiles/doc.dir/compiler_depend.make
generated
vendored
Normal file
2
third-party/cubeb/cubeb/CMakeFiles/doc.dir/compiler_depend.make
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Empty custom commands generated dependencies file for doc.
|
||||
# This may be replaced when dependencies are built.
|
2
third-party/cubeb/cubeb/CMakeFiles/doc.dir/compiler_depend.ts
generated
vendored
Normal file
2
third-party/cubeb/cubeb/CMakeFiles/doc.dir/compiler_depend.ts
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# CMAKE generated file: DO NOT EDIT!
|
||||
# Timestamp file for custom commands dependencies management for doc.
|
2
third-party/cubeb/cubeb/CMakeFiles/doc.dir/progress.make
generated
vendored
Normal file
2
third-party/cubeb/cubeb/CMakeFiles/doc.dir/progress.make
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
CMAKE_PROGRESS_1 =
|
||||
|
1
third-party/cubeb/cubeb/CMakeFiles/progress.marks
generated
vendored
Normal file
1
third-party/cubeb/cubeb/CMakeFiles/progress.marks
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
2
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user