PLAY WAV File VS1003B

Designing hardware that use VLSI Solution's devices as the system controller for the entire design.
adria_toa
User
Posts: 9
Joined: Wed 2021-04-14 8:33

PLAY WAV File VS1003B

Post by adria_toa »

Hi Panu,

Currently I have project using VS1003B.
How about to send WAV file? I try to send MP3 and it's OK but when try send WAV file there is no sound on output.

Here my init code

Code: Select all


uint8_t VSInitSoftware()
{
	WriteSci(SCI_MODE, SM_SDINEW | SM_OUTOFWAV | SM_RESET ); //|SM_SDISHARE|SM_TESTS|SM_RESET);
	WriteSci(SCI_CLOCKF,
			HZ_TO_SC_FREQ(12288000) | SC_MULT_03_30X | SC_ADD_03_10X);

	/*Set volume level at 0 db (0.5 db Steps) -> ((leftchannelx256)+rightchannel */
	WriteSci(SCI_VOL, 0x0000);	//Full Volume
	//WriteSci(SCI_BASS, 0x0055);
	WriteSci(SCI_DECODE_TIME, 0); //Reset Decode Time

	return 0;
}
Here's my play file function

Code: Select all

void playFile()
{
	uint32_t bytesInBuffer;
	uint32_t pos = 0;
	long nextReportPos=0;
	FRESULT		result;

	result = f_read(&AudioFile, playBuf, FILE_BUFFER_SIZE, (void*)&bytesInBuffer);
	if( result == FR_OK)
	{
		uint8_t *bufP = playBuf;

		while(bytesInBuffer){
			int t = min(SDI_MAX_TRANSFER_SIZE, bytesInBuffer);

			SendSDI(bufP, t);

			bufP += t;
			bytesInBuffer -= t;
			pos += t;
			/*If playback is going on as normal, see if we need to collect and update display lcd*/
			if(pos >= nextReportPos)
			{				
				h1 = ReceiveSci(SCI_HDAT1); //global variable
				nextReportPos += 4096;
				sampleRate = ReceiveSci(SCI_AUDATA); //global variable
				time = ReceiveSci(SCI_DECODE_TIME); //global variable
			}
		}
	}else
	{
		Player_Close();
	}
}
And here's SPI part code send data

Code: Select all

uint8_t SendSDI(uint8_t* buffer, uint8_t size)
{
	Mp3SelectData();	//xDCS = 0

	while(!CheckVS1003B_DRQ()); //Check DREQ pin
	if(HAL_SPI_Transmit(&VSSpiHandle, (uint8_t*)buffer, size, 500) != HAL_OK)
	{
		return 1;
	}

	Mp3DeselectData();	//xDCS = 1
	Mp3DeselectControl(); //xCS = 1

	return 0;
}
Is there special case if we want to send WAV or WMA file ?
Hannu
VLSI Staff
Posts: 550
Joined: Mon 2016-05-30 11:54
Location: Finland
Contact:

Re: PLAY WAV File VS1003B

Post by Hannu »

adria_toa wrote: Wed 2021-04-21 4:06 Currently I have project using VS1003B.
How about to send WAV file? I try to send MP3 and it's OK but when try send WAV file there is no sound on output.


Here my init code
Which I modded and removed the stop playing wav bit.

Code: Select all


uint8_t VSInitSoftware()
{
	/*WriteSci(SCI_MODE, SM_SDINEW | SM_OUTOFWAV | SM_RESET ); //|SM_SDISHARE|SM_TESTS|SM_RESET);*/
	WriteSci(SCI_MODE, SM_SDINEW  | SM_RESET ); //|SM_SDISHARE|SM_TESTS|SM_RESET);
	WriteSci(SCI_CLOCKF,
			HZ_TO_SC_FREQ(12288000) | SC_MULT_03_30X | SC_ADD_03_10X);

	/*Set volume level at 0 db (0.5 db Steps) -> ((leftchannelx256)+rightchannel */
	WriteSci(SCI_VOL, 0x0000);	//Full Volume
	//WriteSci(SCI_BASS, 0x0055);
	WriteSci(SCI_DECODE_TIME, 0); //Reset Decode Time

	return 0;
}

