Initial Sound Implementation (#1325)

This commit is contained in:
Ziemas 2022-05-19 22:54:36 +02:00 committed by GitHub
parent be976d2e69
commit 07cc0ddc35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
377 changed files with 108012 additions and 338 deletions

View File

@ -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)

View File

@ -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()

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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"

View File

@ -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;
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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();

View File

@ -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");
}

View File

@ -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);

View File

@ -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;

View File

@ -11,6 +11,8 @@
#include "common/common_types.h"
extern u32 gMemFreeAtStart;
void ramdisk_init_globals();
void InitRamdisk();
u32 Thread_Server();

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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;
}

View 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

View 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
View 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
View 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

View 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

View 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
View 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)

View 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; };
};

View 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

View 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
View 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 = {};
};

View 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 },
} };

View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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();
}

View File

@ -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_

View File

@ -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;
}
/*!

View File

@ -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)

View 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
View File

@ -0,0 +1 @@
2

10
third-party/cubeb/CMakeLists.txt generated vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,2 @@
.vscode/
build/

6
third-party/cubeb/cubeb/.gitmodules generated vendored Normal file
View 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
View 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>

View 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})

View 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)

View 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)

View 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 "")

View 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

View 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()

View File

@ -0,0 +1,2 @@
# Empty custom commands generated dependencies file for clang-format-check.
# This may be replaced when dependencies are built.

View File

@ -0,0 +1,2 @@
# CMAKE generated file: DO NOT EDIT!
# Timestamp file for custom commands dependencies management for clang-format-check.

View File

@ -0,0 +1,2 @@
CMAKE_PROGRESS_1 =

View 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
View 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

View 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()

View File

@ -0,0 +1,3 @@
file(REMOVE_RECURSE
"libcubeb.a"
)

View File

@ -0,0 +1,2 @@
# Empty compiler generated dependencies file for cubeb.
# This may be replaced when dependencies are built.

View File

@ -0,0 +1,2 @@
# CMAKE generated file: DO NOT EDIT!
# Timestamp file for compiler generated dependencies management for cubeb.

View File

@ -0,0 +1,2 @@
# Empty dependencies file for cubeb.
# This may be replaced when dependencies are built.

View 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

View 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

View 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 =

View 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
View 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

View 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()

View File

@ -0,0 +1,2 @@
# Empty custom commands generated dependencies file for doc.
# This may be replaced when dependencies are built.

View File

@ -0,0 +1,2 @@
# CMAKE generated file: DO NOT EDIT!
# Timestamp file for custom commands dependencies management for doc.

View File

@ -0,0 +1,2 @@
CMAKE_PROGRESS_1 =

1
third-party/cubeb/cubeb/CMakeFiles/progress.marks generated vendored Normal file
View File

@ -0,0 +1 @@
2

Some files were not shown because too many files have changed in this diff Show More