Implement & link jaudio_NES/internal/streamctrl.c

This commit is contained in:
Cuyler36
2024-06-08 22:57:45 -04:00
parent 320baf22b8
commit 3bb7c0c89f
5 changed files with 255 additions and 64 deletions
+2
View File
@@ -6,6 +6,7 @@ symbol_aligns:
0x80018920: 32
0x800190e0: 32
0x80019380: 32
0x80019760: 32
0x8001a0c0: 32
0x80031d80: 32
0x80207458: 8 # align RunQueue to 0x001251d8
@@ -14,3 +15,4 @@ symbol_aligns:
0x800daaa0: 32 # align texture_cache_data_func to 32 bytes
0x80206f30: 16 # malloc.c align 16 bytes
0x800ab260: 32
0x801864b0: 8 # dspbuf align 8 (not sure why this doesn't happen)
+5
View File
@@ -84,6 +84,11 @@ jaudio_NES/internal/neosthread.c:
.bss: [0x80180020, 0x80186440]
.sdata: [0x80217be0, 0x80217be8]
.sbss: [0x80218460, 0x80218478]
jaudio_NES/internal/streamctrl.c:
.text: [0x80019380, 0x80019760]
.data: [0x800d01a8, 0x800d0278]
.bss: [0x80186440, 0x801864b0]
.sdata2: [0x80218dc0, 0x80218dd0]
jaudio_NES/internal/playercall.c:
.text: [0x80019dc0, 0x8001a0c0]
.bss: [0x801864d0,0x80186590]
+67 -64
View File
@@ -19,89 +19,89 @@ typedef void (*DVDDoneReadCallback)(s32, DVDFileInfo*);
typedef void (*DVDOptionalCommandChecker)(DVDCommandBlock* block, DVDLowCallback callback);
typedef struct DVDDriveInfo {
u16 revisionLevel; // _00
u16 deviceCode; // _02
u32 releaseDate; // _04
u8 padding[24]; // _08
u16 revisionLevel; // _00
u16 deviceCode; // _02
u32 releaseDate; // _04
u8 padding[24]; // _08
} DVDDriveInfo;
// Struct for DVD information (size 0x20)
typedef struct DVDDiskID {
char gameName[4]; // _00
char company[2]; // _04
u8 diskNumber; // _06
u8 gameVersion; // _07
u8 streaming; // _08
u8 streamBufSize; // _09, default = 0
u8 padding[22]; // _0A, all 0s
char gameName[4]; // _00
char company[2]; // _04
u8 diskNumber; // _06
u8 gameVersion; // _07
u8 streaming; // _08
u8 streamBufSize; // _09, default = 0
u8 padding[22]; // _0A, all 0s
} DVDDiskID;
// Struct for command information (size 0x30).
struct DVDCommandBlock {
DVDCommandBlock* next; // _00
DVDCommandBlock* prev; // _04
u32 command; // _08
s32 state; // _0C
u32 offset; // _10
u32 length; // _14
void* addr; // _18
u32 currTransferSize; // _1C
u32 transferredSize; // _20
DVDDiskID* id; // _24
DVDCBCallback callback; // _28
void* userData; // _2C
DVDCommandBlock* next; // _00
DVDCommandBlock* prev; // _04
u32 command; // _08
s32 state; // _0C
u32 offset; // _10
u32 length; // _14
void* addr; // _18
u32 currTransferSize; // _1C
u32 transferredSize; // _20
DVDDiskID* id; // _24
DVDCBCallback callback; // _28
void* userData; // _2C
};
// Struct for file information (size 0x3C).
// NB: we had this as DVDPlayer previously.
struct DVDFileInfo {
DVDCommandBlock cBlock; // _00
u32 startAddr; // _30
u32 length; // _34
DVDCallback callback; // _38
DVDCommandBlock cBlock; // _00
u32 startAddr; // _30
u32 length; // _34
DVDCallback callback; // _38
};
// Struct for directory information (size 0xC).
typedef struct DVDDir {
u32 entryNum; // _00
u32 location; // _04
u32 next; // _08
u32 entryNum; // _00
u32 location; // _04
u32 next; // _08
} DVDDir;
// Struct for directory entries (size 0xC).
typedef struct DVDDirEntry {
u32 entryNum; // _00
BOOL isDir; // _04
char* name; // _08
u32 entryNum; // _00
BOOL isDir; // _04
char* name; // _08
} DVDDirEntry;
// Struct for handing queues.
typedef struct DVDQueue DVDQueue;
struct DVDQueue {
DVDQueue* mHead; // _00
DVDQueue* mTail; // _04
DVDQueue* mHead; // _00
DVDQueue* mTail; // _04
};
// DVD Boot information instructions.
// Struct 1.
typedef struct DVDBB1 {
u32 appLoaderLength; // _00
void* appLoaderFunc1; // _04
void* appLoaderFunc2; // _08
void* appLoaderFunc3; // _0C
u32 appLoaderLength; // _00
void* appLoaderFunc1; // _04
void* appLoaderFunc2; // _08
void* appLoaderFunc3; // _0C
} DVDBB1;
// Struct 2.
typedef struct DVDBB2 {
u32 bootFilePosition; // _00
u32 FSTPosition; // _04
u32 FSTLength; // _08
u32 FSTMaxLength; // _0C
void* FSTAddress; // _10
u32 userPosition; // _14
u32 userLength; // _18
u32 reserved_1C; // _1C
u32 bootFilePosition; // _00
u32 FSTPosition; // _04
u32 FSTLength; // _08
u32 FSTMaxLength; // _0C
void* FSTAddress; // _10
u32 userPosition; // _14
u32 userLength; // _18
u32 reserved_1C; // _1C
} DVDBB2;
//////////////////////////////////
@@ -143,6 +143,8 @@ s32 DVDGetTransferredSize(DVDFileInfo* fileInfo);
DVDDiskID* DVDGetCurrentDiskID();
BOOL DVDCompareDiskID(DVDDiskID* id1, DVDDiskID* id2);
DVDLowCallback DVDLowClearCallback();
BOOL DVDPrepareStreamAsync(DVDFileInfo* fileInfo, u32 length, u32 offset, DVDCallback callback);
s32 DVDCancelStream(DVDCommandBlock* block);
BOOL DVDCheckDisk();
@@ -160,36 +162,37 @@ void DVDDumpWaitingQueue();
////// USEFUL DVD DEFINES ////////
// Macro for reading.
#define DVDReadAsync(fileInfo, addr, length, offset, callback) DVDReadAsyncPrio((fileInfo), (addr), (length), (offset), (callback), 2)
#define DVDReadAsync(fileInfo, addr, length, offset, callback) \
DVDReadAsyncPrio((fileInfo), (addr), (length), (offset), (callback), 2)
#define DVDGetFileInfoStatus(fileInfo) DVDGetCommandBlockStatus(&(fileInfo)->cBlock)
// Minimum transfer size.
#define DVD_MIN_TRANSFER_SIZE 32
// DVD states.
#define DVD_STATE_FATAL_ERROR -1
#define DVD_STATE_END 0
#define DVD_STATE_BUSY 1
#define DVD_STATE_WAITING 2
#define DVD_STATE_COVER_CLOSED 3
#define DVD_STATE_NO_DISK 4
#define DVD_STATE_COVER_OPEN 5
#define DVD_STATE_WRONG_DISK 6
#define DVD_STATE_FATAL_ERROR -1
#define DVD_STATE_END 0
#define DVD_STATE_BUSY 1
#define DVD_STATE_WAITING 2
#define DVD_STATE_COVER_CLOSED 3
#define DVD_STATE_NO_DISK 4
#define DVD_STATE_COVER_OPEN 5
#define DVD_STATE_WRONG_DISK 6
#define DVD_STATE_MOTOR_STOPPED 7
#define DVD_STATE_PAUSING 8
#define DVD_STATE_IGNORED 9
#define DVD_STATE_CANCELED 10
#define DVD_STATE_RETRY 11
#define DVD_STATE_PAUSING 8
#define DVD_STATE_IGNORED 9
#define DVD_STATE_CANCELED 10
#define DVD_STATE_RETRY 11
// File info states.
#define DVD_FILEINFO_READY 0
#define DVD_FILEINFO_BUSY 1
#define DVD_FILEINFO_BUSY 1
// DVD results.
#define DVD_RESULT_GOOD 0
#define DVD_RESULT_GOOD 0
#define DVD_RESULT_FATAL_ERROR -1
#define DVD_RESULT_IGNORED -2
#define DVD_RESULT_CANCELED -3
#define DVD_RESULT_IGNORED -2
#define DVD_RESULT_CANCELED -3
#define DVD_AIS_SUCCESS 0
+38
View File
@@ -3,6 +3,44 @@
#include "types.h"
/* @unused */
// Jac_PlayStreamBGM(s32, s32, s32);
// Jac_StopStreamBGM(s32, s32);
// Jac_VolMoveStreamBGM(s32, s32);
#define JSTREAM_NO_TRACK_ID (-1)
#define JSTREAM_FADEOUT_TIMER (120)
typedef struct JSTREAM_ {
s32 state;
s32 req_stream_id;
s32 now_stream_id;
f32 fadein_vol;
s32 fadein_vol_timer;
s32 _14;
s32 fadeout_timer;
f32 target_vol1;
s32 change_vol_timer1;
f32 stream_vol;
u32 total_samples;
} JSTREAM;
typedef enum JSTREAM_STATE_ {
JSTREAM_STATE_STOPPED,
JSTREAM_STATE_REQUEST_STREAM,
JSTREAM_STATE_START,
JSTREAM_STATE_PLAYING,
JSTREAM_STATE_CANCELLED,
JSTREAM_STATE_FADEOUT,
JSTREAM_STATE_STOP,
JSTREAM_STATE_CLEANUP,
JSTREAM_STATE_NUM
} JSTREAM_STATE;
extern char J_STREAMNAME[][16];
extern JSTREAM J_STREAM;
extern void StreamMain(void);
#endif
+143
View File
@@ -0,0 +1,143 @@
#include "jaudio_NES/streamctrl.h"
#include "jaudio_NES/audiowork.h"
#include "jaudio_NES/rate.h"
#include "dolphin/ai.h"
#include "dolphin/dvd.h"
char J_STREAMNAME[8][16] = {
"/stream00.adp", "/stream01.adp", "/stream02.adp", "/stream03.adp",
"/stream04.adp", "/stream05.adp", "/stream06.adp", "/stream07.adp",
};
// clang-format off
JSTREAM J_STREAM = {
JSTREAM_STATE_STOPPED,
JSTREAM_NO_TRACK_ID, JSTREAM_NO_TRACK_ID,
0.0f, 0,
0,
0,
0.0f, 0,
0.0f,
0
};
// clang-format on
/* @fabricated -- necessary for float ordering */
#pragma force_active on
MATCH_FORCESTRIP static f32 Jac_VolMoveStreamBGM(s32 l, s32 r) {
// AISetStreamVolLeft((s32)(f32)l);
// AISetStreamVolRight((s32)(f32)r);
return l;
}
#pragma force_active reset
extern void StreamMain(void) {
static DVDFileInfo finfo;
static DVDCommandBlock cmd;
u32 streamed_samples;
u32 trigger;
switch (J_STREAM.state) {
case JSTREAM_STATE_STOPPED:
break;
case JSTREAM_STATE_REQUEST_STREAM:
J_STREAM.now_stream_id = J_STREAM.req_stream_id;
J_STREAM.req_stream_id = JSTREAM_NO_TRACK_ID;
if (J_STREAM.now_stream_id == JSTREAM_NO_TRACK_ID) {
J_STREAM.state = JSTREAM_STATE_STOPPED;
} else {
if (DVDOpen(J_STREAMNAME[J_STREAM.now_stream_id], &finfo) == FALSE) {
J_STREAM.now_stream_id = JSTREAM_NO_TRACK_ID;
J_STREAM.state = JSTREAM_STATE_STOPPED;
} else {
J_STREAM.total_samples = finfo.length;
J_STREAM.total_samples =
(J_STREAM.total_samples / 256) * 224; // TODO: should probably make these defines
AISetStreamSampleRate(AI_SAMPLERATE_48KHZ);
if (J_STREAM.fadein_vol_timer == 0) {
J_STREAM.stream_vol = J_STREAM.fadein_vol;
} else {
J_STREAM.stream_vol = 0.0f;
}
AISetStreamVolLeft((s32)J_STREAM.stream_vol);
AISetStreamVolRight((s32)J_STREAM.stream_vol);
DVDPrepareStreamAsync(&finfo, 0, 0, nullptr);
J_STREAM.state = JSTREAM_STATE_START;
}
}
break;
case JSTREAM_STATE_START:
if (DVDGetDriveStatus() == DVD_STATE_END) {
AIResetStreamSampleCount();
AISetStreamPlayState(AI_STREAM_START);
J_STREAM.state = JSTREAM_STATE_PLAYING;
}
break;
case JSTREAM_STATE_PLAYING:
streamed_samples = AIGetStreamSampleCount();
trigger = AIGetStreamTrigger();
if (J_STREAM.fadein_vol_timer != 0) {
f32 vol = J_STREAM.fadein_vol;
vol -= J_STREAM.stream_vol;
vol /= (f32)J_STREAM.fadein_vol_timer;
J_STREAM.stream_vol += vol;
J_STREAM.fadein_vol_timer--;
AISetStreamVolLeft((s32)J_STREAM.stream_vol);
AISetStreamVolRight((s32)J_STREAM.stream_vol);
}
if (J_STREAM.change_vol_timer1 != 0) {
f32 vol = J_STREAM.target_vol1;
vol -= J_STREAM.stream_vol;
vol /= (f32)J_STREAM.change_vol_timer1;
J_STREAM.stream_vol += vol;
J_STREAM.change_vol_timer1--;
AISetStreamVolLeft((s32)J_STREAM.stream_vol);
AISetStreamVolRight((s32)J_STREAM.stream_vol);
}
if ((J_STREAM.total_samples - streamed_samples) < (JAC_FRAMESAMPLES * JSTREAM_FADEOUT_TIMER)) {
J_STREAM.state = JSTREAM_STATE_FADEOUT;
J_STREAM.fadeout_timer = JSTREAM_FADEOUT_TIMER;
}
break;
case JSTREAM_STATE_CANCELLED:
case JSTREAM_STATE_FADEOUT:
u32 streamed_samples = AIGetStreamSampleCount();
if (J_STREAM.fadeout_timer != 0 && (J_STREAM.total_samples - streamed_samples) != 0) {
f32 vol = -J_STREAM.stream_vol;
vol /= (f32)J_STREAM.fadeout_timer;
J_STREAM.stream_vol += vol;
J_STREAM.fadeout_timer--;
AISetStreamVolLeft((s32)J_STREAM.stream_vol);
AISetStreamVolRight((s32)J_STREAM.stream_vol);
} else {
DVDCancelStream(&cmd);
J_STREAM.state = JSTREAM_STATE_STOP;
}
break;
case JSTREAM_STATE_STOP:
if (DVDGetDriveStatus() == DVD_STATE_END) {
AISetStreamPlayState(AI_STREAM_STOP);
J_STREAM.state = JSTREAM_STATE_CLEANUP;
}
break;
case JSTREAM_STATE_CLEANUP:
if (DVDGetDriveStatus() == DVD_STATE_END) {
DVDClose(&finfo);
J_STREAM.now_stream_id = -1;
J_STREAM.state = JSTREAM_STATE_REQUEST_STREAM;
AISetStreamPlayState(AI_STREAM_STOP);
}
break;
}
}