Here's my play file function
Which will read one FILE_BUFFER_SIZE of bytes and transmit it. It may not be what you intended. I presume, you opened the AudioFile previously and then called playFile function.
And does your system really give some real object and not just a pointer to a something which could be called as file?

Usually I read files something like this:

Code: Select all

int bytes;
while (1) {
	bytes = fread(buf, 1, BUF_SIZE, fp);
	if (bytes <= 0)break;
	pos += bytes;
	SendSdi(buf, bytes);
	PrintInfoToScreen(pos);
}
With that kind of structure, the infoprint is contrerolled by BUF_SIZE and if you have for example 256 byte buffer, wrap the three first lines inside for-loop and iterate 16 times to get 4096. 4096 would come really fast with wav files. 8 kHz stereo 16-bit would be about 2*2*2 = 8 times in second
And here's SPI part code send data
Which I modded to respect DREQ and the 32 bytes. That way I think, the player function can be simplified.

What is the parameter 500 in HAL_SPI_Trasmit function?

Code: Select all

#define SAFELY_CAN_SEND_BYTES 32
uint8_t SendSDI(uint8_t* buffer, uint8_t size)
{
	int16_t toSend = bytes; /* Signed 16-bit handles case where size > 128 and can go to negative side. */
	Mp3DeselectControl(); //xCS = 1 Is this really needed? Does some function leave XCS down?
	while(toSend > 0) {
		while(!CheckVS1003B_DRQ()); //Check DREQ pin
		Mp3SelectData();	//xDCS = 0
		if(HAL_SPI_Transmit(&VSSpiHandle, (uint8_t*)buffer, SAFELY_CAN_SEND_BYTES , 500) != HAL_OK)
		{
			return 1;
		}
		Mp3DeselectData();	//xDCS = 1
		toSend -= SAFELY_CAN_SEND_BYTES ;
	}
	return 0;
}
Is there special case if we want to send WAV or WMA file ?
Not really. As long as clocks are high enough (PLL on VS1003 and SPI) I believe that you just set the SM_OUT_OF_WAV to jump out before you even stared to decode. Rest of this post I tried to make your code look nicer. :)
User avatar
pasi
VLSI Staff
Posts: 2167
Joined: Thu 2010-07-15 16:04

Re: PLAY WAV File VS1003B

Post by pasi »

Hannu is correct, you should not be setting SM_OUTOFWAV (SM_CANCEL) during the init.

When any audio decoder sees SM_CANCEL, it stops decoding, clears SM_CANCEL and returns to the main loop. For mp3 it's not critical, because only one frame of decoded audio gets lost, and the next mp3 frame starts the mp3 decoder again. But for other formats that have one header, the decoding will end even before it is started. Your controller will then send the rest of the file and the vs10xx is trying to find anything decodable from that data.

You can see the currently running decoder from HDAT1. If the value is 0, there is no decoding happening.

You should only use SM_CANCEL to cancel decoding when you switch songs (and at the end of tracks) -- but for vs1003b software reset probably works better.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
adria_toa
User
Posts: 9
Joined: Wed 2021-04-14 8:33

Re: PLAY WAV File VS1003B

Post by adria_toa »

Which I modded and removed the stop playing wav bit.

Code: Select all


