Ogg recording : only the first file is OK, next files are 1ko size

Designing hardware that uses VLSI Solution's devices as slave codecs such as an external MP3 decoder chip for a host microcontroller.
User avatar
samy_r
User
Posts: 17
Joined: Sun 2022-06-26 12:28
Location: Lyon (France)
Contact:

Ogg recording : only the first file is OK, next files are 1ko size

Post by samy_r »

Hi all
I'm currenty developing audio guestbooks using old dial phones. And I discovered VS1053-based solutions.

The hardware I use:
- Seeeduino Xiao
- VS1053 Shield : https://www.geeetech.com/wiki/index.php ... th_SD_card

Software:
- Arduino
- v08k1q05.img plugin

My problem is simple : recording works, but only the first recorded file is OK, following files are 1ko-sized.

I saw here viewtopic.php?t=2503 Pasi suggested an hardware reset before each recording but it seems to freeze the circuit. The only solution I found is to load the plugin each time I want to record, but it adds extra delay.

You can find the "corrupted" and the "not corrupted" Ogg files as attachments.

Did you experience this problem ?

Thanks

EDIT : I had also file with silent ranges every two seconds

EDIT2 : I solved both problems by:
- downgrading the RECBUFFSIZE to 32
- increasing the speeds used by SPI (Xiao is 48Mhz, not 16Mhz like Arduinos)
The upload time has been shorten too like explained here viewtopic.php?p=14734#p14734

Code: Select all

#define VS1053_CONTROL_SPI_SETTING                                             \
  SPISettings(2000000, MSBFIRST, SPI_MODE0) //!< VS1053 SPI control settings
#define VS1053_DATA_SPI_SETTING                                                \
  SPISettings(12000000, MSBFIRST, SPI_MODE0)
My original code:

Code: Select all

/***************************************************
  This is an example 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
 ****************************************************/

// This is a very beta demo of Ogg Vorbis recording. It works...
// Connect a button to digital 7 on the Arduino and use that to
// start and stop recording.

// A mic or line-in connection is required. See page 13 of the
// datasheet for wiring

// Don't forget to copy the v44k1q05.img patch to your micro SD
// card before running this example!


// include SPI, MP3 and SD libraries
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// define the pins used
#define RESET 5      // VS1053 reset pin (output)
#define CS 6        // VS1053 chip select pin (output)
#define DCS 4        // VS1053 Data/command select pin (output)
#define CARDCS 7     // Card chip select pin
#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

#define REC_BUTTON 1

Adafruit_VS1053_FilePlayer musicPlayer = Adafruit_VS1053_FilePlayer(RESET, CS, DCS, DREQ, CARDCS);

File recording;  // the file we will save our recording to
#define RECBUFFSIZE 128  // 64 or 128 bytes.
uint8_t recording_buffer[RECBUFFSIZE];

void setup() {
  Serial.begin(9600);
  while (!Serial);
  Serial.println("Adafruit VS1053 Ogg Recording Test");

  // initialise the music player
  if (!musicPlayer.begin()) {
    Serial.println("VS1053 not found");
    while (1);  // don't do anything more
  }

  musicPlayer.sineTest(0x44, 500);    // Make a tone to indicate VS1053 is working

  if (!SD.begin(CARDCS)) {
    Serial.println("SD failed, or not present");
    while (1);  // don't do anything more
  }
  Serial.println("SD OK!");

  // Set volume for left, right channels. lower numbers == louder volume!
  musicPlayer.setVolume(10, 10);

  // when the button is pressed, record!
  pinMode(REC_BUTTON, INPUT);
  digitalWrite(REC_BUTTON, HIGH);

  // load plugin from SD card! We'll use mono 44.1KHz, high quality
  if (! musicPlayer.prepareRecordOgg("v08k1q05.img")) {
    Serial.println("Couldn't load plugin!");
    while (1);
  }
  pinMode(0, OUTPUT); //règle la borne numérique numéro 1 de la carte Arduino en mode sortie

}

uint8_t isRecording = false;

