Gapless looping of files on VS1000

Designing hardware that use VLSI Solution's devices as the system controller for the entire design.
clisystems
User
Posts: 9
Joined: Thu 2015-12-03 23:46

Gapless looping of files on VS1000

Post by clisystems » Thu 2015-12-17 23:46

We are using the VS1000 chip to play OGG files for background sound and we would like to have files play and, when finished, loop back to start. Currently we have a custom application based on the "VS1000 UART Voicemail Software for VS1000 Audio Module" application using the sbfs file system and files on an SPI flash chip. Files can be played, and as soon as the play function returns I seek to the start of the file and play it again.

Code: Select all

while(1){
    switch(m_state){
    ...
    case CSM_STATE_PLAYING:
        cs.Seek(&cs,0,SEEK_SET);
        PlayCurrentFile();
        if(m_loop==0)
        {
            m_state = CSM_STATE_OFF;
            Writeln("O\n");
        }
        break;
    ...
}
This works and loops the file however there is a gap of silence between calls to PlayCurrentFile(). Even if I do the following, no other commands between the PlayCurrentFile() calls, there is still a gap

Code: Select all

cs.Seek(&cs,0,SEEK_SET);
PlayCurrentFile();
cs.Seek(&cs,0,SEEK_SET);
PlayCurrentFile();
First, is using seek the best way to start to play the file again? Setting goto=-1 did not start the file again

I would also like to know, what is causing the gap? I don't have the player code (I don't know if you even release it) so I don't know what is going on behind the scenes, Is it a read from the SPI? Is there any way to "preload" the beginning of the file to decrease this gap?

Finally, I noticed a #define GAPLESS in the Audio Module code, is there any way to implement gapless in the Voicemail application?

Thank you

User avatar
pasi
VLSI Staff
Posts: 1466
Joined: Thu 2010-07-15 16:04

Re: Gapless looping of files on VS1000

Post by pasi » Fri 2015-12-18 12:50

The ROM version of PlayCurrentFile() sends zero samples after each file in case EarSpeaker has been active. You can replace it with PlayCurrentFileFast(), which doesn't add zero samples, or PatchPlayCurrentFile(), which patches a small bug in the Ogg Vorbis decoder at the same time. (See dev1000.h .)

Each Ogg Vorbis file contains a header, which contains the information about decoding tables. It takes quite a while to process that into a format that can be used during decoding. Also, the first decoded audio frame does not generate any output, it is only used to fill the history for the overlap-add part of the transform.

So, the decoder needs to create the decoding tables and decode two full audio frames before the first audio sample can be output.

The GAPLESS code in the vs1000 audio module gets around this by checking the size of the header. If it matches, the encoding parameters are (assumed to be) the same. A few variables and structures are modified to skip the processing of the header - the decoding tables are already ready.

You should be able to port the GAPLESS code (be sure to copy all pieces) to the voicemail firmware, although I'm not sure whether it will fit into the memory without removing something else.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

clisystems
User
Posts: 9
Joined: Thu 2015-12-03 23:46

Re: Gapless looping of files on VS1000

Post by clisystems » Thu 2016-01-07 22:19

Pasi,

Thank you for the info. I am having a bit of trouble determining where these functions are and how one can modify the player code and buid it. It seems that the VS1000 libraries are binaries and the source is not distributed, is that correct?

I have included dev1000.h to include the PlayCurrentFileFast() function however the compiler can't find the object file for that function.

Can the original PlayCurrentFile() be removed from the build to save space?

Were is the GAPLESS code located in the module project?

Thank you,

Drew

clisystems
User
Posts: 9
Joined: Thu 2015-12-03 23:46

Re: Gapless looping of files on VS1000

Post by clisystems » Thu 2016-01-07 23:54

Ok, I see that there are a few shared libraries in the libvs1000 directory. I added -ldev1000 to the linker commands in the IDE and was able to link in the PlayCurrentFileFast() function. The files now play MUCH quicker, with only a few ms gap between plays.

I would still like to know where the GAPLESS code is in the Module example and how I can update my code to skip the header if it is the same as the previous run.

