VS1053 Codec board play/rec in in same sketch?

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
jjdeprisco
 
Posts: 38
Joined: Tue Apr 09, 2013 8:09 pm

VS1053 Codec board play/rec in in same sketch?

Post by jjdeprisco »

Like the vs1053 codec board... But has anyone successfully made it function in both play and record mode without having to load a new sketch? Seems like it should be possible to switch it from one mode to the next and back. The pin out is almost identical, but if the sketch doesnt change, then the pinout wouldnt matter.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: VS1053 Codec board play/rec in in same sketch?

Post by adafruit_support_bill »

There were a couple of forum members working on this. I think 'jonlab' got it working. There are probably a few threads on this over in the VLSI forums as well: http://www.vsdsp-forum.com/phpbb/index.php

User avatar
bahnlab
 
Posts: 19
Joined: Tue Aug 27, 2013 2:05 pm

Re: VS1053 Codec board play/rec in in same sketch?

Post by bahnlab »

I've been working on trying to do exactly this in ogg with an arduino uno for the past couple days. Here's what I've learned so far:

1 The pin layout for play from the tutorial works just fine for recording.

2 You'll have a really hard time if you load the plugin and prepare for recording in setup, if you put it inside the loop you can still record.

3 If you record first (or load the recording plugin provided), then try and playback (using interupt or play the full file) everything gets hung up and you get a very very stuttered playback.

4 If you try and playback first then record, all of the recordings are empty.

4.1 It's useful to print the wordswaiting to the monitor, if the wordswaiting is the same value each time, your recording is empty (keeps you from needing to check the SD) alot.

5 The reset doesn't unload the plugin. I wish it did, then I think I could get somewhere. I am in the process of hooking the VS1053 breakout power up through a relay switch so I can confirm that the recording plugin being loaded during playback is my issue.

6 jonlab is way better at this than me.

If you get this working or see somewhere I've went wrong or your stuff suggests different maybe we can get this working.

Here's the code I've been using, it's mostly hodgepodged together from the tutorials, you'll need to change the SD stuff back, mine's coming from the adafruit datalogger:

Code: Select all

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

// define the pins used
#define RESET 9      // VS1053 reset pin (output)
#define CS 2       // VS1053 chip select pin (output)
#define DCS 8        // VS1053 Data/command select pin (output)
#define CARDCS 10     // Card chip select pin
#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

#define REC_BUTTON 7

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];


//Adapted from Blink without delay example


// Variables will change:
long previousMillis = 0;        
long currentMillis = 0;
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 10000;           // interval at which to blink (milliseconds)
long Value = 0;


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

  delay(2000);

  // 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(1,1);
  
  
  // load plugin from SD card! We'll use mono 44.1KHz, high quality
  
}

uint8_t isRecording = false;


void loop() {
  currentMillis = millis();
  if (!isRecording) {
    //Do playback from file
    if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT))
      Serial.println("DREQ pin is not an interrupt pin");
    musicPlayer.setVolume(1,1);
    //This interupt style one would be ideal if it didn't stutter out
    if (! musicPlayer.startPlayingFile("track001.mp3")) {
      Serial.print("Could not open file");
      return;
    }
    Serial.println("Started playing");

    while (musicPlayer.playingMusic) {
      // file is now playing in the 'background' so now's a good time
      // to do something else like handling LEDs or buttons :)
      Serial.print(".");
      delay(1000);
    }
    Serial.println("Done playing music");
    Value = 0;  
    
    if (! musicPlayer.prepareRecordOgg("v44k1q05.img")) {
     Serial.println("Couldn't load plugin!");
     while (1);    
  }
    Serial.println("Begin recording");
    isRecording = true;
    Value = 1;
    // 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);
    }
      // load plugin from SD card! We'll use mono 44.1KHz, high quality
      if (! musicPlayer.prepareRecordOgg("v44k1q05.img")) {
       Serial.println("Couldn't load plugin!");
       while (1);    
  }
    musicPlayer.startRecordOgg(true); // use microphone (for linein, pass in 'false')
   
  }
  if (isRecording)
    saveRecordedData(isRecording);
  
  if (isRecording && currentMillis - previousMillis > interval) {
    Serial.println("End recording");
    musicPlayer.stopRecordOgg();
    isRecording = false;
    Value = 2;
    // flush all the data!
    saveRecordedData(isRecording);
    // close it up
    recording.close();
    delay(1000);
    musicPlayer.softReset();
    
    
    previousMillis = currentMillis;
    delay(1000);
   
  }
}


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) & _BV(2))) {
       recording.write(musicPlayer.recordedReadWord() & 0xFF);
       written++;
    }
    recording.flush();
  }

  return written;
}

User avatar
bahnlab
 
Posts: 19
Joined: Tue Aug 27, 2013 2:05 pm

Re: VS1053 Codec board play/rec in in same sketch?

Post by bahnlab »

Has anyone had better luck?

User avatar
bahnlab
 
Posts: 19
Joined: Tue Aug 27, 2013 2:05 pm

Re: VS1053 Codec board play/rec in in same sketch?

Post by bahnlab »

Further testing hasn't really gotten us any closer. Perhaps the adafruit ogg plugin is related. What does it contain?

User avatar
justphone
 
Posts: 1
Joined: Wed May 13, 2015 1:48 pm

Re: VS1053 Codec board play/rec in in same sketch?

Post by justphone »

I made #3 work ( "If you record first (or load the recording plugin provided), then try and playback (using interupt or play the full file) everything gets hung up and you get a very very stuttered playback.")

You need to musicPlayer.begin() again after recording, then it plays back. But, you need to load musicPlayer.prepareRecordOgg("v44k1q05.img") again to record again. Everything works, but the sound of recording goes down for some reason. Keep investigating. But, looks like you need begin player before playing and load plugin before recording.

radiopetushki
 
Posts: 6
Joined: Fri Feb 28, 2014 12:57 pm

Re: VS1053 Codec board play/rec in in same sketch?

Post by radiopetushki »

Could ya'll post the code? I am right in the middle of this project for an important installation and can't for the life of me get anywhere close to recording and playback in the same sketch

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”