void loop() {
  if (!isRecording && !digitalRead(REC_BUTTON)) {
    // load plugin from SD card! We'll use mono 44.1KHz, high quality

    digitalWrite(0, HIGH); //le courant est envoyé sur la borne 1, la LED  s'allume

    Serial.println("Begin recording");
    isRecording = true;

    // Check if the file exists already
    char filename[15];
    strcpy(filename, "RECORD00.OGG");
    for (uint8_t i = 0; i < 100; i++) {
      filename[6] = '0' + i / 10;
      filename[7] = '0' + i % 10;
      // create if does not exist, do not open existing, write, sync after write
      if (! SD.exists(filename)) {
        break;
      }
    }
    Serial.print("Recording to "); Serial.println(filename);
    recording = SD.open(filename, FILE_WRITE);
    if (! recording) {
      Serial.println("Couldn't open file to record!");
      while (1);
    }
    musicPlayer.startRecordOgg(true); // use microphone (for linein, pass in 'false')
  }
  if (isRecording) {
    saveRecordedData(isRecording);
  }
  if (isRecording && digitalRead(REC_BUTTON)) {
    Serial.println("End recording");

    musicPlayer.stopRecordOgg();
    digitalWrite(0, LOW); //le courant est envoyé sur la borne 1, la LED  s'allume

    isRecording = false;
    // flush all the data!
    saveRecordedData(isRecording);
    // close it up
    recording.close();

    delay(1000);
    Serial.println("Ready");

  }
}

uint16_t saveRecordedData(boolean isrecord) {
  uint16_t written = 0;

  // read how many words are waiting for us
  uint16_t wordswaiting = musicPlayer.recordedWordsWaiting();

  // try to process 256 words (512 bytes) at a time, for best speed
  while (wordswaiting > 256) {
    //Serial.print("Waiting: "); Serial.println(wordswaiting);
    // for example 128 bytes x 4 loops = 512 bytes
    for (int x = 0; x < 512 / RECBUFFSIZE; x++) {
      // fill the buffer!
      for (uint16_t addr = 0; addr < RECBUFFSIZE; addr += 2) {
        uint16_t t = musicPlayer.recordedReadWord();
        //Serial.println(t, HEX);
        recording_buffer[addr] = t >> 8;
        recording_buffer[addr + 1] = t;
      }
      if (! recording.write(recording_buffer, RECBUFFSIZE)) {
        Serial.print("Couldn't write "); Serial.println(RECBUFFSIZE);
        while (1);
      }
    }
    // flush 512 bytes at a time
    recording.flush();
    written += 256;
    wordswaiting -= 256;
  }

  wordswaiting = musicPlayer.recordedWordsWaiting();
  if (!isrecord) {
    Serial.print(wordswaiting); Serial.println(" remaining");
    // wrapping up the recording!
    uint16_t addr = 0;
    for (int x = 0; x < wordswaiting - 1; x++) {
      // fill the buffer!
      uint16_t t = musicPlayer.recordedReadWord();
      recording_buffer[addr] = t >> 8;
      recording_buffer[addr + 1] = t;
      if (addr > RECBUFFSIZE) {
        if (! recording.write(recording_buffer, RECBUFFSIZE)) {
          Serial.println("Couldn't write!");
          while (1);
        }
        recording.flush();
        addr = 0;
      }
    }
    if (addr != 0) {
      if (!recording.write(recording_buffer, addr)) {
        Serial.println("Couldn't write!"); while (1);
      }
      written += addr;
    }
    musicPlayer.sciRead(VS1053_SCI_AICTRL3);
    if (! (musicPlayer.sciRead(VS1053_SCI_AICTRL3) & (1 << 2))) {
      recording.write(musicPlayer.recordedReadWord() & 0xFF);
      written++;
    }
    recording.flush();
  }

  return written;
}

boolean customReset() {

  musicPlayer.softReset();
  while (!musicPlayer.readyForData())
    ;
}
Attachments
corrupted.OGG
(1 KiB) Downloaded 21 times
not_corrupted.OGG
(128.5 KiB) Downloaded 20 times
User avatar
pasi
VLSI Staff
Posts: 2019
Joined: Thu 2010-07-15 16:04

Re: Ogg recording : only the first file is OK, next files are 1ko size

Post by pasi »

You really need to reload the Ogg Vorbis Encoding application for every recording, because as far as I remember the Ogg Vorbis header (among others) is pre-loaded in the FIFO and will be overwritten by the encoded data.

An alternative would be to use vs1063a/vs1163a/vs8063a, which contains the Ogg Vorbis encoder in ROM. The vs1063a patches package doesn't include any critical Ogg Vorbis -encoding-related patches, so it's not absolutely necessary (if you hardware reset between to avoid the channel-swap bug).

