VS1053b WAV playback - no audio

Writing software for systems that use VLSI Solution's devices as slave codecs to a host microcontroller.
Post Reply
thecomfychair
User
Posts: 5
Joined: Fri 2022-08-26 9:14

VS1053b WAV playback - no audio

Post by thecomfychair »

I am testing the VS1053b with a Teensy 4.1, and so far I have successfully played MP3 files and updated to the latest patch.
The Teensy 4.1 has an SD card reader, from which I am streaming files to the VS1053b.

I am now testing WAV files, but I'm having trouble getting any audio out of the VS1053b while playing them. The files seem to play just fine, or at least the VS1053b accepts the data, just no sound comes out of the headphone jack that's on the board I'm using except quiet white noise.

The one exception is a short drum sample which plays perfectly, but I cannot see what the difference between the files are.

Steps I've examined so far:
  1. MP3 files play perfectly through the VS1035b
  2. Volume has not changed
  3. Files play fine on my PC
  4. All files, including the drum sample that does play, are 44.1kHz, so under the 48kHz limit specified on P31 of the datasheet.
  5. All files are 1411kbps, except one which is 4608kbps. This should still be no problem though since the Teensy 4.1 should be fast enough, I'm running my data SPI transmissions at 8MHz (viewtopic.php?p=6311#p6311)

    Code: Select all

    SPISettings(8000000, MSBFIRST, SPI_MODE0)
There's probably something basic I'm missing in my implementation or understanding of the VS1053b's capabilities. Could somebody please point me to what this might be?

For reference:
VS1003B-VS1053-MP3-Module-Development-Board-Onboard-recording-function.jpg_Q90.jpg
VS1003B-VS1053-MP3-Module-Development-Board-Onboard-recording-function.jpg_Q90.jpg (207.9 KiB) Viewed 233 times
User avatar
pasi
VLSI Staff
Posts: 2019
Joined: Thu 2010-07-15 16:04

Re: VS1053b WAV playback - no audio

Post by pasi »

- Do you see SCI_HDAT1 changing to 0x7665 ("ve") to indicate WAV?
- Does SCI_AUDATA reflect the samplerate of the wav file?
- Some extraneous (or missing) bytes do not prevent the mp3 decoder from synchronizing to the next mp3 frame, but will prevent playing of the formats that have headers. So, check your chip select handling if you perform SCI operations between SDI data transfers.

Can you attach an example .wav file or send one to support@vlsi.fi ?

Even if the bitrate is too high for your controller, you should still hear distorted sound. The same applies to higher samplerates.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
thecomfychair
User
Posts: 5
Joined: Fri 2022-08-26 9:14

Re: VS1053b WAV playback - no audio

Post by thecomfychair »

Thank you for your suggestions pasi! Apologies for the delayed reply, things are getting in the way of projects at the moment.

Here are two example files. The first one will play perfectly, the second will not:
track008.wav
This one plays
(369.18 KiB) Downloaded 11 times
Tommy Farrow - Let's Just (Komix Edit) really short.wav
This one doesn't play
(82.32 KiB) Downloaded 11 times
I have tried to read the registers but at the moment reading SCI_HDAT1 just returns 0 regardless of which file I play, even for mp3s. This is likely a user error since I am basing my code on Tobias van Dyk's example project (https://github.com/TobiasVanDyk/VS1053B ... sic-Player) but I'm probably implementing it incorrectly.

Source code and printouts for a few different files below:

Code: Select all

//https://github.com/TobiasVanDyk/VS1053B-Teensy36-Teensy41-SDCard-Music-Player