uint8_t VSInitSoftware()
{
	/*WriteSci(SCI_MODE, SM_SDINEW | SM_OUTOFWAV | SM_RESET ); //|SM_SDISHARE|SM_TESTS|SM_RESET);*/
	WriteSci(SCI_MODE, SM_SDINEW  | SM_RESET ); //|SM_SDISHARE|SM_TESTS|SM_RESET);
	WriteSci(SCI_CLOCKF,
			HZ_TO_SC_FREQ(12288000) | SC_MULT_03_30X | SC_ADD_03_10X);

	/*Set volume level at 0 db (0.5 db Steps) -> ((leftchannelx256)+rightchannel */
	WriteSci(SCI_VOL, 0x0000);	//Full Volume
	//WriteSci(SCI_BASS, 0x0055);
	WriteSci(SCI_DECODE_TIME, 0); //Reset Decode Time

	return 0;
}
Originally I did not use SM_OUTOFWAV. I set SM_OUTOFWAV because after play WAV file then next file is MP3, MP3 file won't play correctly.
Is it correct ?
Which will read one FILE_BUFFER_SIZE of bytes and transmit it. It may not be what you intended. I presume, you opened the AudioFile previously and then called playFile function.
And does your system really give some real object and not just a pointer to a something which could be called as file?

Usually I read files something like this:

Code: Select all

int bytes;
while (1) {
	bytes = fread(buf, 1, BUF_SIZE, fp);
	if (bytes <= 0)break;
	pos += bytes;
	SendSdi(buf, bytes);
	PrintInfoToScreen(pos);
}
With that kind of structure, the infoprint is contrerolled by BUF_SIZE and if you have for example 256 byte buffer, wrap the three first lines inside for-loop and iterate 16 times to get 4096. 4096 would come really fast with wav files. 8 kHz stereo 16-bit would be about 2*2*2 = 8 times in second
Yes i call fopen() function before playfile() function. Thank you for your reference code
Yes my system give real object of file from SDCARD and USB
Which I modded to respect DREQ and the 32 bytes. That way I think, the player function can be simplified.

What is the parameter 500 in HAL_SPI_Trasmit function?

Code: Select all

#define SAFELY_CAN_SEND_BYTES 32
uint8_t SendSDI(uint8_t* buffer, uint8_t size)
{
	int16_t toSend = bytes; /* Signed 16-bit handles case where size > 128 and can go to negative side. */
	Mp3DeselectControl(); //xCS = 1 Is this really needed? Does some function leave XCS down? //[b]Yes you right it's no needed[/b]
	while(toSend > 0) {
		while(!CheckVS1003B_DRQ()); //Check DREQ pin
		Mp3SelectData();	//xDCS = 0
		if(HAL_SPI_Transmit(&VSSpiHandle, (uint8_t*)buffer, SAFELY_CAN_SEND_BYTES , 500) != HAL_OK)
		{
			return 1;
		}
		Mp3DeselectData();	//xDCS = 1
		toSend -= SAFELY_CAN_SEND_BYTES ;
	}
	return 0;
}
500 is timeout parameter (ms) because it's blocking mode. When use DMA mode it doesn't work.
Not really. As long as clocks are high enough (PLL on VS1003 and SPI) I believe that you just set the SM_OUT_OF_WAV to jump out before you even stared to decode. Rest of this post I tried to make your code look nicer. :)
Noted thank you very much
pasi wrote: Wed 2021-04-21 11:06 Hannu is correct, you should not be setting SM_OUTOFWAV (SM_CANCEL) during the init.

When any audio decoder sees SM_CANCEL, it stops decoding, clears SM_CANCEL and returns to the main loop. For mp3 it's not critical, because only one frame of decoded audio gets lost, and the next mp3 frame starts the mp3 decoder again. But for other formats that have one header, the decoding will end even before it is started. Your controller will then send the rest of the file and the vs10xx is trying to find anything decodable from that data.

You can see the currently running decoder from HDAT1. If the value is 0, there is no decoding happening.

You should only use SM_CANCEL to cancel decoding when you switch songs (and at the end of tracks) -- but for vs1003b software reset probably works better.
Noted thank you very much

And one last thing do you have tips/trick how to fast forward or fast backward the mp3/wav/wma file ?
User avatar
pasi
VLSI Staff
Posts: 2167
Joined: Thu 2010-07-15 16:04

