[RESOLVED] Library for Audio Playback from SPI Flash ...

I finally ported Adafruit's WaveHC library (that playbacks raw WAV files from SD Card with Arduino) to a new library "SoundZ".
Main difference is that this one reads files from Serial Flash chip with help of SerialFLash library

Unfortunately I have small issue with part of the code. In WaveHC library there's a portion that checks if data is not a valid "WAVE" data (i.e. header) and skips it when reading.
It uses function seekCur from Fatreader library (that's included in WaveHC library). There's no such function in SerialFlash, so I need help with workaround.

Basically what happens without this part of function is after WAV file finished playing, it makes a burst of noise... I verified it with original WaveHC library (if I comment that section out it happens there too).

This is the function:

int16_t WaveHC::readWaveData(uint8_t *buff, uint16_t len) {
 
  if (remainingBytesInChunk == 0) {
    struct {
      char     id[4];
      uint32_t size;
    } header;
    while (1) {
      if (fd->read(&header, 8) != 8) return -1;
      if (!strncmp(header.id, "data", 4)) {
        remainingBytesInChunk = header.size;
        break;
      }
 
      // if not "data" then skip it!
      if (!fd->seekCur(header.size)) {
        return -1;
      }
    }
  }

Specifically this part:

 // if not "data" then skip it!
      if (!fd->seekCur(header.size)) {
        return -1;
      }

And here's seekCur function from Fatreader.cpp:

uint8_t FatReader::seekCur(uint32_t offset) {

  uint32_t newPos = readPosition_ + offset;
  
  // can't position beyond end of file
  if (newPos > fileSize_) return false;
  
  // number of clusters forward
  uint32_t nc = (newPos >> 9)/vol_->blocksPerCluster()
                 - (readPosition_ >> 9)/vol_->blocksPerCluster();
                 
  // set new position - only corrupt file system can cause error now
  readPosition_ = newPos;
  
  // no clusters if FAT16 root
  if (fileType() == FILE_TYPE_ROOT16) return true;
  
  // don't need to read FAT if contiguous
  if (isContiguous()) {
    readCluster_ += nc;
    return true;
  }
  
  // read FAT chain while nc != 0
  while (nc-- != 0) {
    if (!(readCluster_ = vol_->nextCluster(readCluster_))) {
      return false;
    }
  }
  return true;
}

SerialFlash does have "seek" function (file.seek(number):wink: but it doesn't return any value, and I'm not sure how it works to be honest :frowning: My programming skills are lacking.

So I'd love to get some help :slight_smile:

Were you planning on putting invalid WAVE files in your FLASH?

Assuming the data is contiguous in the FLASH chip, just add header.size to the file pointer. You only need the FAT cluster stuff for files fragmented into non-consecutive clusters.

johnwasser:
Were you planning on putting invalid WAVE files in your FLASH?

Assuming the data is contiguous in the FLASH chip, just add header.size to the file pointer. You only need the FAT cluster stuff for files fragmented into non-consecutive clusters.

Files should be valid WAVE :slight_smile: But I'll double check them in audio editor...
Data is contiguous. I thought this code was unnecessary yet, without it some (not every) files "burp" at the end...

Hmm looks like it's deeper than I thought...
I added print statement inside the code, and it seems it actually never satisfies this condition, because it didn't print anything...

if (!fd->seekCur(header.size)) {
		  putstring_nl("error corrected"); // Debug
        return -1;
      }

So just the action of calling seekCur function somehow prevents wrong portion of file from playback... Now I'm confused even more :frowning:

EDIT: Ok I fixed it. Just needed to add "fd->seek(header.size);"
I think it skips header so it won't play back. No more noise, my library works!!!! :slight_smile:

hi guye
thank you for fabulous liberary
can you add an practical example with their circute ?plz
thank you
i am waiting to your help and itis emregency

johnwasser:
Were you planning on putting invalid WAVE files in your FLASH?

Assuming the data is contiguous in the FLASH chip, just add header.size to the file pointer. You only need the FAT cluster stuff for files fragmented into non-consecutive clusters.

hi dear and lovely friend
i am in emregency condition please help me to play an music about 1MG from flash ic (4 or 8 MG ) with arduino