aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorspicyjpeg <thatspicyjpeg@gmail.com>2022-07-31 18:04:59 +0200
committerspicyjpeg <thatspicyjpeg@gmail.com>2022-07-31 18:04:59 +0200
commit9560a1427aec1681c5d0c2bc30190ce4b1ad8557 (patch)
tree3aad9d0f632687b86b9639c714d49a1a9f1c2397 /examples
parent073a859acf16ccbc0f49364e38126bf2bf03aa3d (diff)
downloadpsn00bsdk-9560a1427aec1681c5d0c2bc30190ce4b1ad8557.tar.gz
Rewrite libpsxspu in C and update sound examples
Diffstat (limited to 'examples')
-rw-r--r--examples/sound/spustream/main.c48
-rw-r--r--examples/sound/vagsample/main.c10
2 files changed, 21 insertions, 37 deletions
diff --git a/examples/sound/spustream/main.c b/examples/sound/spustream/main.c
index 6b9db93..2ad122c 100644
--- a/examples/sound/spustream/main.c
+++ b/examples/sound/spustream/main.c
@@ -123,8 +123,8 @@ typedef struct {
} DB;
typedef struct {
- DB db[2];
- uint32_t db_active;
+ DB db[2];
+ int db_active;
} CONTEXT;
void init_context(CONTEXT *ctx) {
@@ -170,23 +170,13 @@ void display(CONTEXT *ctx) {
/* Stream interrupt handlers */
-// This is a silent looping sample used to keep unused SPU channels busy,
-// preventing them from accidentally triggering the SPU RAM interrupt and
-// throwing off the timing (all channels are always reading sample data, even
-// when "stopped"). It is 64 bytes as that is the minimum size for SPU DMA
-// transfers, however only the first 16 bytes are kept. The rest is going to be
-// overwritten by chunks.
-// https://problemkaputt.de/psx-spx.htm#spuinterrupt
-const uint8_t SPU_DUMMY_BLOCK[] = {
- 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
// The first 4 KB of SPU RAM are reserved for capture buffers, so we have to
-// place stream buffers after those. Sony's SPU library additionally places a
-// dummy sample at 0x1000; we are going to do the same with the block above.
+// place stream buffers after those. A dummy sample is additionally placed by
+// default by the SPU library at 0x1000; it is going to be used here to keep
+// unused SPU channels busy, preventing them from accidentally triggering the
+// SPU RAM interrupt and throwing off the timing (all channels are always
+// reading sample data, even when "stopped").
+// https://problemkaputt.de/psx-spx.htm#spuinterrupt
#define DUMMY_BLOCK_ADDR 0x1000
#define BUFFER_START_ADDR 0x1010
#define CHUNK_SIZE (BUFFER_SIZE * NUM_CHANNELS)
@@ -207,7 +197,7 @@ static volatile StreamContext str_ctx;
// read from the CD and uploaded to SPU RAM. Due to DMA limitations it can't be
// allocated on the stack (especially not in the interrupt callbacks' stack,
// whose size is very limited).
-static uint8_t sector_buffer[2048];
+static uint32_t sector_buffer[512];
void spu_irq_handler(void) {
// Acknowledge the interrupt to ensure it can be triggered again. The only
@@ -231,7 +221,7 @@ void spu_irq_handler(void) {
str_ctx.spu_addr = BUFFER_START_ADDR + CHUNK_SIZE * str_ctx.db_active;
SPU_IRQ_ADDR = SPU_RAM_ADDR(str_ctx.spu_addr);
- for (uint32_t i = 0; i < NUM_CHANNELS; i++)
+ for (int i = 0; i < NUM_CHANNELS; i++)
SPU_CH_LOOP_ADDR(i) = SPU_RAM_ADDR(str_ctx.spu_addr + BUFFER_SIZE * i);
// Start loading the next chunk. cd_event_handler() will be called
@@ -241,7 +231,7 @@ void spu_irq_handler(void) {
CdControlF(CdlReadN, &pos);
}
-void cd_event_handler(int32_t event, uint8_t *payload) {
+void cd_event_handler(int event, uint8_t *payload) {
// Ignore all events other than a sector being ready.
// TODO: read errors should be handled properly
if (event != CdlDataReady)
@@ -255,7 +245,7 @@ void cd_event_handler(int32_t event, uint8_t *payload) {
// other buffer, as we're overriding loop addresses) at the end.
// NOTE: this isn't actually necessary here as the stream converter script
// already sets these flags in the file.
- /*for (uint32_t i = 0; i < NUM_CHANNELS; i++) {
+ /*for (int i = 0; i < NUM_CHANNELS; i++) {
if (
str_ctx.spu_pos >= (BUFFER_SIZE * i - 2048) &&
str_ctx.spu_pos < (BUFFER_SIZE * i)
@@ -268,7 +258,7 @@ void cd_event_handler(int32_t event, uint8_t *payload) {
// just treat the chunk as a single blob of data and copy it as-is; we only
// have to trim the padding at the end (if any) to avoid overwriting other
// data in SPU RAM.
- uint32_t length = CHUNK_SIZE - str_ctx.spu_pos;
+ size_t length = CHUNK_SIZE - str_ctx.spu_pos;
if (length > 2048)
length = 2048;
@@ -288,15 +278,9 @@ void cd_event_handler(int32_t event, uint8_t *payload) {
/* Stream helpers */
void init_spu_channels(void) {
- // Upload the dummy block to the SPU and play it on all channels, locking
- // them up and stopping them from messing with the SPU interrupt.
- // TODO: is this really necessary? (needs testing on real hardware)
- SpuSetTransferStartAddr(DUMMY_BLOCK_ADDR);
- SpuWrite(SPU_DUMMY_BLOCK, 64);
-
SPU_KEY_OFF = 0x00ffffff;
- for (uint32_t i = 0; i < 24; i++)
+ for (int i = 0; i < 24; i++)
SPU_CH_ADDR(i) = SPU_RAM_ADDR(DUMMY_BLOCK_ADDR);
SPU_KEY_ON = 0x00ffffff;
@@ -330,7 +314,7 @@ void init_stream(CdlFILE *file) {
void start_stream(void) {
SPU_KEY_OFF = CHANNEL_MASK;
- for (uint32_t i = 0; i < NUM_CHANNELS; i++) {
+ for (int i = 0; i < NUM_CHANNELS; i++) {
SPU_CH_ADDR(i) = SPU_RAM_ADDR(BUFFER_START_ADDR + BUFFER_SIZE * i);
SPU_CH_FREQ(i) = SAMPLE_RATE;
SPU_CH_ADSR(i) = 0x1fee80ff; // or 0x9fc080ff, 0xdff18087
@@ -429,7 +413,7 @@ int main(int argc, const char* argv[]) {
// Only set the sample rate registers if necessary.
if (pad->btn != 0xffff) {
- for (uint32_t i = 0; i < NUM_CHANNELS; i++)
+ for (int i = 0; i < NUM_CHANNELS; i++)
SPU_CH_FREQ(i) = sample_rate;
}
diff --git a/examples/sound/vagsample/main.c b/examples/sound/vagsample/main.c
index 1ec3b8a..c79e68e 100644
--- a/examples/sound/vagsample/main.c
+++ b/examples/sound/vagsample/main.c
@@ -32,7 +32,7 @@
*/
#include <stdio.h>
-#include <sys/types.h>
+#include <stdint.h>
#include <psxetc.h>
#include <psxgte.h>
#include <psxgpu.h>
@@ -104,8 +104,8 @@ void init(void)
SpuSetTransferStartAddr(addr_temp);
// Upload first sound clip and wait for transfer to finish
- SpuWrite(((unsigned char*)proyt)+48, proyt_size-48);
- SpuWait();
+ SpuWrite((const uint32_t *) &proyt[48], proyt_size-48);
+ SpuIsTransferCompleted(SPU_TRANSFER_WAIT);
// Obtain the address of the sound and advance address for the next one
// Samples are addressed in 8-byte units, so it'll have to be divided by 8
@@ -116,8 +116,8 @@ void init(void)
// Upload second sound clip
SpuSetTransferStartAddr(addr_temp);
- SpuWrite(((unsigned char*)tdfx)+48, tdfx_size-48);
- SpuWait();
+ SpuWrite((const uint32_t *) &tdfx[48], tdfx_size-48);
+ SpuIsTransferCompleted(SPU_TRANSFER_WAIT);
// Obtain the address of the second sound clip
tdfx_addr = addr_temp/8;