gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Can you stream a looping wav from efs?

#170874 - iainprice - Sat Oct 24, 2009 5:10 pm

Can you stream a looping wav from efs?

#170875 - headspin - Sat Oct 24, 2009 8:08 pm

Yes you can
_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game

#170893 - iainprice - Sun Oct 25, 2009 11:25 am

:) good.... any help with loading the file from efs so that it can be streamed?

Thanks.

#170895 - headspin - Sun Oct 25, 2009 1:57 pm

Here are the file io functions I wrote for streaming a file into a buffer. I also used a timer for calculating the position but I must warn you that without compensation for sync issues you may encounter clicking sounds.

You can view my actual streaming code (in asm) here. It may have changed a bit but it still was never fixed to compensate for sync issues often caused by cards with lots of files and fragmentation.'

With EFS you must use stat instead of fstat for getting file size because fstat will return the size of the whole file instead of the size of the embedded file. Without knowing that it can cause havok when writing data as you can imagine.

Code:
#include <nds.h>
#include <stdio.h>
#include <malloc.h>
#include <fat.h>
#include <unistd.h>


#include "efs_lib.h"    // include EFS lib

char *pFileBuffer = NULL;
FILE *pFileStream = NULL;

int initFileStream(char *fileName)
{
   struct stat fileStat;
   
   if(pFileStream != NULL)
      fclose(pFileStream);
   
   pFileStream = fopen(fileName, "rb");
   
   if(pFileStream == NULL)
      return 0;

   if(stat(fileName, &fileStat) != 0)
      return 0;

   return fileStat.st_size;
}

int readFileStream(char *pBuffer, int size)
{
   int result;
   
   if(pFileStream == NULL)
      return 0;
   
   result = fread(pBuffer, 1, size, pFileStream);
   
   return result;
}

int resetFileStream()
{
   size_t result;
   
   if(pFileStream == NULL)
      return 0;
   
   result = fseek(pFileStream, 0, SEEK_SET);
   
   if(result != 0)
      return 0;
   
   return 1;
}

int closeFileStream()
{
   if(pFileStream != NULL)
   {
      fclose(pFileStream);
      
      return 1;
   }
   
   return 0;
}

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

#170918 - iainprice - Mon Oct 26, 2009 1:59 pm

Thanks, would it be possible (or a good idea) to have two buffers, fill one while playing another, then swap, so that there is no delay when filling the buffer?

#170957 - headspin - Tue Oct 27, 2009 6:01 pm

iainprice wrote:
Thanks, would it be possible (or a good idea) to have two buffers, fill one while playing another, then swap, so that there is no delay when filling the buffer?


The code I linked to uses a buffer split into two and swaps between them. Without doing that there were audio artifacts.

Unfortunately on some cards we have found sync issues would creep in when changing songs. So we are looking at changing to use a library that hopefully deals with these problems.
_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game