//////////////////////////////////////////////////////////////////////////
// Modified for Teensy 3.6 Tobias van Dyk October 2020
//
// Also based on PJRC.com Teensy libraries
/////////////////////////////////////////////////////////////////////////
/***************************************************
  This is a library for the Adafruit VS1053 Codec Breakout

  Designed specifically to work with the Adafruit VS1053 Codec Breakout
  ----> https://www.adafruit.com/products/1381

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include <Arduino.h>
#include <SPI.h>
#include <SD.h>

// Connect SCLK, MISO and MOSI to standard hardware SPI pins.
#define SCLK 13       // SPI Clock shared with SD card
//#define MISO 12       // Input data from vs1053 or SD card
//#define MOSI 11       // Output data to vs1053 or SD card

// These are the pins used for the Adafruit vs1053B breakout module
#define XRST  33                // vs1053 reset (output)
#define XCS   36               // vs1053 chip select (output)
#define XDCS  35                // vs1053 Data select (output)
#define XDREQ 34                // vs1053 Data Ready an Interrupt pin (input)
#define SDCS  BUILTIN_SDCARD   // Use Teensy built-in card
// For Teensy 3.5, 3.6, 4.0, 4.1 better to use its built-in SDCard
//#define SDCS 4                // Use vs1053 SDCard Card chip select pin


/////////////////////////////////////////////////////////////////////////////////
// vs1053B.h
/////////////////////////////////////////////////////////////////////////////////

#define vs1053_FILEPLAYER_TIMER0_INT 255 // allows useInterrupt to accept pins 0 to 254
#define vs1053_FILEPLAYER_PIN_INT 5      // Interrupt number from dreqinttable dreq pin # = 3

#define vs1053_SCI_READ 0x03
#define vs1053_SCI_WRITE 0x02

#define vs1053_REG_MODE  0x00
#define vs1053_REG_STATUS 0x01
#define vs1053_REG_BASS 0x02
#define vs1053_REG_CLOCKF 0x03
#define vs1053_REG_DECODETIME 0x04
#define vs1053_REG_AUDATA 0x05
#define vs1053_REG_WRAM 0x06
#define vs1053_REG_WRAMADDR 0x07
#define vs1053_REG_HDAT0 0x08
#define vs1053_REG_HDAT1 0x09
#define vs1053_REG_VOLUME 0x0B

#define vs1053_GPIO_DDR 0xC017
#define vs1053_GPIO_IDATA 0xC018
#define vs1053_GPIO_ODATA 0xC019

#define vs1053_INT_ENABLE  0xC01A

#define vs1053_MODE_SM_DIFF 0x0001
#define vs1053_MODE_SM_LAYER12 0x0002
#define vs1053_MODE_SM_RESET 0x0004
#define vs1053_MODE_SM_CANCEL 0x0008
#define vs1053_MODE_SM_EARSPKLO 0x0010
#define vs1053_MODE_SM_TESTS 0x0020
#define vs1053_MODE_SM_STREAM 0x0040
#define vs1053_MODE_SM_SDINEW 0x0800
#define vs1053_MODE_SM_ADPCM 0x1000
#define vs1053_MODE_SM_LINE1 0x4000
#define vs1053_MODE_SM_CLKRANGE 0x8000

#define vs1053_SCI_AIADDR 0x0A
#define vs1053_SCI_AICTRL0 0x0C
#define vs1053_SCI_AICTRL1 0x0D
#define vs1053_SCI_AICTRL2 0x0E
#define vs1053_SCI_AICTRL3 0x0F

#define vs1053_DATABUFFERLEN 32

File currentTrack;
boolean playingMusic;
uint8_t SoundBuffer[vs1053_DATABUFFERLEN];

////////////////////////////////////////////////////////////////////////////////
// vs1053B.cpp
////////////////////////////////////////////////////////////////////////////////
#define vs1053_CONTROL_SPI_SETTING  SPISettings(250000,  MSBFIRST, SPI_MODE0) // 2.5 MHz SPI speed Control 
//#define vs1053_DATA_SPI_SETTING     SPISettings(8000000, MSBFIRST, SPI_MODE0) // 8 MHz SPI speed Data
#define vs1053_DATA_SPI_SETTING     SPISettings(18000000, MSBFIRST, SPI_MODE0) // 18 MHz SPI speed Data

////////////////////////////////////////////////////////////////
// Configure interrupt for Data XDREQ from vs1053
// XDREQ is low while the receive buffer is full
////////////////////////////////////////////////////////////////
void vs1053Interrupt()
{ SPI.usingInterrupt(XDREQ);                          // Disable Interrupt during SPI transactions
  attachInterrupt(XDREQ, vs1053FeedBuffer, CHANGE);   // Interrupt on Pin XDREQ state change
}                                                    // feeder->feedBuffer executed (lines 26, 209)

//////////////////////////////////////////////////////////
// Set the card to be disabled while we get the vs1053 up
//////////////////////////////////////////////////////////
void vs1053DisableCard ()
{ playingMusic = false;
  pinMode(SDCS, OUTPUT);
  digitalWrite(SDCS, HIGH);
}

/////////////////////////////////////////////////////////////////////////
// Play file without interrupts
/////////////////////////////////////////////////////////////////////////
boolean vs1053PlayFullFile(const char *trackname) {
  Serial.print("Playing ");
  Serial.println(trackname);
  if (! vs1053StartPlayingFile(trackname)) return false;
  while (playingMusic) {
    vs1053FeedBuffer();
  }
  return true;
}

/////////////////////////
void vs1053StopPlaying()
{ playingMusic = false;
  currentTrack.close();
}

///////////////////////////////////////
void vs1053PausePlaying(boolean pause)
{ if (pause) playingMusic = false; else {
    playingMusic = true;
    vs1053FeedBuffer();
  }
}

///////////////////////
boolean vs1053Paused()
{ return (!playingMusic && currentTrack);
}

////////////////////////
boolean vs1053Stopped()
{ return (!playingMusic && !currentTrack);
}

//////////////////////////////////////////////////////
boolean vs1053StartPlayingFile(const char *trackname)  {
  Serial.println("vs1053StartPlayingFile");
  currentTrack = SD.open(trackname);
  if (!currentTrack) {
    Serial.print("Failed to open from SD: ");
    Serial.println(trackname);
    return false;
  }
  else {
    Serial.print("Opened from SD: ");
    Serial.println(trackname);
  }
  playingMusic = true;
  while (!vs1053ReadyForData() );                                    // wait for ready for data
  while (playingMusic && vs1053ReadyForData()) vs1053FeedBuffer();   // then send data
  return true;
}

///////////////////////////////////////////////////
// XDREQ is low while the receive buffer is full
///////////////////////////////////////////////////
void vs1053FeedBuffer() { //debugging this function causes memory overruns
  //  Serial.println("vs1053FeedBuffer");

  static uint8_t running = 0;
  uint8_t sregsave;

  // Do not allow 2 FeedBuffer instances to run concurrently
  // SREG bit 7 = OFF => no interrupts until bit 7 = ON
  //  sregsave = SREG; // Status Register can clear/set interrupt enable bit 7 cli or sei
  noInterrupts();           // Clear interrupt enable bit 7 in SREG => disable interrupts
  //  if (running) { SREG = sregsave; return; } else { running = 1; SREG = sregsave;  }
  // paused or stopped. no SDCard track open, XDREQ=0 receive buffer full
  if ((!playingMusic) || (!currentTrack) || (!vs1053ReadyForData())) {
    running = 0;
    interrupts();
    return;
  }
  interrupts();
  //  if (!playingMusic){
  //    Serial.println("Paused or stopped");
  //    running = 0; return;
  //  }
  //  if (!currentTrack){
  //    Serial.println("No track open from SD card");
  //    running = 0; return;
  //  }
  //  if(!vs1053ReadyForData()){
  //    Serial.println("XDREQ=0 receive buffer full");
  //    running = 0; return;
  //  }

  //  Serial.println("Ready to send buffer");

  // Send buffer
  while (vs1053ReadyForData())
  { int bytesread = currentTrack.read(SoundBuffer, vs1053_DATABUFFERLEN);
    if (bytesread == 0)           // End of File
    { playingMusic = false;
      currentTrack.close();
      running = 0;
      return;
    }
    vs1053PlayData(SoundBuffer, bytesread);
  }
  running = 0;
  return;
}

////////////////////////////////////////////////////
// XDREQ is true while the receive buffer has space
////////////////////////////////////////////////////
boolean vs1053ReadyForData()
{ return digitalRead(XDREQ);
}

//////////////////////////////////////////////////////
void vs1053PlayData(uint8_t *buffer, uint8_t buffsiz)
{ SPI.beginTransaction(vs1053_DATA_SPI_SETTING);
  digitalWrite(XDCS, LOW);

  for (uint8_t i = 0; i < buffsiz; i++) {
    vs1053SpiWrite(buffer[i]);  // buffsiz = 32
  }

  digitalWrite(XDCS, HIGH);
  SPI.endTransaction();
}

//////////////////////////////////////////////////
void vs1053SetVolume(uint8_t left, uint8_t right)
{ uint16_t v;
  v = left;
  v <<= 8;
  v |= right;

  cli();
  vs1053SciWrite(vs1053_REG_VOLUME, v);
  sei();
}

////////////////////////////
uint16_t vs1053DecodeTime()
{ cli();
  uint16_t t = vs1053SciRead(vs1053_REG_DECODETIME);
  sei();
  return t;
}

///////////////////////
void vs1053SoftReset()
{ vs1053SciWrite(vs1053_REG_MODE, vs1053_MODE_SM_SDINEW | vs1053_MODE_SM_RESET);
  delay(100);
}

//////////////////////////
void vs1053Reset()
{ if (XRST >= 0)
  { digitalWrite(XRST, LOW);
    delay(100);
    digitalWrite(XRST, HIGH);
  }
  digitalWrite(XCS, HIGH);
  digitalWrite(XDCS, HIGH);
  delay(100);
  vs1053SoftReset();
  delay(100);

  vs1053SciWrite(vs1053_REG_CLOCKF, 0x6000);

  vs1053SetVolume(40, 40);
}

//////////////////////
uint8_t vs1053Begin()
{ if (XRST >= 0) {
    pinMode(XRST, OUTPUT);  // if reset = -1 ignore
    digitalWrite(XRST, LOW);
  }

  pinMode(XCS, OUTPUT);
  digitalWrite(XCS, HIGH);
  pinMode(XDCS, OUTPUT);
  digitalWrite(XDCS, HIGH);
  pinMode(XDREQ, INPUT);

  SPI.begin();
  //  SPI.setDataMode(SPI_MODE0);
  //  SPI.setBitOrder(MSBFIRST);
  //  SPI.setClockDivider(SPI_CLOCK_DIV128);

  vs1053Reset();

  return (vs1053SciRead(vs1053_REG_STATUS) >> 4) & 0x0F;
}

/////////////////////////////////////
uint16_t vs1053SciRead(uint8_t addr)
{ uint16_t data;
  SPI.beginTransaction(vs1053_CONTROL_SPI_SETTING);
  digitalWrite(XCS, LOW);
  vs1053SpiWrite(vs1053_SCI_READ);
  vs1053SpiWrite(addr);
  delayMicroseconds(10);
  data = vs1053SpiRead();
  data <<= 8;
  data |= vs1053SpiRead();
  digitalWrite(XCS, HIGH);
  SPI.endTransaction();
  return data;
}

//////////////////////////////////////////////
void vs1053SciWrite(uint8_t addr, uint16_t data)
{ SPI.beginTransaction(vs1053_CONTROL_SPI_SETTING);
  digitalWrite(XCS, LOW);
  vs1053SpiWrite(vs1053_SCI_WRITE);
  vs1053SpiWrite(addr);
  vs1053SpiWrite(data >> 8);
  vs1053SpiWrite(data & 0xFF);
  digitalWrite(XCS, HIGH);
  SPI.endTransaction();
}

static volatile uint8_t *clkportreg;
static uint8_t clkpin;

////////////////////////
uint8_t vs1053SpiRead()
{ int8_t x;
  x = 0;
  //clkportreg = portOutputRegister(digitalPinToPort(SCLK));
  //clkpin = digitalPinToBitMask(SCLK);
  // MSB first, clock low when inactive (CPOL 0), data valid on leading edge (CPHA 0)
  // Make sure clock starts low
  x = SPI.transfer(0x00);
  // Make sure clock ends low
  //*clkportreg &= ~clkpin;

  return x;
}

///////////////////////////////
void vs1053SpiWrite(uint8_t c)
{ // MSB first, clock low when inactive (CPOL 0), data valid on leading edge (CPHA 0)
  // Make sure clock starts low
  //clkportreg = portOutputRegister(digitalPinToPort(SCLK));
  //clkpin = digitalPinToBitMask(SCLK);
  SPI.transfer(c);
  //*clkportreg &= ~clkpin;   // Make sure clock ends low
}

////////////////////////////// from https://mpflaga.github.io/Arduino_Library-vs1053_for_SdFat/vs1053___sd_fat_8cpp_source.html
  union twobyte {
 
   uint16_t word;
 
   uint8_t  byte[2];
 } ;
 
 uint8_t VSLoadUserCode(char* fileName){

  /*
    0 indicates that upload was successful.
    1 indicates the upload can not be performed while currently streaming music.
    2 indicates that desired file was not found.
    3 indicates that the VSdsp is in reset.
  */
  
   union twobyte val;
   union twobyte addr;
   union twobyte n;
 
