pschatzmann / ESP32-A2DP

A Simple ESP32 Bluetooth A2DP Library (to implement a Music Receiver or Sender) that supports Arduino, PlatformIO and Espressif IDF
Apache License 2.0
1.63k stars 269 forks source link

Problem to send MP3 sound by ESP32 DEV kit to a Bluetooth Speaker #234

Closed williamesp2015 closed 2 years ago

williamesp2015 commented 2 years ago

I have hard time to test a simple mp3 file to a bluetooth Speaker. Any help would be very appreciated.

pschatzmann commented 2 years ago

I suggest to try to use https://github.com/pschatzmann/arduino-audio-tools: Starting from this example you could try to replace the destination I2SStream with a A2DPStream.

williamesp2015 commented 2 years ago

@pschatzmann . Thank you for suggestion. I couldn't find example to replace Bluetooth Speaker name with I2SStream. It would be very nice if you kindly add an example.

pschatzmann commented 2 years ago

Take a look at https://github.com/pschatzmann/arduino-audio-tools/tree/main/examples/examples-stream/streams-generator-a2dp which shows how to output to A2DP. I cant provide examples for all possible combinations!

williamesp2015 commented 2 years ago

After more search I decided to do streaming MP3 file using SdFat but no sound can hear from the BT Speaker. It might be due to delicate problem in setting SdFat custom SPI configuration:

define USE_SDFAT

include "AudioTools.h"

include "AudioLibs/AudioA2DP.h"

include "AudioCodecs/CodecMP3Helix.h"

const char startFilePath="/"; const char ext="mp3"; int speedMz = 15; AudioSourceSdFat source(startFilePath, ext, SD_CS_PIN, speedMz); A2DPStream out = A2DPStream::instance(); // A2DP input - A2DPStream is a singleton! MP3DecoderHelix decoder; AudioPlayer player(source, out, decoder);

void setup() { Serial.begin(115200); Serial.print(F("Initializing SD card...")); SPI.begin(SDCARD_SCK_PIN,SDCARD_MISO_PIN,SDCARD_MOSI_PIN,SDCARD_SS_PIN);

AudioLogger::instance().begin(Serial, AudioLogger::Warning);

// setup output - We send the test signal via A2DP - so we conect to the "LEXON MINO L" Bluetooth Speaker auto cfg = out.defaultConfig(TX_MODE); cfg.name = "BT SPEAKER"; //cfg.auto_reconnect = true; // if this is use we just quickly connect to the last device ignoring cfg.name out.begin(cfg);

// setup player player.setVolume(0.1); player.begin();

}

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

SERIAL OUTPUT: Initializing SD card...[W] AudioA2DP.h : 302 - ==> state: Connecting [W] AudioA2DP.h : 302 - ==> state: Connected [W] AudioPlayer.h : 236 - -> selectStream: 0 'T1.mp3' [W] AudioA2DP.h : 209 - is_a2dp_active -> true with 59904 bytes [W] AudioPlayer.h : 804 - -> timeout - moving to next stream [W] AudioPlayer.h : 227 - -> nextStream: 1 [W] AudioPlayer.h : 236 - -> selectStream: 1 'T3.mp3' [W] AudioPlayer.h : 804 - -> timeout - moving to next stream

pschatzmann commented 2 years ago

I think your speedMz is much too high. Start with the proposed default value: which is only 2. What made you go for this high value ?

williamesp2015 commented 2 years ago

Hi pschatzmann. Thanks but it was not related to the clock speed because by SDFat I tested on 15 mhz. Finially this woks for custom SPI pinout when SdFatConfig.h modiffied for SPI pinout. Now the problem is with VSPI eventhough sdFat using sd.begin(SD_CONFIG); when SD_CONFIG can configure #define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SPI_CLOCK, &SD_SPI)

define USE_SDFAT

include "AudioTools.h"

include "AudioLibs/AudioA2DP.h"

include "AudioCodecs/CodecMP3Helix.h"

///////////////

//SPIClass SD_SPI(VSPI); //NOT WORKING ON VSPI CUSTOM const uint8_t SD_CS_PIN = 23;//5;//SS; // Try max SPI clock for an SD. Reduce SPI_CLOCK if errors occur.

define SPI_CLOCK SD_SCK_MHZ(2)

const char startFilePath="/"; const char ext="mp3"; int speedMz = 15; // AudioSourceSdFat(const char startFilePath = "/", const char ext = ".mp3", int chipSelect = PIN_CS, int speedMHz = 2) AudioSourceSdFat source(startFilePath, ext, SD_CS_PIN, speedMz); A2DPStream out = A2DPStream::instance(); // A2DP input - A2DPStream is a singleton! MP3DecoderHelix decoder; AudioPlayer player(source, out, decoder);

