Hey guys,
I just want to know if you run this ISO if the sound eventually annihilates your sanity (with static, of course).
It would only ever do this on
real hardware. You can test emulators if you want, but about all you will get are some skips and the end of the file not terminating the sound.
http://www.mediafire.com/file/gvvevvruvr4cwnb/sl_coff.iso----------------------------------------------------------------------------------------------------------------------------------------------
"But!" you may ask, "what is this?!"
This is streamed PCM playback of 30720 Hz (30.72KHz) audio using SGL, with the sound effect itself being copied straight to the PCM playback buffer.
Is this useful? Hell man, I don't know! But this actually plays sound, so it's what I have to work with because I cannot for the life of me get SBL to play any sound
at all."What is the problem?"
I'm not sure. It could be a limitation of SGL. It could be a hardware limitation that SBL circumvents. It could just be my Saturn. But after so long of playing back the file, static gets thrown into the mix and I do not know how to suppress it.
Theories:
- SGL PCM playback pointer moves to a region of memory that has bad data
- SGL PCM playback pointer eventually starts playing back the incomplete data in LWRAM as its being copied
- SGL PCM playback pointer eventually leaves the Saturn's entire possible memory map range, returning NULL data
- A-bus and B-bus DMA processes eventually cross-corrupt
- SGL PCM playback library eventually attempts to mux PCM sound outputs, resulting in garbage added
Things I have tried:
- Attempt to move SGL playback start pointer (You cannot, slPCMOn will not change its parameters once started)
- Using NULL for PCM data region (I don't want it to point to any region, since I am copying the PCM data directly to the PCM buffer) (Result: Garbage)
- Using end-of-memory for PCM data region (Result: Crash)
- Different DMA modes
- Not much else (only one song and bitrate on real hardware)
MAJOR ISSUE:
No emulators replicate this problem.
Relevant code:
#ifndef __AUDIO_H__
#define __AUDIO_H__
#define SECTOR_SIZE (2048)
#define RING_BUF_SIZE (2048*10)
#define PCM_ADDR ((void*)0x25a20000)
#define PCM_SIZE (4096*2)
#define SMP_1TASK_SAMPLE (1024)
#define SMP_TR_MODE_CD (PCM_TRMODE_CPU)
#define SMP_LOAD_NUM (10)
#define PCMRAM (631734272)
#define LWRAM (2097152)
#define HIMEM (100679680)
//(31122)
#define S4410KHZ (0)
#define S3780KHZ (31451)
//THIS IS TESTED
#define M3072KHZ (31118)
//
#define S2205KHZ (30720)
#define S1920KHZ (29431)
#define S18900HZ (29404)
#define S1600KHZ (29134)
#define S1536KHZ (29074)
#define S1100KHZ (27643)
#define S0800KHZ (27086)
extern jo_sound main_pcmfx;
extern jo_sound music_pcmfx;
//Functions go here
void pcm_music_play(void(*sysframe)(void));
void* load_pcm(Sint8* filename, const jo_sound_mode mode, jo_sound *sound, void * workAddress);
void sound_on_channel(jo_sound * const sound, const unsigned char channel);
#endif
//Modified Jo Engine functions
jo_sound music_pcmfx;
jo_sound main_pcmfx;
static PCM _pcm[JO_SOUND_MAX_CHANNEL] =
{
{(_Stereo | _PCM16Bit), 0, 127, 0, 0x0, 0, 0, 0, 0},
{(_Stereo | _PCM16Bit), 2, 127, 0, 0x0, 0, 0, 0, 0},
{(_Stereo | _PCM16Bit), 4, 127, 0, 0x0, 0, 0, 0, 0},
{(_Stereo | _PCM16Bit), 6, 127, 0, 0x0, 0, 0, 0, 0},
{(_Stereo | _PCM16Bit), 8, 127, 0, 0x0, 0, 0, 0, 0},
{(_Stereo | _PCM16Bit), 10, 127, 0, 0x0, 0, 0, 0, 0},
};
static Sint16 music_frames = 0;
static Sint16 music_sectors = 0;
void pcm_music_play(void(*sysframe)(void))
{
//DEBUG INFORMATION
Sint8* filename = "B.PCM";
music_pcmfx.mode = JoSoundMono16Bit;
//This function is supposed to play a mono PCM sound effect constantly.
//Some LWRAM is consumed in the process (10 sectors / 20KB).
void* pcm = LWRAM;
void* write_buffer = LWRAM;
Sint32 fid = GFS_NameToId(filename);
GfsHn gfsm = GFS_Open(fid);
Sint8 fetch_timer = 0;
Sint32 fsize;
Sint32 nsct;
Sint32 stat;
Sint32 rdsize;
//Rate of data reading
Sint16 rt_step = (2 * 2048);
Sint16 rt_sector = 2;
//Get sectors
//HEY! SBL DOCUMENTATION IS WRONG! THIRD ITEM nzect IS GFS SECTOR COUNT. SECOND ITEM IS CD SECTOR SIZE.
//TIP: MEMORY MUST BE MANAGED IN SECTORS (2KB)
GFS_GetFileSize(gfsm, NULL, &nsct, NULL);
GFS_GetFileInfo(gfsm, NULL, NULL, &fsize, NULL);
//This determines playback time?
music_pcmfx.data_length = (fsize);
_pcm[(int)0].mode = (Uint8)music_pcmfx.mode;
_pcm[(int)0].pitch = M3072KHZ;
//How many frames are we reading?
if(rt_step < fsize){
music_sectors = (fsize + (rt_step - 1))/(rt_step);
}
jo_printf(0, 18, "(%i)", fsize);
GFS_SetReadPara(gfsm, rt_step);
GFS_SetTransPara(gfsm, rt_sector);
GFS_SetTmode(gfsm, GFS_TMODE_CPU);
//Loading follows
GFS_NwCdRead(gfsm, (10 * 2048));
for( ; music_frames <= music_sectors ; ){
//Copy memory from work area buffer directly into the PCM stream buffer
slDMACopy(write_buffer, PCMRAM, (8 * 2048));
slDMAWait();
//Very tightly timed! Not even timed right! Saturn appears to playback sounds faster than advertised; check pitch?
fetch_timer++;
if(music_frames < 4){
GFS_NwFread(gfsm, rt_sector, write_buffer + (music_frames * rt_step), rt_step);
}
do{
sysframe();
slSynch();
if(music_frames < 4){
GFS_NwExecOne(gfsm);
GFS_NwGetStat(gfsm, &stat, &rdsize);
}
jo_printf(0, 7, "(%i)", music_frames);
jo_printf(7, 7, "(%i)", music_sectors);
jo_printf(0, 11, "(%i)", rdsize);
jo_printf(10, 11, "(fetched filesize)");
}while(stat != GFS_SVR_COMPLETED && rdsize < rt_step);
if(music_frames < 4){
music_frames++;
}
if(music_frames == 4 && fetch_timer == 8){
music_frames = 0; fetch_timer = 0;
}
slSndFlush();
music_pcmfx.data = pcm;
jo_printf(0, 0, "(%i)", pcm);
music_pcmfx.current_playing_channel = 0;
//HEY! slPCMOn does -NOT- accept changes to the data address during playback. IT WILL DO NOTHING.
slPCMOn(&_pcm[(int)0], music_pcmfx.data, music_pcmfx.data_length);
slPCMParmChange(&_pcm[(int)0]);
}
GFS_Close(gfsm);
}