//   if(!digitalRead(MP3_RESET)) return 3;
   if(!digitalRead(XRST)) return 3;
   if(playingMusic) return 1;
   if(!digitalRead(XRST)) return 3;

    File file;
    
   //Open the file in read mode.
   //if(!track.open(fileName, O_READ)) return 2;
   file = SD.open(fileName, O_READ);
   if(!file) return 2;
   //playing_state = loading;
   //while(i<size_of_Plugin/sizeof(Plugin[0])) {
   while(1) {
     //addr = Plugin[i++];
     //if(!track.read(addr.byte, 2)) break;
     if(!file.read(addr.byte, 2)) break;
     //n = Plugin[i++];
//     if(!track.read(n.byte, 2)) break;
     if(!file.read(n.byte, 2)) break;
     if(n.word & 0x8000U) { /* RLE run, replicate n samples */
       n.word &= 0x7FFF;
       //val = Plugin[i++];
//       if(!track.read(val.byte, 2)) break;
       if(!file.read(val.byte, 2)) break;
       while(n.word--) {
//         Mp3WriteRegister(addr.word, val.word);
         vs1053SciWrite(addr.word, val.word);

       }
     } else {           /* Copy run, copy n samples */
       while(n.word--) {
         //val = Plugin[i++];
//         if(!track.read(val.byte, 2))   break;
         if(!file.read(val.byte, 2))   break;
//         Mp3WriteRegister(addr.word, val.word);
         vs1053SciWrite(addr.word, val.word);

       }
     }
   }
