#167526 - headspin - Tue Mar 17, 2009 1:58 pm
I'm trying to stream some music for a game using the EFS to break the 4 MB memory limit of the DS. So far I have got the basic streaming working but every time the buffer is refilled there is an annoying click sound. Is there are bug in the code or perhaps streaming from the ROM is not fast enough in the timer? Any suggestions would be appreciated.
Code from main.s
Here is the audioStream.s
and the readFile.c routines for reading from the EFS
_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game
Last edited by headspin on Fri Mar 20, 2009 4:03 pm; edited 10 times in total
Code from main.s
Code: |
ldr r0, =strInGame @ Read the path to the file
bl playAudio @ Play the sound mainLoop: bl swiWaitForVBlank b mainLoop strInGame: .asciz "/InGame.raw" |
Here is the audioStream.s
Code: |
#define BUFFER_SIZE 4096
#define AUDIO_FREQ 22050 .arm .align .text .global initAudioStream .global playAudio .global audioStreamTimer1 initAudioStream: stmfd sp!, {r0-r1, lr} ldr r0, =TIMER0_DATA ldr r1, =SOUND_FREQ(AUDIO_FREQ) * 2 strh r1, [r0] ldr r0, =TIMER0_CR ldr r1, =(TIMER_ENABLE | TIMER_DIV_1) strh r1, [r0] ldr r0, =TIMER1_DATA ldr r1, =(0x10000 - (BUFFER_SIZE / 2)); strh r1, [r0] ldr r0, =TIMER1_CR ldr r1, =(TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE) strh r1, [r0] ldmfd sp!, {r0-r1, pc} @ Return @ --------------------------------------------- playAudio: stmfd sp!, {r0-r2, lr} @ r0 = string pointer to music mov r1, r0 @ Move string pointer ldr r0, =fileName @ Read address of fileName ldr r2, =256 @ Size == 256 bl memcpy @ Copy filename to fileName ldr r0, =fileName ldr r1, =(BUFFER_SIZE / 2) ldr r2, =fileSize @ Read fileSize address bl readFileSize str r0, [r2] @ Write the filesize to it ldr r0, =fileName ldr r1, =buffer ldr r2, =bufferPos ldr r2, [r2] ldr r3, =(BUFFER_SIZE / 2) @ Read the buffer size bl readFileStream @ Read the next buffer of audio file bl playBuffer ldmfd sp!, {r0-r2, pc} @ restore registers and return @ --------------------------------------------- playBuffer: stmfd sp!, {r0-r1, lr} ldr r0, =IPC_SOUND_LEN(0) @ Get the IPC sound length address ldr r1, =BUFFER_SIZE @ buffer size str r1, [r0] @ Write the buffer size ldr r0, =IPC_SOUND_DATA(0) @ Get the IPC sound data address ldr r1, =buffer @ Get the sample address str r1, [r0] @ Write the value ldmfd sp!, {r0-r1, pc} @ restore registers and return @ --------------------------------------------- audioStreamTimer1: stmfd sp!, {r0-r6, lr} ldr r0, =fileName ldr r1, =buffer ldr r2, =bufferPos ldr r2, [r2] ldr r3, =(BUFFER_SIZE / 2) @ Read the buffer size ldr r4, =backBuffer ldr r5, [r4] cmp r5, #0 moveq r5, #1 addeq r1, r3 movne r5, #0 str r5, [r4] bl readFileStream @ Read the next buffer of audio file bl DC_FlushAll @ Flush the cache ldr r0, =bufferPos @ Read the bufferPos address ldr r1, [r0] @ Read the bufferPos value ldr r2, =fileSize @ Read the file size address ldr r2, [r2] @ Read the fileSize value ldr r3, =(BUFFER_SIZE / 2) @ Read the buffer size add r1, r3 @ Add buffer size to bufferPos str r1, [r0] @ Write value back to bufferPos ldmfd sp!, {r0-r6, pc} @ Return @ --------------------------------------------- .data .align backBuffer: .word 0 bufferPos: .word 0 fileSize: .word 0 .section .bss fileName: .space 256 buffer: .space BUFFER_SIZE .pool .end |
and the readFile.c routines for reading from the EFS
Code: |
FILE *pFileStream = NULL;
int readFileStream(char *fileName, unsigned char *pBuffer, int pos, int size) { size_t result; if(pFileStream == NULL) pFileStream = fopen(fileName, "rb"); if (pFileStream == NULL) return 0; result = fseek(pFileStream, pos, SEEK_SET); if(result != 0) { fclose(pFileStream); return 0; } result = fread(pBuffer, 1, size, pFileStream); if(result != size) { fclose(pFileStream); return 0; } return 1; } int readFileSize(char *fileName) { struct stat fileStat; size_t result; result = stat(fileName, &fileStat); if(result != 0) return 0; return fileStat.st_size; } |
_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game
Last edited by headspin on Fri Mar 20, 2009 4:03 pm; edited 10 times in total