Re: PLAY WAV File VS1003B

Post by pasi »

adria_toa wrote: Thu 2021-04-22 6:32Originally I did not use SM_OUTOFWAV. I set SM_OUTOFWAV because after play WAV file then next file is MP3, MP3 file won't play correctly.
Is it correct ?
If you give a software reset between the tracks, it restarts the decoder. The decoder is always looking for something to decode when you start sending the file.
adria_toa wrote: Thu 2021-04-22 6:32And one last thing do you have tips/trick how to fast forward or fast backward the mp3/wav/wma file ?
For mp3 it's very simple -- send some zero-bytes (to make sure the current mp3 frame gets filled), then start sending from the new position. The decoder will look for the next mp3 frame header and resynchronize automatically.

For WAV and WMA in vs1003b rewind / goto is not simple...

For WMA see VS1003b WMA Webcast / Rewind Patch from http://www.vlsi.fi/en/support/software/ ... tches.html .

For WAV you would probably need to modify the "data" chunk size to 0 or 0xffffffff in the wav header you send, then you need to skip a multiple of the (stereo) samples in the data (probably a multiple of 4 bytes, because vs1003 only supports 8-bit and 16-bit mono and stereo formats). Without adjusting the data size the playback would end prematurely when you skip backwards.

Later vs10xx chips also have a "fast play" option.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
adria_toa
User
Posts: 9
Joined: Wed 2021-04-14 8:33

Re: PLAY WAV File VS1003B

Post by adria_toa »

pasi wrote: Wed 2021-04-21 11:06 Hannu is correct, you should not be setting SM_OUTOFWAV (SM_CANCEL) during the init.

When any audio decoder sees SM_CANCEL, it stops decoding, clears SM_CANCEL and returns to the main loop. For mp3 it's not critical, because only one frame of decoded audio gets lost, and the next mp3 frame starts the mp3 decoder again. But for other formats that have one header, the decoding will end even before it is started. Your controller will then send the rest of the file and the vs10xx is trying to find anything decodable from that data.

You can see the currently running decoder from HDAT1. If the value is 0, there is no decoding happening.

You should only use SM_CANCEL to cancel decoding when you switch songs (and at the end of tracks) -- but for vs1003b software reset probably works better.
I have other problem. What cause if playback is sound slower than original ?
I use different MCU now but vs1003 didn't work properly. Playback is slow. But on last MCU I used, vs1003 working perfect for mp3 but still cannot play WAV until now.
I I tried to read HDAT register and its value is 0.
I also tried sinewave test using this data {0x53, 0xEF, 0x6E, 0x24, 0x00, 0x00, 0x00, 0x00} -> 0x24 Freq result is 1 kHz but output its not 1 kHz. Possible hardware failure ??
User avatar
pasi
VLSI Staff
Posts: 2167
Joined: Thu 2010-07-15 16:04

Re: PLAY WAV File VS1003B

Post by pasi »

adria_toa wrote: Fri 2022-01-28 9:59I have other problem. What cause if playback is sound slower than original ?
a) you're sending the data too slowly -- this is the probable cause if you have problems with WAV, but not with other formats like mp3. (Or if you have problems with all files, check your SPI speed and the speed of the data fetch from you storage medium.)
b) you have not set SCI_CLOCKF to high enough multiplier value -- this is the probable cause if WAV is playing, but you have problems with other formats, or just some low-bitrate WMA songs (that use LPC).
c) the crystal is not 12.288MHz and you have not set the CLK part of the SCI_CLOCKF register correctly.
adria_toa wrote: Fri 2022-01-28 9:59I use different MCU now but vs1003 didn't work properly. Playback is slow. But on last MCU I used, vs1003 working perfect for mp3 but still cannot play WAV until now.
Sounds like a).
adria_toa wrote: Fri 2022-01-28 9:59I I tried to read HDAT register and its value is 0.
During decoding they should both be non-zero in vs1003.
adria_toa wrote: Fri 2022-01-28 9:59I also tried sinewave test using this data {0x53, 0xEF, 0x6E, 0x24, 0x00, 0x00, 0x00, 0x00} -> 0x24 Freq result is 1 kHz but output its not 1 kHz. Possible hardware failure ??
Sounds like c).