//   track.close(); //Close out this track
   file.close(); //Close out this track
   //playing_state = ready;
   return 0;
 }

/////////////////////////////////////
// End .cpp
/////////////////////////////////////

void playbackRegDebug(){
  //check registers for WAV debug

  uint16_t HDAT0 = vs1053SciRead(vs1053_REG_HDAT0);
  uint16_t HDAT1 = vs1053SciRead(vs1053_REG_HDAT1);
  uint16_t AUDATA = vs1053SciRead(vs1053_REG_AUDATA);
  uint16_t VOL = vs1053SciRead(vs1053_REG_VOLUME);
  
  Serial.print("SCI_HDAT0 int: ");
  Serial.print(HDAT0); //"For WAV files, SCI_HDAT1 contains 0x7665 (“ve”)" datasheet P45
  Serial.print(" hex: ");
  Serial.println(HDAT0,HEX);
  
  Serial.print("SCI_HDAT1 int: ");
  Serial.print(HDAT1); //"SCI_HDAT0 contains the data rate measured in bytes per second...To get the bitrate of the file, multiply the value by 8." datasheet P45
  Serial.print(" hex: ");
  Serial.println(HDAT1,HEX);
  
  Serial.print("vs1053_REG_AUDATA int: ");
  Serial.print(AUDATA);
  Serial.print(" hex: ");
  Serial.println(AUDATA,HEX);
  
  Serial.print("Volume int: ");
  Serial.print(VOL);
  Serial.print(" hex: ");
  Serial.println(VOL,HEX);
}

