Ogg-Vorbis audio file duration

Writing software for systems that use VLSI Solution's devices as slave codecs to a host microcontroller.
Post Reply
roy
User
Posts: 3
Joined: Thu 2018-05-10 16:21

Ogg-Vorbis audio file duration

Post by roy » Thu 2018-05-10 16:24

I am using the VS1053 to decode ogg files. I need to know the duration of the recording. It there a way I can determine it with the VS1053 short of playing it back and timing it?

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

Re: Ogg-Vorbis audio file duration

Post by pasi » Mon 2018-05-14 9:41

You would need to determine the size with your controller.

You would:
1. determine the sample rate from the headers
2. seek to the end of the file, and locate the last Ogg Vorbis header (usually in the last 8kB of file) and get the sample number (granule position)
3. calculate the duration from the sample number and the sample rate.

The following is VS1000 code to determine the play time for an already opened file. Maybe it will be of some help developing your own. The vs1000 code reads 8-bit bytes to 16-bit words, so it is a bit more complicated than needed. I need two compare loops to search for "OggS".

Code: Select all

/*
  The file has to be open when PlayTimeFile is called.
 */
u_int32 PlayTimeFile(void) {
    register int i;
//    u_int32 pos = Tell(); /* We assume it is 0 */
    __mem_y u_int32 sample = 0;
    u_int32 rate;
    register u_int16 *p;
    int last = 0;

    /* Find rate */
    Seek(0x28); /* Depend on samplerate being always at this offset. */
    ReadFile(mallocAreaX, 0, 4);
    rate = SwapWord(mallocAreaX[0]);//|((u_int32)SwapWord(mallocAreaX[1])<<16);

    /* First seek word-aligned */
    Seek(minifatInfo.fileSize-8192);
    ReadFile(mallocAreaX, 0, 8192);
    p = mallocAreaX;
    for (i=0;i<4096-5;i++) {
        if (p[0] == (('O'<<8)|'g') && p[1] == (('g'<<8)|'S')) {
            last = i;
            /* granuleposition gives the last sample number in this Ogg frame.
               We only read 32 bits of the position, which corresponds
               to 24 hours 51 minutes of 48kHz audio. */
            sample = SwapWord(p[3]) | ((u_int32)SwapWord(p[4]) << 16);
        }
        p++;
    }
    /* Seek non-word-aligned from the last aligned position forward */
    Seek(minifatInfo.fileSize-8191);
    ReadFile(mallocAreaX, 0, 8191);
    p = mallocAreaX;
    for (i=last;i<4096-5;i++) {
        if (p[0] == (('O'<<8)|'g') && p[1] == (('g'<<8)|'S')) {
            sample = SwapWord(p[3]) | ((u_int32)SwapWord(p[4]) << 16);
        }
        p++;
    }
//    Seek(pos); /*We assume it is 0*/
    Seek(0);
    return sample / rate; /* in seconds -- change or scale if you need to.*/
}
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

Post Reply