pschatzmann / arduino-audio-tools

Arduino Audio Tools (a powerful Audio library not only for Arduino)
GNU General Public License v3.0
1.49k stars 232 forks source link

Can't play audio files in SD Card using Raspberry Pi Pico #661

Closed djairjr closed 1 year ago

djairjr commented 1 year ago

"I'm having trouble playing audio files on the SD Card using Raspberry Pi Pico and the example files. It seems that there is some incompatibility between the SD.h and FS.h libraries with the Raspberry Pi Pico, which uses SDFS.h. I'm trying to compile the code below using earlephilhower's core, but I'm getting errors."

` In file included from D:\Users\mywindowsuser\AppData\Local\Temp\arduino_modified_sketch_592486\player-sd-i2s.ino:10: D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h:106:16: error: 'SDFS' is not a member of 'fs'; did you mean 'FS'? 106 | SDDirect<fs::SDFS,fs::File> idx{SD}; | ^~~~ | FS D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h:106:29: error: template argument 1 is invalid 106 | SDDirect<fs::SDFS,fs::File> idx{SD}; | ^ D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h:106:35: error: 'SD' was not declared in this scope; did you mean 'SDA'? 106 | SDDirect<fs::SDFS,fs::File> idx{SD}; | ^~ | SDA D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h:106:37: error: cannot convert '' to 'int' in initialization 106 | SDDirect<fs::SDFS,fs::File> idx{SD}; | ^ In file included from D:\Users\mywindowsuser\AppData\Local\Temp\arduino_modified_sketch_592486\player-sd-i2s.ino:10: D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h: In member function 'virtual void audio_tools::AudioSourceSD::begin()': D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h:48:15: error: 'SD' was not declared in this scope; did you mean 'SDA'? 48 | while (!SD.begin(cs)) { | ^~ | SDA D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h:54:9: error: request for member 'begin' in '((audio_tools::AudioSourceSD)this)->audio_tools::AudioSourceSD::idx', which is of non-class type 'int' 54 | idx.begin(start_path, exension, file_name_pattern); | ^~~~~ D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h: In member function 'void audio_tools::AudioSourceSD::end()': D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h:59:5: error: 'SD' was not declared in this scope; did you mean 'SDA'? 59 | SD.end(); | ^~ | SDA D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h: In member function 'virtual arduino::Stream audio_tools::AudioSourceSD::selectStream(int)': D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h:71:20: error: invalid types 'int[int]' for array subscript 71 | file_name = idx[index]; | ^ D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h:74:12: error: 'SD' was not declared in this scope; did you mean 'SDA'? 74 | file = SD.open(file_name); | ^~ | SDA D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h: In member function 'virtual arduino::Stream audio_tools::AudioSourceSD::selectStream(const char)': D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h:80:12: error: 'SD' was not declared in this scope; did you mean 'SDA'? 80 | file = SD.open(path); | ^~ | SDA In file included from D:\Users\mywindowsuser\AppData\Local\Temp\arduino_modified_sketch_592486\player-sd-i2s.ino:10: D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h: In member function 'long int audio_tools::AudioSourceSD::size()': D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSD.h:103:28: error: request for member 'size' in '((audio_tools::AudioSourceSD*)this)->audio_tools::AudioSourceSD::idx', which is of non-class type 'int' 103 | long size() { return idx.size();} | ^~~~ Foram encontradas múltiplas bibliotecas para "WiFi.h" Usado: D:\Users\mywindowsuser\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\3.0.0\libraries\WiFi Não usado: C:\Program Files (x86)\Arduino\libraries\WiFi exit status 1 Erro compilando para a placa Raspberry Pi Pico W

`

Simply replacing the lines that include the SD.h and FS.h libraries in audiosourcesd.h with the inclusion of the SDFS.h library does not result in any improvement.

pschatzmann commented 1 year ago

Feel free to correct this issue. I think it will work if you use the greimans sdfat library instead...

djairjr commented 1 year ago

I will try it and post it here, if it works. I've tested this simple player with the ESP8266 Audio from earlephilhower, and it works.