void loadPatch(){
Serial.println("Loading patch patches.053 Sparkfun.053"); 
int patchloadstatus = VSLoadUserCode("patches.053 Sparkfun.053"); //https://github.com/mpflaga/Arduino_Library-vs1053_for_SdFat/tree/master/plugins
Serial.print("Patch status: ");
Serial.println(patchloadstatus);
}



void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for Arduino Serial Monitor
  Serial.println("Adafruit vs1053B SDCard Music Player Test");

  if (! vs1053Begin()) { // initialise the music player
    Serial.println(F("Couldn't find vs1053"));
    while (1);
  }
  Serial.println(F("vs1053 found"));

  SD.begin(SDCS);    // initialise the SD card

  // Set volume for left, right channels. lower numbers is higher volume
  vs1053SetVolume(20, 20);

  // If XDREQ is on an interrupt pin (any Teensy pin) can do background audio playing
  vs1053Interrupt();  // XDREQ int

//PLAYBACK TESTING
  
//  Serial.println(F("Playing track008.wav - press p to pause, s to stop"));  //ISSUE: Short wav files work but long ones don't?
//  vs1053StartPlayingFile("track008.wav");
//
    Serial.println(F("Playing /MusicBee/Music/Deadmau5/4x4=12/09 - Raise Your Weapon (Original Mix).mp3 - press p to pause, s to stop"));
  vs1053StartPlayingFile("/MusicBee/Music/Deadmau5/4x4=12/09 - Raise Your Weapon (Original Mix).mp3");
