[vorbis-dev] Decompression error with two streams.

Lars Brubaker lbb at reflexive.net
Thu Feb 22 19:31:03 PST 2001



> -----Original Message-----
> From: owner-vorbis-dev at xiph.org [mailto:owner-vorbis-dev at xiph.org]On
> Behalf Of Dave Hooper
> Sent: Thursday, February 22, 2001 11:08 AM
> To: vorbis-dev at xiph.org
> Subject: Re: [vorbis-dev] Decompression error with two streams.
>
>
> This doesn't immediately sound like a Vorbis decoding error - perhaps a
> problem with the state being maintained of each stream; or a problem with
> the way the streams are being sent to the audio output device?  Could you
> post the code you are using to play these two streams?
> D

Thanks for taking the time to look at this.

Below is the code that is interfacing with Vorbis.  The rest of the code is
shared across all types of sounds and works perfectly when decompressing
.raw and .wav files.  I am using ov_open_callbacks to make the vorbis
decompresser use the same file interface that is used when .raw's and .wav's
are present rather than .ogg's.  The code has never (in 3 years that I've
been using it) made this sound while playing multiple streamed sound files.

Lars.

ize_t COggSoundReader::OggFileCallbackRead(void *ptr, size_t size, size_t
nmemb, void *datasource)
{
        COggSoundReader* pOggSoundReader = (COggSoundReader*)datasource;
        return (pOggSoundReader->m_pFile->Read(ptr, size * nmemb) / size);
}

int COggSoundReader::OggFileCallbackSeek(void *datasource, ogg_int64_t
offset, int whence)
{
        COggSoundReader* pOggSoundReader = (COggSoundReader*)datasource;
        switch(whence)
        {
        case SEEK_SET:
                return pOggSoundReader->m_pFile->SeekAbsolute((long)offset);

        case SEEK_CUR:
                return pOggSoundReader->m_pFile->SeekRelative((long)offset);

        case SEEK_END:
                return
pOggSoundReader->m_pFile->SeekAbsolute(pOggSoundReader->m_pFile->GetLength()
);

        default:
                assert(0);  // not implemented
        }

        return 0;
}

int COggSoundReader::OggFileCallbackClose(void *datasource)
{
        COggSoundReader* pOggSoundReader = (COggSoundReader*)datasource;
        pOggSoundReader->m_pFile->Close();
        return true;
}

long COggSoundReader::OggFileCallbackTell(void *datasource)
{
        COggSoundReader* pOggSoundReader = (COggSoundReader*)datasource;
        return pOggSoundReader->m_pFile->GetPosition();
}

tatic ov_callbacks OggSoundCallBacks;

COggSoundReader::COggSoundReader()
{
        m_IsOpen = false;
        m_IsReading = false;
        m_pOggVorbis_File = new OggVorbis_File; // they have some allocation
problems

        if(!OggSoundCallBacks.close_func)
        {
                OggSoundCallBacks.close_func = OggFileCallbackClose;
                OggSoundCallBacks.read_func = OggFileCallbackRead;
                OggSoundCallBacks.seek_func = OggFileCallbackSeek;
                OggSoundCallBacks.tell_func = OggFileCallbackTell;
        }
}

ulong COggSoundReader::Read(Byte* pDest, ulong
NumUncompressedBytesRequested)
{
        //Sleep(10); // let's sleep for 10 mili seconds (1/100 of a second) and try
again
        if(!m_IsReading)
        {
                m_IsReading = true;
                int current_section;

                bool ReadMoreDataOrRetry = true; // set it to true so we can get into our
while loop.
                long NumBytesRead = 0;

                bool EndOffFile = false;
                uint NumRetries = 0;
                while(!EndOffFile && NumBytesRead < (long)NumUncompressedBytesRequested &&
ReadMoreDataOrRetry && NumRetries < 20)
                {
                        ReadMoreDataOrRetry = false;
                        static long MaxBytesRead =  0;
                        //ulong CurTick = GetSystemTickCount();
                        long ByteReadThisTime = ov_read(m_pOggVorbis_File,
(char*)&pDest[NumBytesRead], min((int)NumUncompressedBytesRequested -
(int)NumBytesRead, (int)4096), 0, 2, 1, &current_section);
                        //ulong NumTicks = GetSystemTickCount() - CurTick;
                        //NumSecodsReadingOggSound += (float)NumTicks / (float)TICKS_PER_SEC;
                        switch(ByteReadThisTime)
                        {
                        case 0:
                                EndOffFile = true;
                                break;

                        case OV_EBADLINK:
                                // indicates that an invalid stream section was supplied to
libvorbisfile, or the requested
                                // link is corrupt.
                                assert(0); // I would like to see this, Lars.
                                break;

                        case OV_HOLE:
                                // indicates there was an interruption in the data.
                                // (one of: garbage between pages, loss of sync followed by recapture,
or a corrupt page)
                                // we can safely try again (so says Monty)
                                ByteReadThisTime = 0;
                                ReadMoreDataOrRetry = true;  // so that we try to read this again
                                NumRetries++;
                                break;

                        default:
                                // indicates actual number of bytes read. Within a logical bitstream,
the number should equal length. At the end of a logical bitstream, the
number of bytes read will equal the remaining number of bytes in the
bitstream.
                                if(ByteReadThisTime > 0)
                                {
                                        NumBytesRead += ByteReadThisTime;
                                        ReadMoreDataOrRetry = true;  // so that we try to read this again
                                }
                                else
                                {
                                        ByteReadThisTime = 0;
                                        ReadMoreDataOrRetry = true;  // so that we try to read this again
                                        NumRetries++;
                                        assert(0);
                                }
                        }

                        MaxBytesRead = (uint)max(ByteReadThisTime, MaxBytesRead);
                }

                m_IsReading = false;
                return NumBytesRead;
        }
        else
        {
                assert(0); // please let me know if this happens, Lars.
        }

        return 0;
}