#include "AudioFileSourceSD.h"
#include "AudioGeneratorMP3.h"
#include "AudioGeneratorFLAC.h"
#include "AudioGeneratorWAV.h"
#include "AudioOutputI2S.h"

#define SPI_SPEED SD_SCK_MHZ(40)

const int _MISO = 4;
const int _MOSI = 7;
const int _CS = 5;
const int _SCK = 6;

File dir;
AudioFileSourceSD *source = NULL;
AudioGeneratorFLAC *decoder;
AudioOutputI2S *output;

void setup()
{
  Serial.begin(115200);
  delay(1000);
  SPI.setRX(_MISO);
  SPI.setTX(_MOSI);
  SPI.setSCK(_SCK);
  SPI.setCS(_CS);

  Serial.printf("Audio Player Iniciado");

  audioLogger = &Serial;
  source = new AudioFileSourceSD();
  output = new AudioOutputI2S();
  output->SetPinout(26,27,28); // BCk, WS, DATA
  decoder = new AudioGeneratorFLAC();
  SD.begin(_CS, SPI_SPEED); // Aumenta a velocidade para o SD
  dir = SD.open("/"); // Pasta onde gravei os audios
}
void loop() {
  if ((decoder) && (decoder->isRunning())) {
    if (!decoder->loop()) decoder->stop();
  } else {
    File file = dir.openNextFile();
    if (file) {      
      if (String(file.name()).endsWith(".flac")) {
        source->close();
        if (source->open(file.name())) { 
          Serial.printf_P(PSTR("Playing '%s' from SD card...\n"), file.name());
          decoder->begin(source, output);
          output->SetGain(0.3); // Volume?
        } else {
          Serial.printf_P(PSTR("Error opening '%s'\n"), file.name());
        }
      } 
    } else {
      Serial.println(F("Playback from SD card done\n"));
      delay(1000);
    }       
  }
}
djairjr commented 1 year ago

I've made some changes in the original code:

/**
 * @file player-littlefs-i2s.ino
 * @brief example using the SD library
 * 
 * @author Phil Schatzmann
 * @copyright GPLv3
 */
#include "FreeStack.h"
#include "AudioTools.h"
#include "AudioLibs/AudioSourceSDFAT.h" // Here was SD. Does not work...
#include "AudioCodecs/CodecMP3Helix.h"

#define SD_CS_PIN 5
// #define SPI_SPEED SD_SCK_MHZ(40)
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK)

const int _MISO = 4;
const int _MOSI = 7;
const int _CS = 5;
const int _SCK = 6;

const char *startFilePath="/";
const char* ext="mp3";
AudioSourceSDFAT source(startFilePath, ext); // Here was SD. Does not work...
I2SStream i2s;
MP3DecoderHelix decoder;
AudioPlayer player(source, i2s, decoder);

void printMetaData(MetaDataType type, const char* str, int len){
  Serial.print("==> ");
  Serial.print(toStr(type));
  Serial.print(": ");
  Serial.println(str);
}

void setup() {
  Serial.begin(115200);
  AudioLogger::instance().begin(Serial, AudioLogger::Info);
  delay(1000);
  SPI.setRX(_MISO);
  SPI.setTX(_MOSI);
  SPI.setSCK(_SCK);
  SPI.setCS(_CS);
  // setup output
  auto cfg = i2s.defaultConfig(TX_MODE);
  cfg.pin_bck= 26;
  cfg.pin_ws= 27;
  cfg.pin_data = 28;
  i2s.begin(cfg);

  // setup player
  //source.setFileFilter("*Bob Dylan*");
  player.setMetadataCallback(printMetaData);
  player.begin();
}

void loop() {
  player.copy();
}

and now, the message is that:

In file included from D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:12,
                 from D:\Users\mywindowsuser\AppData\Local\Temp\arduino_modified_sketch_235208\player-sd-i2s.ino:10:
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/SDDirect.h: In member function 'const char* audio_tools::SDDirect<SDT, FileT>::fileNamePath(FileT&)':
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/SDDirect.h:212:21: error: 'class arduino::String' has no member named 'clear'
  212 |       file_path_str.clear();
      |                     ^~~~~
