how to record my voice in Vs1003?

Writing software for systems that use VLSI Solution's devices as slave codecs to a host microcontroller.
mf1364
Senior User
Posts: 25
Joined: Sun 2012-09-02 7:53

how to record my voice in Vs1003?

Post by mf1364 » Mon 2014-05-19 14:40

Hi every body
Last year I could play mp3 music by Vs1003 very good now I would like to record my voice in VS, and play it by vs. could you please learn me which command I should use ? in frankly speaking what should I have do?

User avatar
Panu
VLSI Staff
Posts: 2743
Joined: Tue 2010-06-22 13:43

Re: how to record my voice in Vs1003?

Post by Panu » Tue 2014-05-20 20:55

Hi!

Use VS1003 and a microcontroller. With the microcontroller, create a file on an SD card with a WAV header (see datasheet). Activate the ADPCM encoder. Read the ADPCM data from the VS1003 and add it to the file. For elegance, after recording, set the correct file length in the WAV header. The file can now be played.

See:
viewtopic.php?f=11&t=3 and
http://www.vlsi.fi/player_vs1011_1002_1 ... 8c.html#a3
http://www.vlsi.fi/player_vs1011_1002_1 ... ource.html

Alternatively, you can use the Standalone Recorder firmware, but the capabilities are very limited. See:
http://www.vlsi.fi/fileadmin/evaluation ... dalone.pdf page 8

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

mf1364
Senior User
Posts: 25
Joined: Sun 2012-09-02 7:53

Re: how to record my voice in Vs1003?

Post by mf1364 » Wed 2014-05-21 14:12

Dear Panu
It seems too difficult I don't know what you mean by wav header ?
could you please guide me step by step, your efforts is so appreciated.

User avatar
Panu
VLSI Staff
Posts: 2743
Joined: Tue 2010-06-22 13:43

Re: how to record my voice in Vs1003?

Post by Panu » Wed 2014-05-21 16:47

Ok we can do it step by step.

First create a file on the SD card. Write this data into the file:

Code: Select all

const unsigned char RIFFHeader0[] = {
 'R' , 'I' , 'F' , 'F' , // Chunk ID (RIFF)
 0x70, 0x70, 0x70, 0x70, // Chunk payload size (calculate after rec!)
 'W' , 'A' , 'V' , 'E' , // RIFF resource format type
 
 'f' , 'm' , 't' , ' ' , // Chunk ID (fmt )
 0x14, 0x00, 0x00, 0x00, // Chunk payload size (0x14 = 20 bytes)
 0x11, 0x00,             // Format Tag (IMA ADPCM)
 0x01, 0x00,             // Channels (1)
 0x80, 0x3e, 0x00, 0x00, // Sample Rate, 0x3e80 = 16.0kHz
 0xd7, 0x0f, 0x00, 0x00, // Average Bytes Per Second
 0x00, 0x01,             // Data Block Size (256 bytes) 
 0x04, 0x00,             // ADPCM encoded bits per sample (4 bits)
 0x02, 0x00,             // Extra data (2 bytes)
 0xf9, 0x01,             // Samples per Block (505 samples)
 
 'f' , 'a' , 'c' , 't' , // Chunk ID (fact)
 0xc8, 0x01, 0x00, 0x00, // Chunk payload size (456 bytes (zeropad!))
 0xff, 0xff, 0xff, 0xff  // Number of Samples (calculate after rec!)
 };
Then add 448 bytes of zero to the file. Then add this data to the file.

Code: Select all

const unsigned char RIFFHeader504[] = {
 'd' , 'a' , 't' , 'a' , // Chunk ID (data)
 0x70, 0x70, 0x70, 0x70  // Chunk payload size (calculate after rec!)
 };
 
There should now be 512 bytes of data in the file.

Let's continue after you have completed this step.

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

mf1364
Senior User
Posts: 25
Joined: Sun 2012-09-02 7:53

Re: how to record my voice in Vs1003?

Post by mf1364 » Thu 2014-05-22 10:12