bool COggSoundReader::Open(CFile* pFile)
{
        Close();
        m_pFile = pFile;

        //ulong CurTick = GetSystemTickCount();
        if(m_pFile && ov_open_callbacks(this, m_pOggVorbis_File, 0, 0,
OggSoundCallBacks))
        {
                // if(ov_open(stdin, &vf, NULL, 0) < 0)
                assert(0);
                DebugStream("Input does not appear to be an Ogg bitstream.\n");
                return false;
        }

        // in case we want to read the user coments
        // char **ppUserComments =
ov_comment(m_pOggVorbis_File, -1)->user_comments;

        // read in the info about the stream
        vorbis_info* pVorbisInfo = ov_info(m_pOggVorbis_File, -1);

        // * 2 because it is 16 bit (this is a valid assumption with vorbis beta 3)
        m_UncompressedDataSize = (ulong)ov_pcm_total(m_pOggVorbis_File, -1) *
pVorbisInfo->channels * 2;
        m_CompressedDataSize = m_pFile->GetLength();

        m_pFormatInfo = (CWaveFormatEx*) new Byte[sizeof(CWaveFormatEx)];
        memset(m_pFormatInfo, 0, sizeof (CWaveFormatEx));

        m_pFormatInfo->wFormatTag = REFLEX_WAVE_FORMAT_PCM;
        m_pFormatInfo->nChannels = (ushort)pVorbisInfo->channels;
        m_pFormatInfo->nSamplesPerSec = pVorbisInfo->rate;
        m_pFormatInfo->wBitsPerSample = 16;
        m_pFormatInfo->nBlockAlign = (ushort) (m_pFormatInfo->wBitsPerSample *
m_pFormatInfo->nChannels / 8);
        m_pFormatInfo->nAvgBytesPerSec = m_pFormatInfo->nSamplesPerSec *
m_pFormatInfo->nBlockAlign;

        m_IsOpen = true;

        //ulong NumTicks = GetSystemTickCount() - CurTick;
        //NumSecodsReadingOggSound += (float)NumTicks / (float)TICKS_PER_SEC;
        return true;
}
> ----- Original Message -----
> From: "Lars Brubaker" <lbb at reflexive.net>
> To: <vorbis-dev at xiph.org>
> Sent: Thursday, February 22, 2001 7:00 PM
> Subject: [vorbis-dev] Decompression error with two streams.
>
>
> > I reported this earlier and just want to state that it is still
> happening
> > in beta 4 as of 2-20-01.  I'm decompressing two streamed sounds
> (there are
> > two vorbis files open at the same time, I used ov_open_callbacks to open
> > both files) and the second is getting a high pitched 1/2 second error in
> > it every 4-5 minutes.  This has been happening since beta 3 for me.
> > However, there is a slight change in the behavior with beta 4,
> it seems to
> > be happening less often (used to be about every 2 minuets) and at least
> 1/2
> > the time the sound is silence rather than a high pitched squeal.
> >
> > * This only happens on the second streaming sound.
> > * This only happens when playing two sounds.
> > * Vorbis reports no errors during playback (the ov_read call is always
> >   reporting a good read).
> > * I have verified that the read is never being called reentrantly.
> >
> > If anyone knows how this could be happening it would be unbelievably
> > appreciated.
> >
> > Lars.
>
>
>
> --- >8 ----
> List archives:  http://www.xiph.org/archives/
> Ogg project homepage: http://www.xiph.org/ogg/
> To unsubscribe from this list, send a message to
> 'vorbis-dev-request at xiph.org'
> containing only the word 'unsubscribe' in the body.  No subject is needed.
> Unsubscribe messages sent to the list will be ignored/filtered.
>

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'vorbis-dev-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the Vorbis-dev mailing list