Edit: your not_corrupted.OGG contains just zeroes, corrupted.OGG has a valid Ogg Vorbis header, but the data is truncated at 1kB. So, I'm not sure what has happened there.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
User avatar
samy_r
User
Posts: 17
Joined: Sun 2022-06-26 12:28
Location: Lyon (France)
Contact:

Re: Ogg recording : only the first file is OK, next files are 1ko size

Post by samy_r »

Thanks ! Another solution is to record PCM/WAV files, but I don't find much information about it (Arduino libraries seems to only support Ogg recording).
User avatar
pasi
VLSI Staff
Posts: 2019
Joined: Thu 2010-07-15 16:04

Re: Ogg recording : only the first file is OK, next files are 1ko size

Post by pasi »

In vs1053b you need to generate the WAV headers yourself and do the byte order swap -- see the datasheet for details. With vs1063a the WAV headers are part of the encoded stream, you only need to fix the size fields in the WAV header when you finish encoding.

There are some plugin / patch loading speedup suggestions in: viewtopic.php?f=11&t=2883
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
User avatar
samy_r
User
Posts: 17
Joined: Sun 2022-06-26 12:28
Location: Lyon (France)
Contact:

Re: Ogg recording : only the first file is OK, next files are 1ko size

Post by samy_r »

I have a big stock of VS1053 so I will explore vs1053 solutions ;)

Thanks for advices

(I already used solutions to speedup recording but the patch loading still takes about 1 second, and for my project, I need to have "instant" recording ;)

So using OGG recording seems not to be the solution.

I will post here the result of my tests !
User avatar
pasi
VLSI Staff
Posts: 2019
Joined: Thu 2010-07-15 16:04

Re: Ogg recording : only the first file is OK, next files are 1ko size

Post by pasi »

There is another option to speed up the loading of the vs1053b Ogg Vorbis application.

It could be made to be loaded from 64kB (1024kbit) SPI EEPROM. The release on the web doesn't include a spi-bootable version at the moment, but we tested the idea here, and it seems to work. (After we remembered to configure the encoder parameters by also writing the SCI_CLOCKF and SCI_AICTRLx registers from the boot image.)

Do you have the option of adding the SPI EEPROM and controlling GPIO0 (so that you can select between normal decoding mode and SPI boot)?
If yes, what's the encoding profile you need? (I have the spi boot image for the 24kHz mono profile at the moment.)
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
User avatar
samy_r
User
Posts: 17
Joined: Sun 2022-06-26 12:28
Location: Lyon (France)
Contact:

Re: Ogg recording : only the first file is OK, next files are 1ko size

Post by samy_r »

I apologize, but I think it overrides my skills :) (XCS is plugged on my Arduino, but I don't know how to use the EEPROM)
User avatar
pasi
VLSI Staff
Posts: 2019
Joined: Thu 2010-07-15 16:04

Re: Ogg recording : only the first file is OK, next files are 1ko size

Post by pasi »

Sorry, it should've been GPIO0 (and not xCS)... I edited the post.

GPIO0 is the chip select used for the EEPROM during SPI boot. If the pin is low during hardware or software reset, the vs1053 assumes there is no SPI boot device. If it is pulled high during hw/sw reset, vs1053 tries to boot from any SPI device connected to the specific pins defined in the datasheet.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
User avatar
samy_r
User
Posts: 17
Joined: Sun 2022-06-26 12:28
Location: Lyon (France)
Contact:

Re: Ogg recording : only the first file is OK, next files are 1ko size

Post by samy_r »

I'm not sure GPIO pins are connected on the breakout I use : https://www.geeetech.com/wiki/index.php ... th_SD_card

If I understand well, you mean I should:
- pull high GPIO pins on VS1053 to enable SPI boot
- add EEPROM to the board to boot from
(sorry for newbie questions about EEPROMs)
User avatar
pasi
VLSI Staff
Posts: 2019
Joined: Thu 2010-07-15 16:04

Re: Ogg recording : only the first file is OK, next files are 1ko size

Post by pasi »

From the view of that specific board, it's unlikely the needed pins are easily accessible.

You would need GPIO0, GPIO1, GPIO2, and DREQ to connect the SPI memory, and only DREQ is easily accessible. For the others you would probably need to solder wires directly to the vs1053 pins.

Anyway, even if this isn't useful for you, I hope this discussion is useful for others.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
Post Reply