Dear Panu
It seems I should finally wrote complete codes in record.c right ? because this part you put for me as a step by step guidance is a part of record.c but notice because I am Amateur that file is too difficult for me I change that codes for mikroc (I use PIC) so finally after compiling I receive lots of error so I found the below codes that are for mikroc if you could check it and correct its mistake it is so appreciated

Code: Select all


const unsigned char header[]={

0x52,0x49,0x46,0x46,0x34,0x2C,0x01,0x00,
0x57,0x41,0x56,0x45,0x66,0x6d,0x74,0x20,
0x14,0x00,0x00,0x00,0x11,0x00,0x01,0x00,
0x40,0x1f,0x00,0x00,0x75,0x12,0x00,0x00,
0x00,0x01,0x04,0x00,0x02,0x00,0xf9,0x01,
0x66,0x61,0x63,0x74,0x04,0x00,0x00,0x00,
0xCC,0x4F,0x02,0x00,0x64,0x61,0x74,0x61,
0xC4,0x2B,0x01,0x00};

unsigned char db[512];
unsigned int ww=0, k=0;
int idx=0;
unsigned int reg =0;
unsigned char data=0 , i=0 ,m=0;
int j=0;
char txt[14];
main(){
adcon1=6;     //config portA digital
CCP1CON=1;

trisd.f2=0;   // Dreq
portd.f2=0;

trisd.f3=0;

portd.f3=0;

trisc.f0=0;       // VS chip select
portc.f0=1;

trisc.f1=0;

trisc.f2=0;
portc.f2=1;

trisd.f0=1;       //seial CLK
portd.f0=0;

trisd.f1=0;      // serial data
portd.f1=0;

Spi_Init_Advanced(MASTER_OSC_DIV64, DATA_SAMPLE_MIDDLE, CLK_IDLE_LOW, LOW_2_HIGH);


Lcd_Init(&PORTB);
Lcd_Cmd(LCD_CLEAR);
Lcd_Cmd(LCD_CURSOR_OFF);
lcd_out(2,8,"START");
delay_ms(1000);
Lcd_Cmd(LCD_CLEAR);

if(mmc_fat_init(&portc ,1)!=0)  //if FAT16 boot sector was not found
{
lcd_out(1,1,"SD CARD didn't Found");
//delay_ms(500);
//Lcd_Cmd(LCD_CLEAR);
}
 Spi_Init_Advanced(MASTER_OSC_DIV16, DATA_SAMPLE_MIDDLE, CLK_IDLE_LOW, LOW_2_HIGH);


/////////////////RESET/////////////////
reg=0x0204;
portc.f0=0;
spi_write(2);
spi_write(0);
spi_write(reg>>8);
spi_write(reg);
portc.f0=1;
///////////////////////////////////////

while (PORTD.f2==0) {}
delay_us(2);
while (PORTD.f2==0) {}

data=0;
for (j=1;j<2049;j++)
{
while (PORTD.f2==0) {}
//portd.f1=1;
portd.f0=0; portd.f1=data.f0; portd.f0=1;
portd.f0=0; portd.f1=data.f1; portd.f0=1;
//portd.f1=0;
portd.f0=0; portd.f1=data.f2; portd.f0=1;
portd.f0=0; portd.f1=data.f3; portd.f0=1;
portd.f0=0; portd.f1=data.f4; portd.f0=1;
portd.f0=0; portd.f1=data.f5; portd.f0=1;
portd.f0=0; portd.f1=data.f6; portd.f0=1;
portd.f0=0; portd.f1=data.f7; portd.f0=1;
portd.f0=0;
}
/////////////////RESET/////////////////
delay_ms(1);
/////////////////CLOCK/////////////////
reg=0x9BE8;     [color=#FF0000] //please check this value is correct?[/color]
portc.f0=0;
spi_write(2);
spi_write(3);
spi_write(reg>>8);
spi_write(reg);
portc.f0=1;
while (PORTD.f2==0) {}
/////////////////CLOCK/////////////////
delay_ms(1);



/////////////////RECORD/////////////////

portc.f0=0;
spi_write(2);
spi_write(12);   //AICTRL0
reg=0x5;           [color=#FF0000]//please check this value is correct?[/color]
spi_write(reg>>8);
spi_write(reg);
portc.f0=1;

while (PORTD.f2==0) {}

portc.f0=0;
spi_write(2);
spi_write(13);       //AICTRL1
reg=0x0;            [color=#FF0000]//please check this value is correct?[/color]
spi_write(reg>>8);
spi_write(reg);
portc.f0=1;

while (PORTD.f2==0) {}

portc.f0=0;
spi_write(2);
spi_write(0);     //MODE
reg=0x3204;        //soft rest,MSB last,recording active,high-pass filter active
spi_write(reg>>8);
spi_write(reg);
portc.f0=1;

while (PORTD.f2==0) {}

portc.f0=0;
spi_write(2);
spi_write(3);       //ClOCKF
//reg=0x9BE8;
reg=0x3E8;          [color=#FF0000]//please check this value is correct?[/color]
//reg=384;
spi_write(reg>>8);
spi_write(reg);
portc.f0=1;

while (PORTD.f2==0) {}

portc.f0=0;
spi_write(2);
spi_write(5);       //AUDATA
reg=0x1f40;         [color=#FF0000]//please check this value is correct?[/color]
//reg=0x1E78;
spi_write(reg>>8);
spi_write(reg);
portc.f0=1;
while (PORTD.f2==0) {}


/////////////////RECORD/////////////////
delay_ms(1);
for (idx=0;idx<sizeof(header);idx++){
db[idx]=header[idx];
}

lcd_out(1,1,"START RECORD");
delay_ms(1000);
Lcd_Cmd(LCD_CLEAR);


Mmc_Fat_Assign("1.wav",0xA0);
Mmc_Fat_reWrite();


//while (1){ //record on
for(k=0;k<150;k++)
{

//
do {
portc.f0=0;
spi_write(3);
spi_write(9);   //HDAT1
i=SPI_read(0);
m=SPI_read(0);
portc.f0=1;

ww=i;
ww=(ww*256);              //why?
ww=ww+m;
}while(ww<256 ||ww>896);   [color=#FF0000]//please check this value is correct?[/color]

while (idx<512){





portc.f0=0;
spi_write(3);
spi_write(8);         //HDAT0
i=SPI_read(0);
m=SPI_read(0);
portc.f0=1;

 db[idx]=i;
 idx++;
db[idx]=m;
idx++;

}
idx=0;
//Mmc_Fat_Assign("www.wav",0xA0);
Mmc_Fat_Append();
mmc_fat_write(db,512);

}

lcd_out(1,1,"END RECORD");


  while (1){};
}


User avatar
Panu
VLSI Staff
Posts: 2743
Joined: Tue 2010-06-22 13:43

Re: how to record my voice in Vs1003?

Post by Panu » Thu 2014-05-22 10:35

Hi,

That header is not the same which I gave to you. The sample rate, data rate, chunk sizes, sample counts are different. If you cannot use the header which I gave you, the probability of success in our step by step method is close to 0%. Is there any local C language expert who might be able to help you?

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

mf1364
Senior User
Posts: 25
Joined: Sun 2012-09-02 7:53

Re: how to record my voice in Vs1003?

Post by mf1364 » Thu 2014-05-22 11:33

Dear Pan
I didn't think those parameters are so important and I pick up that numbers from VS1003 datasheet in any way I replace that with your codes it is so easy

Code: Select all

const unsigned char header[]={

   'R' , 'I' , 'F' , 'F' , // Chunk ID (RIFF)
   0x70, 0x70, 0x70, 0x70, // Chunk payload size (calculate after rec!)
   'W' , 'A' , 'V' , 'E' , // RIFF resource format type

   'f' , 'm' , 't' , ' ' , // Chunk ID (fmt )
   0x14, 0x00, 0x00, 0x00, // Chunk payload size (0x14 = 20 bytes)
   0x11, 0x00,             // Format Tag (IMA ADPCM)
   0x01, 0x00,             // Channels (1)
   0x80, 0x3e, 0x00, 0x00, // Sample Rate, 0x3e80 = 16.0kHz
   0xd7, 0x0f, 0x00, 0x00, // Average Bytes Per Second
   0x00, 0x01,             // Data Block Size (256 bytes)
   0x04, 0x00,             // ADPCM encoded bits per sample (4 bits)
   0x02, 0x00,             // Extra data (2 bytes)
   0xf9, 0x01,             // Samples per Block (505 samples)

   'f' , 'a' , 'c' , 't' , // Chunk ID (fact)
   0xc8, 0x01, 0x00, 0x00, // Chunk payload size (456 bytes (zeropad!))
   0xff, 0xff, 0xff, 0xff  // Number of Samples (calculate after rec!)
   // Insert 448 zeroes here!
 };
how is your idea abut the rest of codes that I put for you in the previous topic ? those could help me ? are correct?

User avatar
Panu
VLSI Staff
Posts: 2743
Joined: Tue 2010-06-22 13:43

Re: how to record my voice in Vs1003?

Post by Panu » Sat 2014-05-24 8:25

Yes, otherwise it seems ok. Right, the header seemed to be a valid IMA ADPCM header. But at first it must be 100% similar than my header, otherwise the file will not play correctly. After we get it to play correctly, it's easy to modify (because we can fall back to a working setup in case of errors).

So if you close the SD card file now, it's size is 512 bytes?

Ok, the next step is to switch on the recording mode on the VS1003. First be sure that your clockf register is set, and that you have something like 3X clock multiplier. You need the clock frequency to be high enough so that you can efficiently read data.

Then switch on the recording with these register writes:

Code: Select all

   //Set sample rate 16khz for VS1003 (6.4kHz for VS1002 :( )
   Mp3WriteRegister(SPI_AICTRL0,0x00,0x09); //Set sample rate divider=9
   Mp3WriteRegister(SPI_AICTRL1,0x10,0x00); //AutoGain OFF, reclevel 0x1000
   Mp3WriteRegister(SPI_MODE,0x18,0x04);    //RECORD,NEWMODE,RESET

After that, start reading the SCI_HDAT1 register. It tells you how many 16-bit words of data there are available in the recording buffer. The register is zero at first, but its value will soon start to increase as blocks of data arrive from the ADPCM encoder.

Do something like... (this is not real C code, I'm writing this in the forum window)

Code: Select all

  int wordsToRead = ReadRegister(HDAT1);
  for (i=0; i<wordsToRead; i++) {
    u_int16 d = ReadRegister(HDAT0);
    WriteByteToFile(d>>8); //Write the high byte
    WriteByteToFile(d&255);   //Write the low byte (the and is usually not needed)
  }
Repeat this for as long as you want. Then close the file and give it the name "RECORD.WAV".

Let's continue after this step.

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

mf1364
Senior User
Posts: 25
Joined: Sun 2012-09-02 7:53

Re: how to record my voice in Vs1003?

Post by mf1364 » Mon 2014-05-26 10:00

Thank you very much
now I can record my voice and can play it, just my problem is the record time is limited (around 10 second )and I want to control it for example by pressing switch 1 the device start to recording and by pressing switch 2 the device stop recording. I know I should use register HDAT0 and HDAT1 but I don't know how ? could you please help me ?

User avatar
Panu
VLSI Staff
Posts: 2743
Joined: Tue 2010-06-22 13:43

Re: how to record my voice in Vs1003?

Post by Panu » Mon 2014-05-26 13:08

Hi!

Congratulations on making the record work! :D

From where does the 10 second limitation come from?

You can continue reading the data from VS1003 for as long as you want. Just do a soft reset after you're done.

After you have recorded for as long as you want, you should change the number of samples, size of the RIFF chunk and size of the DATA chunk in the header.

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

Post Reply