void setup() { Serial.begin(115200); // SPI.begin(21,19,22,23);//SCK, MISO, MOSI, SS); Serial.print(F("Initializing SD card...")); //Custom SPI Pinout SPI.begin(SDCARD_SCK_PIN,SDCARD_MISO_PIN,SDCARD_MOSI_PIN,SDCARD_SS_PIN);//SCK, MISO, MOSI, SS); // SD_SPI.begin(SDCARD_SCK_PIN,SDCARD_MISO_PIN,SDCARD_MOSI_PIN,SDCARD_SS_PIN);///NOT WORKING ON VSPI CUSTOM delay(10);// a dely AudioLogger::instance().begin(Serial, AudioLogger::Warning); // setup output - We send the test signal via A2DP - so we conect to the "LEXON MINO L" Bluetooth Speaker auto cfg = out.defaultConfig(TX_MODE); cfg.name = "BT SPEAKER"; out.begin(cfg);

// setup player player.setVolume(0.9);//0.1); player.begin();

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

pschatzmann commented 2 years ago

Hmm, I think you created a mess with your CS pins. Either use consistently SDCARD_SS_PIN or SD_CS_PIN because in my understanding this should be the same pin!

williamesp2015 commented 2 years ago

SdFat was not implemented for the Custome SPI port and pinout.

pschatzmann commented 2 years ago

In your case there is no need to use VSPI: Custom pin assignments work perfectly with SPI. This has been used e.g. in https://github.com/pschatzmann/arduino-audiokit

williamesp2015 commented 2 years ago

Yes indeed but I want it for my project using VSPI for SdFat and HSPI for another purpose.

pschatzmann commented 2 years ago

So I would just turn it around and use VSPI for your other purpose or you could create your own AudioSource implementation based on the SD library (or using sdmmc which does not use SPI at all)

pschatzmann commented 2 years ago

Feel free to submit a pull request

williamesp2015 commented 2 years ago

Unfortunately, I have no clue to modify Audioplaye.h.

pschatzmann commented 2 years ago

I don't think any change to the AudioSourceSdFat is needed:

I was testing this setup on an AudioKit both with HSPI and VSPI and it works perfectly.

What was your problem again ?

a442509097 commented 2 years ago

https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-player/player-sd-a2dp/player-sd-a2dp.ino This demo works very well, but the sd compatibility is not very good, I try to change another sd card and it works fine

williamesp2015 commented 2 years ago

https://github.com/pschatzmann/ESP32-A2DP/issues/234#issuecomment-1150346682 Seems

Many thanks. It is agood start to have VSPI/HSPI but after modify AUDIOKIT_BOARD in the AudiokitSetting.h problem is with Audiokit.h AudioKit.h : 189 - begin faild: please verify your AUDIOKIT_BOARD setting: 6 I do not use any Audiokit and My custom design ESP32 board have START/STOP/NEXT/.. keys

williamesp2015 commented 2 years ago

This modified example is working with ESP32 custom define SPI port for SD Card Using SdFat on VSPI and Free HSPI port for other purposes:

define USE_SDFAT

include "AudioTools.h"

include "AudioCodecs/CodecMP3Helix.h"

const char startFilePath="/"; const char ext="mp3"; SPIClass SD_SPI(VSPI); SPIClass HSPI_SPI(HSPI);//FOR OTHER PURPOSE SdSpiConfig sdcfg(SDCARD_SS_PIN, DEDICATED_SPI, SD_SCK_MHZ(15) , &SD_SPI); AudioSourceSdFat source(startFilePath, ext, sdcfg); MP3DecoderHelix decoder; // or change to MP3DecoderMAD

include "AudioLibs/AudioA2DP.h"

A2DPStream out = A2DPStream::instance(); // A2DP input - A2DPStream is a singleton! AudioPlayer player(source, out, decoder);

void next(bool, int, void*) { player.next(); }

void previous(bool, int, void*) { player.previous(); }

void setup() { Serial.begin(115200); //SD Init ///////////////// //Custom SD_SPI Pinout // Make sure you add/changed SD card pinout in the last line of sdFatConfig.h (for ESP32) /* #define SDCARD_MISO_PIN 19

define SDCARD_MOSI_PIN 21

define SDCARD_SCK_PIN 18

define SDCARD_SS_PIN 23 */

SD_SPI.begin(SDCARD_SCK_PIN,SDCARD_MISO_PIN,SDCARD_MOSI_PIN,SDCARD_SS_PIN);//SCK, MISO, MOSI, SS); delay(10);// a dely Serial.print("CS "); Serial.println(SDCARD_SS_PIN); Serial.print("SO "); Serial.println(SDCARD_MISO_PIN); Serial.print("SI "); Serial.println(SDCARD_MOSI_PIN); Serial.print("CLK "); Serial.println(SDCARD_SCK_PIN); AudioLogger::instance().begin(Serial, AudioLogger::Warning); auto cfg = out.defaultConfig(TX_MODE); cfg.name = "BT SPEAKER"; out.begin(cfg);

// setup player player.setVolume(0.9); player.begin();

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