//------------------------------------------------------------------------------------------------------------------------
// 
// Title: SD Card Wav Player
//
// Description:
//    Simple example to demonstrate the fundementals of playing WAV files (digitised sound) from an SD Card via the I2S 
//    interface of the ESP32. Plays WAV file from SD card. To keep this simple the WAV must be stereo and 16bit samples. 
//    The Samples Per second can be anything. On the SD Card the wav file must be in root and called wavfile.wav
//    Libraries are available to play WAV's on ESP32, this code does not use these so that we can see what is happening.
//    This is part 3 in a tutorial series on using I2S on ESP32. See the accompanying web page (which will also include
//    a tutorial video).
//
// Boring copyright/usage information:
//    (c) XTronical, www.xtronical.com
//    Use as you wish for personal or monatary gain, or to rule the world (if that sort of thing spins your bottle)
//    However you use it, no warrenty is provided etc. etc. It is not listed as fit for any purpose you perceive
//    It may damage your house, steal your lover, drink your beers and more.
//
//    http://www.xtronical.com/i2s-ep3
//
//------------------------------------------------------------------------------------------------------------------------

#ifndef __SDPLAY_H
#define __SDPLAY_H

#include <Arduino.h>
#include "SD.h"                         // SD Card library, usually part of the standard install
#include "driver/i2s.h"                 // Library of I2S routines, comes with ESP32 standard install
#include "set_settings.h"

class SDplay
{
 public:

    File WavFile;

    static byte Samples[];            // Array for frame data from WAV
    static uint32_t BytesReadSoFar;   // Number of bytes read from file so far
    static uint16_t BufferIdx;        // Current pos of buffer to output next

    struct WavHeader_Struct
      {
          //   RIFF Section    
          char RIFFSectionID[4];      // Letters "RIFF"
          uint32_t Size;              // Size of entire file less 8
          char RiffFormat[4];         // Letters "WAVE"
          
          //   Format Section    
          char FormatSectionID[4];    // letters "fmt"
          uint32_t FormatSize;        // Size of format section less 8
          uint16_t FormatID;          // 1=uncompressed PCM
          uint16_t NumChannels;       // 1=mono,2=stereo
          uint32_t SampleRate;        // 44100, 16000, 8000 etc.
          uint32_t ByteRate;          // =SampleRate * Channels * (BitsPerSample/8)
          uint16_t BlockAlign;        // =Channels * (BitsPerSample/8)
          uint16_t BitsPerSample;     // 8,16,24 or 32
        
          // Data Section
          char DataSectionID[4];      // The letters "data"
          uint32_t DataSize;          // Size of the data that follows
      }WavHeader;

 private:
    
    size_t BytesWritten;         // Returned by the I2S write routine, 
    uint16_t BytesToRead;        // Number of bytes to read from the file
    uint8_t* DataPtr;            // Point to next data to send to I2S
    uint16_t BytesToSend;        // Number of bytes to send to I2S
    bool done = false;

 public:
    void ReadFile(byte* Samples);  // Read WAV file from SD
    void FillI2SBuffer(byte* Samples); // Write SD Buffer to DMA tx buffer
    void SDCardInit();
    void OpenWaveFile();
    bool ValidWavData(WavHeader_Struct* Wav); // Check WAV Header for valid types
    void PrintWAVHeader(WavHeader_Struct* Wav); // Print WAV Header to Monitor
    void PrintData(const char* Data,uint8_t NumBytes); // Print char bytes to Monitor

};

#endif