Thank you,

Drew

User avatar
pasi
VLSI Staff
Posts: 1466
Joined: Thu 2010-07-15 16:04

Re: Gapless looping of files on VS1000

Post by pasi » Fri 2016-01-08 15:28

See the (Gapless) NAND Player package from http://www.vlsi.fi/en/support/software/ ... tions.html .

Also see VS1000AudioModule-072-VSIDE.zip .

The Gapless code itself is not specific to storage. You can find the relevant parts between #ifndef GAPLESS and #endif /*GAPLESS*/ preprocessor definitions.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

bLG
User
Posts: 11
Joined: Tue 2016-06-07 23:02

Re: Gapless looping of files on VS1000

Post by bLG » Tue 2016-06-07 23:19

Hi,
I am now working on this particular project too (Drew has other projects now). Our files are 16bit .ogg, 44.1kHz.

With gapless audio properly implemented is a 30ms gap still to be expected when repeating a file due to handling of the first audio frame? Is the same result expected when playing a series of files? Lastly, is there anything special that needs to be implemented in the headers of the files that is required?

Thanks in advance,
David

User avatar
pasi
VLSI Staff
Posts: 1466
Joined: Thu 2010-07-15 16:04

Re: Gapless looping of files on VS1000

Post by pasi » Wed 2016-06-08 14:50

I would expect a much shorter gap when the GAPLESS code is enabled, but it has been a long time since I worked on that code. Check that there are no UART printouts that could block the execution. The gapless option in the audio module firmware does not print the whole filename.

As long as the Ogg Vorbis files have been encoded with the same profile (same samplerate and same quality setting), the gapless code should be able to just skip from one file to the next without rebuilding the decoding Huffman trees and other decoding structures.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

bLG
User
Posts: 11
Joined: Tue 2016-06-07 23:02

Re: Gapless looping of files on VS1000

Post by bLG » Wed 2016-06-08 23:15

Thanks for the advice. We are not using UART printout function.
A few more questions. What is the shortest gap we should hope to achive in ms for GAPLESS ogg? We observe the 30ms gap for repeating the same .ogg file or playing two files sequentially. Does that makes sense to you?

Lastly, the issue I have is that I am repeating a cyclical sound file. The gap is much more noticeable because of the steady state nature of my sound file. Any thoughts on using a very short .wav file instead of .ogg and repeat that instead? Just wondering if file format change could prove useful as we seek a practical solution.

Thanks again,
David

User avatar
pasi
VLSI Staff
Posts: 1466
Joined: Thu 2010-07-15 16:04

Re: Gapless looping of files on VS1000

Post by pasi » Thu 2016-06-09 11:45

See the attached sdplayer.c . It contains a loop option which you could try and also WAV option with or without gapless/loop.

How long is the looped fragment? If it is too short, the decoder needs to decode upto three times the samples.

Normally Ogg Vorbis plays the exact number of samples. OggGranulePatch disables granule check, and as a side effect causes all samples from the last frame to be played (instead of just the correct number), but I don't think it is used in any of the generic codes.

Also remember to LoadCheck(NULL,0); to switch to the highest clock, or if you use a fixed clock, try 3.5x clock instead of 3.0x. (UartLoadCheck, change the two instances of 6 to 7.)
Attachments
sdplayer.c
example sdplayer with gapless and looping
(43.68 KiB) Downloaded 90 times
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

bLG
User
Posts: 11
Joined: Tue 2016-06-07 23:02

Re: Gapless looping of files on VS1000

Post by bLG » Mon 2016-06-13 15:45

My looped fragment is 1 min long .ogg file. This is a stereo noise signal with a delay of 100ms between the channels to make certain that the sound produced is non-correlated. I could certainly drop the length of my loop down significantly and use a .wav file if gapless .wav would have better performance than gapless .ogg.

In gapless .ogg, you mentioned that 30ms gap seems like too much. What gap length would you expect with optimized code?

I will try the sdplayer code you sent and revert back with my findings.

Thank you,
David

Post Reply