In file included from D:\Users\mywindowsuser\AppData\Local\Temp\arduino_modified_sketch_235208\player-sd-i2s.ino:10:
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h: At global scope:
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:25:13: error: 'sdfat' does not name a type
   25 |     typedef sdfat::SdSpiConfig SdSpiConfig;
      |             ^~~~~
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:26:13: error: 'sdfat' does not name a type
   26 |     typedef sdfat::SdFs AudioFs;
      |             ^~~~~
In file included from D:\Users\mywindowsuser\AppData\Local\Temp\arduino_modified_sketch_235208\player-sd-i2s.ino:10:
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:152:3: error: 'AudioFs' does not name a type
  152 |   AudioFs sd;
      |   ^~~~~~~
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:153:3: error: 'AudioFile' does not name a type; did you mean 'AudioTime'?
  153 |   AudioFile file;
      |   ^~~~~~~~~
      |   AudioTime
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:154:12: error: 'AudioFs' was not declared in this scope
  154 |   SDDirect<AudioFs,AudioFile> idx{sd};
      |            ^~~~~~~
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:154:20: error: 'AudioFile' was not declared in this scope; did you mean 'AudioTime'?
  154 |   SDDirect<AudioFs,AudioFile> idx{sd};
      |                    ^~~~~~~~~
      |                    AudioTime
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:154:29: error: template argument 1 is invalid
  154 |   SDDirect<AudioFs,AudioFile> idx{sd};
      |                             ^
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:154:29: error: template argument 2 is invalid
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:165:15: error: expected ';' at end of member declaration
  165 |   const char* getFileName(AudioFile&file){
      |               ^~~~~~~~~~~
      |                          ;
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:165:36: error: expected ')' before '&' token
  165 |   const char* getFileName(AudioFile&file){
      |                          ~         ^
      |                                    )
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:154:35: error: 'sd' was not declared in this scope; did you mean 'std'?
  154 |   SDDirect<AudioFs,AudioFile> idx{sd};
      |                                   ^~
      |                                   std
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:154:37: error: cannot convert '<brace-enclosed initializer list>' to 'int' in initialization
  154 |   SDDirect<AudioFs,AudioFile> idx{sd};
      |                                     ^
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h: In member function 'virtual void audio_tools::AudioSourceSDFAT::begin()':
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:84:14: error: 'sd' was not declared in this scope; did you mean 'std'?
   84 |         if (!sd.begin(*p_cfg)) {
      |              ^~
      |              std
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:90:9: error: request for member 'begin' in '((audio_tools::AudioSourceSDFAT*)this)->audio_tools::AudioSourceSDFAT::idx', which is of non-class type 'int'
   90 |     idx.begin(start_path, exension, file_name_pattern);
      |         ^~~~~
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h: In member function 'void audio_tools::AudioSourceSDFAT::end()':
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:95:5: error: 'sd' was not declared in this scope; did you mean 'std'?
   95 |     sd.end();
      |     ^~
      |     std
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h: In member function 'virtual arduino::Stream* audio_tools::AudioSourceSDFAT::selectStream(int)':
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:110:28: error: invalid types 'int[size_t {aka unsigned int}]' for array subscript
  110 |     return selectStream(idx[idx_pos]);
      |                            ^
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h: In member function 'virtual arduino::Stream* audio_tools::AudioSourceSDFAT::selectStream(const char*)':
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:114:5: error: 'file' was not declared in this scope
  114 |     file.close();
      |     ^~~~
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:120:5: error: 'AudioFile' was not declared in this scope; did you mean 'AudioTime'?
  120 |     AudioFile new_file;
      |     ^~~~~~~~~
      |     AudioTime
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:121:10: error: 'new_file' was not declared in this scope
  121 |     if (!new_file.open(path, O_RDONLY)){
      |          ^~~~~~~~
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:127:12: error: 'new_file' was not declared in this scope
  127 |     file = new_file;
      |            ^~~~~~~~
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h: In member function 'long int audio_tools::AudioSourceSDFAT::size()':
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:148:28: error: request for member 'size' in '((audio_tools::AudioSourceSDFAT*)this)->audio_tools::AudioSourceSDFAT::idx', which is of non-class type 'int'
  148 |   long size() { return idx.size();}
      |                            ^~~~
Foram encontradas múltiplas bibliotecas para "WiFi.h"
Usado: D:\Users\mywindowsuser\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\3.0.0\libraries\WiFi
Não usado: C:\Program Files (x86)\Arduino\libraries\WiFi
Foram encontradas múltiplas bibliotecas para "FreeStack.h"
Usado: D:\Users\mywindowsuser\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\3.0.0\libraries\ESP8266SdFat
Não usado: D:\Users\mywindowsuser\Arduino\libraries\SdFat
exit status 1
Erro compilando para a placa Raspberry Pi Pico W
djairjr commented 1 year ago

This is strange: file_path_str.clear(); I will replace it for file_path_str="";

The SDDirect.h is not compiling. So, all the other errors maybe related to it.

djairjr commented 1 year ago

I've changed this block in AudioSourceSDFAT.h (maybe Earle change something?):

#if defined(ARDUINO_ARCH_RP2040) && !defined(PICO)
    // only RP2040 from Earle Phil Hower is using the library with a sdfat namespace
    typedef sdfat::SdSpiConfig SdSpiConfig;
    typedef sdfat::SdFs AudioFs;
#else
#if SD_FAT_TYPE == 0
    typedef SdFat AudioFs;
    typedef File AudioFile;
#elif SD_FAT_TYPE == 1
    typedef SdFat32 AudioFs;
    typedef File32 AudioFile;
#elif SD_FAT_TYPE == 2
    typedef SdExFat AudioFs;
    typedef ExFile AudioFile;
#elif SD_FAT_TYPE == 3
    typedef SdFs AudioFs;
    typedef FsFile AudioFile;
#else  // SD_FAT_TYPE
#endif
#endif

and now this is the error message:

In file included from D:\Users\mywindowsuser\AppData\Local\Temp\arduino_modified_sketch_562057\player-sd-i2s.ino:10:
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h: In member function 'void audio_tools::AudioSourceSDFAT::end()':
D:\Users\mywindowsuser\Arduino\libraries\arduino-audio-tools-main\src/AudioLibs/AudioSourceSDFAT.h:91:8: error: 'AudioFs' {aka 'class SdFat32'} has no member named 'end'
   91 |     sd.end();
      |        ^~~
Foram encontradas múltiplas bibliotecas para "WiFi.h"
Usado: D:\Users\mywindowsuser\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\3.0.0\libraries\WiFi
Não usado: C:\Program Files (x86)\Arduino\libraries\WiFi
Foram encontradas múltiplas bibliotecas para "FreeStack.h"
Usado: D:\Users\mywindowsuser\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\3.0.0\libraries\ESP8266SdFat
Não usado: D:\Users\mywindowsuser\Arduino\libraries\SdFat
exit status 1
Erro compilando para a placa Raspberry Pi Pico W
djairjr commented 1 year ago

It is just trial and error compiling, ok? I am just reading the error messages and commenting the blocks that I think that could be incompatible. But I am not an expert.

Thank you anyway.

djairjr commented 1 year ago
/*#if defined(ARDUINO_ARCH_RP2040) && !defined(PICO)
    // only RP2040 from Earle Phil Hower is using the library with a sdfat namespace
    typedef sdfat::SdSpiConfig SdSpiConfig;
    typedef sdfat::SdFs AudioFs;
#else*/
#if SD_FAT_TYPE == 0
    typedef SdFat AudioFs;
    typedef File AudioFile;
#elif SD_FAT_TYPE == 1
    typedef SdFat32 AudioFs;
    typedef File32 AudioFile;
#elif SD_FAT_TYPE == 2
    typedef SdExFat AudioFs;
    typedef ExFile AudioFile;
#elif SD_FAT_TYPE == 3
    typedef SdFs AudioFs;
    typedef FsFile AudioFile;
#else  // SD_FAT_TYPE
#endif
/*#endif*/
pschatzmann commented 1 year ago

After committing some corrections I tested the compilation of the Player SDFAT example for the following

djairjr commented 1 year ago

Thanks Phil. This library is an amazing job!