Which value are you writing to SCI_CLOCKF and what is your crystal value?
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
adria_toa
User
Posts: 9
Joined: Wed 2021-04-14 8:33

Re: PLAY WAV File VS1003B

Post by adria_toa »

pasi wrote: Fri 2022-01-28 10:54
adria_toa wrote: Fri 2022-01-28 9:59I have other problem. What cause if playback is sound slower than original ?
a) you're sending the data too slowly -- this is the probable cause if you have problems with WAV, but not with other formats like mp3. (Or if you have problems with all files, check your SPI speed and the speed of the data fetch from you storage medium.)
b) you have not set SCI_CLOCKF to high enough multiplier value -- this is the probable cause if WAV is playing, but you have problems with other formats, or just some low-bitrate WMA songs (that use LPC).
c) the crystal is not 12.288MHz and you have not set the CLK part of the SCI_CLOCKF register correctly.
adria_toa wrote: Fri 2022-01-28 9:59I use different MCU now but vs1003 didn't work properly. Playback is slow. But on last MCU I used, vs1003 working perfect for mp3 but still cannot play WAV until now.
Sounds like a).
adria_toa wrote: Fri 2022-01-28 9:59I I tried to read HDAT register and its value is 0.
During decoding they should both be non-zero in vs1003.
adria_toa wrote: Fri 2022-01-28 9:59I also tried sinewave test using this data {0x53, 0xEF, 0x6E, 0x24, 0x00, 0x00, 0x00, 0x00} -> 0x24 Freq result is 1 kHz but output its not 1 kHz. Possible hardware failure ??
Sounds like c).

Which value are you writing to SCI_CLOCKF and what is your crystal value?
OK, now I found the problem why MP3 playback hear to slow. AVDD and CVDD are ~ 1.7V. It seem voltage dropped when VS1003 start working. I use serial diode from 5V to generate 2.8 Volt. I should use 2.8 voltage regulator.
Everthing normal now with MP3.

My SCI_CLOCKF value setting

Code: Select all

WriteSci(SCI_CLOCKF,HZ_TO_SC_FREQ(12288000) | SC_MULT_03_30X | SC_ADD_03_10X);
My SPI speed setting is 1 Mbps.
Crystal value is 12.288 MHz
is it not fast enough to play WAV?
User avatar
pasi
VLSI Staff
Posts: 2167
Joined: Thu 2010-07-15 16:04

Re: PLAY WAV File VS1003B

Post by pasi »

adria_toa wrote: Fri 2022-02-04 2:58My SPI speed setting is 1 Mbps.
Crystal value is 12.288 MHz
is it not fast enough to play WAV?
48000kHz 16-bit stereo WAV is 48000*16*2 = 1.536Mbit/sec. And you probably need to fetch the data also for x2, so you'll probably need above 3MHz.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
adria_toa
User
Posts: 9
Joined: Wed 2021-04-14 8:33

Re: PLAY WAV File VS1003B

Post by adria_toa »

pasi wrote: Fri 2022-02-04 11:51
adria_toa wrote: Fri 2022-02-04 2:58My SPI speed setting is 1 Mbps.
Crystal value is 12.288 MHz
is it not fast enough to play WAV?
48000kHz 16-bit stereo WAV is 48000*16*2 = 1.536Mbit/sec. And you probably need to fetch the data also for x2, so you'll probably need above 3MHz.
Thank you. Now WAV is working with bit rate 705.6 kbps (44100 * 16 * 1).
My SPI speed can only set up to 2 MHz (I don't know why).
Post Reply