//
//    Serial.println(F("Playing the olllam - lllow the sun.wav - press p to pause, s to stop")); //4608kbps
//  vs1053StartPlayingFile("the olllam - lllow the sun.wav");

//    Serial.println(F("Playing Manjit - 01. Forget Me Nots (Original Mix).wav - press p to pause, s to stop")); //1411kbps
//  vs1053StartPlayingFile("Manjit - 01. Forget Me Nots (Original Mix).wav");
//
//      Serial.println(F("Playing Tommy Farrow - Let's Just (Komix Edit) really short.wav - press p to pause, s to stop")); //1411kbps
//  vs1053StartPlayingFile("Tommy Farrow - Let's Just (Komix Edit) really short.wav");
//
//  if (playingMusic) {
//    Serial.println("Playback started");
//  }
//  else {
//    Serial.println("Playback failed");
//  }

  delay(10);

  playbackRegDebug();

}

void loop() {
 
  // File is playing in the background
  if (vs1053Stopped()) {
    Serial.println("Terminated");
    while (1);
  }
  if (Serial.available()) {
    char c = Serial.read();

    // if we get an 's' on the serial console, stop!
    if (c == 's') {
      vs1053StopPlaying();
    }

    // if we get an 'p' on the serial console, pause/unpause!
    if (c == 'p') {
      if (! vs1053Paused()) {
        Serial.println("Pause - press p to pause, s to stop");
        vs1053PausePlaying(true);
      } else {
        Serial.println("Resumed - press p to pause, s to stop");
        vs1053PausePlaying(false);
      }
    }
  }
 
  Serial.println("Loop running");
  playbackRegDebug();

  delay(100);
}
Printouts:

Code: Select all

Adafruit vs1053B SDCard Music Player Test
vs1053 found
Playing Tommy Farrow - Let's Just (Komix Edit) really short.wav - press p to pause, s to stop
vs1053StartPlayingFile
Opened from SD: Tommy Farrow - Let's Just (Komix Edit) really short.wav
SCI_HDAT0 int: 0 hex: 0
SCI_HDAT1 int: 0 hex: 0
vs1053_REG_AUDATA int: 8000 hex: 1F40
Volume int: 5140 hex: 1414
Loop running

Adafruit vs1053B SDCard Music Player Test
vs1053 found
Playing Manjit - 01. Forget Me Nots (Original Mix).wav - press p to pause, s to stop
vs1053StartPlayingFile
Opened from SD: Manjit - 01. Forget Me Nots (Original Mix).wav
SCI_HDAT0 int: 0 hex: 0
SCI_HDAT1 int: 0 hex: 0
vs1053_REG_AUDATA int: 8000 hex: 1F40
Volume int: 5140 hex: 1414
Loop running

Adafruit vs1053B SDCard Music Player Test
vs1053 found
Playing the olllam - lllow the sun.wav - press p to pause, s to stop
vs1053StartPlayingFile
Opened from SD: the olllam - lllow the sun.wav
SCI_HDAT0 int: 0 hex: 0
SCI_HDAT1 int: 0 hex: 0
vs1053_REG_AUDATA int: 8000 hex: 1F40
Volume int: 5140 hex: 1414
Loop running

Adafruit vs1053B SDCard Music Player Test
vs1053 found
Playing track008.wav - press p to pause, s to stop
vs1053StartPlayingFile
Opened from SD: track008.wav
SCI_HDAT0 int: 0 hex: 0
SCI_HDAT1 int: 0 hex: 0
vs1053_REG_AUDATA int: 8000 hex: 1F40
Volume int: 5140 hex: 1414
Loop running

Adafruit vs1053B SDCard Music Player Test
vs1053 found
Playing /MusicBee/Music/Deadmau5/4x4=12/09 - Raise Your Weapon (Original Mix).mp3 - press p to pause, s to stop
vs1053StartPlayingFile
Opened from SD: /MusicBee/Music/Deadmau5/4x4=12/09 - Raise Your Weapon (Original Mix).mp3
SCI_HDAT0 int: 0 hex: 0
SCI_HDAT1 int: 0 hex: 0
vs1053_REG_AUDATA int: 8000 hex: 1F40
Volume int: 5140 hex: 1414
Loop running
The files do usually appear to run through and stop, so that this check in the loop() eventually prints 'Terminated':

Code: Select all

if (vs1053Stopped()) {
    Serial.println("Terminated");
    while (1);
  }
User avatar
pasi
VLSI Staff
Posts: 2019
Joined: Thu 2010-07-15 16:04

Re: VS1053b WAV playback - no audio

Post by pasi »

I tried both with vs1053b (without patches) and they both produced sound. Not very pretty sound, my stream IO is much too slow, even slower than yours.

And a quick note for HDAT1: the audio format cannot be detected before you send the first few bytes of the file at least (depends on the decoder). Also, you'll always see the default 8000Hz samplerate in SCI_AUDATA when you read it before sending the first file. If you read SCI_AUDATA after sending the file, you should see the last used samplerate, so that's probably the next good debug.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
thecomfychair
User
Posts: 5
Joined: Fri 2022-08-26 9:14

Re: VS1053b WAV playback - no audio

Post by thecomfychair »

Always read the fine print, and always thoroughly check anything bought from Aliexpress... While the product page implies the chip might be a VS1053b, what you actually get is a VS1003b:
20220913_172810.jpg
20220913_172810.jpg (1.13 MiB) Viewed 160 times
I will make another purchase, and this time zoom in veeeery closely on the IC's label in the preview pictures before buying!

Thank you for your help Pasi. I will test the new boards when they arrive and confirm whether this code works.
User avatar
pasi
VLSI Staff
Posts: 2019
Joined: Thu 2010-07-15 16:04

Re: VS1053b WAV playback - no audio

Post by pasi »

I compared the headers of the wav files and it looks like if one plays, the other one should also play. Even if that's a vs1003b. (I tested with vs1003b -- naturally with the same crappy sound due to the too-slow-transfer issue.)

You might want to check the data you are sending to the vs10xx. Does it start with "RIFF" in both cases?
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
thecomfychair
User
Posts: 5
Joined: Fri 2022-08-26 9:14

Re: VS1053b WAV playback - no audio

Post by thecomfychair »

New and correct boards have (finally!) arrived, one of which works perfectly including debugging via registers.
pasi wrote: Wed 2022-09-14 8:31 You might want to check the data you are sending to the vs10xx. Does it start with "RIFF" in both cases?
Thank you Pasi, this solves the silence issue: some files had non-standard headers, which I fixed in a quick-and-dirty way by importing and exporting them from Audacity as WAV again. They now fit the format specified in the VS1053b datasheet (P56), also available here: https://docs.fileformat.com/audio/wav/#wav-file-header. Here's a before and after comparison:

Before:
Wav bad header.PNG
Wav bad header.PNG (51.38 KiB) Viewed 57 times
After:
Wav good header.PNG
Wav good header.PNG (42.36 KiB) Viewed 57 times

All WAV files now play! However a file with a bitrate of 4608kbps plays extremely slowly. Presumably this is a hardware limitation and I should convert it down to something like 1411kbps (which plays flawlessly)?
User avatar
pasi
VLSI Staff
Posts: 2019
Joined: Thu 2010-07-15 16:04

Re: VS1053b WAV playback - no audio

Post by pasi »

It seems your "before"-WAV uses WAVE_FORMAT_EXTENSIBLE, and the WAV decoder in vs1053b doesn't know how to interpret that. The WAV decoder in vs1063a would process that correctly.

The bitrate of the file isn't an issue, but the samplerate is 96000Hz, and vs1053b / vs1063a can only play up to 48000Hz. In addition the WAV decoder uses only the low 16 bits of the samplerate information, making 96000Hz it play at 30464Hz.

The best workaround is to convert to 48kHz sample rate.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
thecomfychair
User
Posts: 5
Joined: Fri 2022-08-26 9:14

Re: VS1053b WAV playback - no audio

Post by thecomfychair »

pasi wrote: Thu 2022-10-27 11:15 The WAV decoder in vs1063a would process that correctly
Great news! I am committed to the VS1053b on this version of the project but will investigate the vs1063a for the next revision.
pasi wrote: Thu 2022-10-27 11:15 The best workaround is to convert to 48kHz sample rate.
This make absolute sense, thank you. I will ensure to downsample all WAV files before playing through the VS1053b.

Thank you very much for your assistance Pasi, this IC will make my project many times easier!
Post Reply