Page 1 of 1

Playing Vorbis produces some noise [SOLVED]

Posted: Thu Oct 26, 2017 11:14 am
by Mel
I am trying to playback some OGG files. I get the setup done (I'm using XAUDIO2, and I play WAVS just fine) , but when i play vorbis the decoded sound isn't nearly as good as it should be. It plays with noise, as if had decoding problems, at the correct speed, but doesn't sound as good as it should. Anybody has had any similar problems? i guess OpenAL works the same, submitting buffers, i get the buffers, but the buffers doesn't seem to be good. Any ideas? Thanks :)

Re: Playing Vorbis produces some noise

Posted: Thu Oct 26, 2017 1:28 pm
by hendu
a) you're using a vorbis library compiled for fixed point and low precision
b) something else is wrong

Dump the buffers to a file and play in audacity to check.

Re: Playing Vorbis produces some noise

Posted: Thu Oct 26, 2017 2:07 pm
by Mel
I got the library from Xiph.org (https://www.xiph.org/downloads/) and I've messed enough with it to make sure there is something else wrong, thus i was asking if somebody else got similar problems. I'm streaming from the memory, with all the proper setup, and all i do is call ov_read to get a buffer uncompressed, and pass it back to XAUDIO2, via submitBuffers, uses the same approach with WAVs, and these play just fine. I've tried filling a larger buffer, and the same, and all the ogg files i've tested show the same problems. They sound, but they don't sound well.

this is the decoding code:

Code: Select all

 
        void* COggVorbisSoundSource::getFrame(const u32 frame, u32& dataLength)
        {
            dataLength = ov_read(&vorbisFile, transferBuffer, BUFFER_SIZE, 0, 2, 1, nullptr);
            return transferBuffer;
        }
 
This is the playing code:

Code: Select all

 
        bool CWin32XAudio2Sound::play()
        {
            u8* buffer = nullptr;
            u32 length;
 
            if (!isPaused)
            {
                XAUDIO2_VOICE_STATE state;
                soundVoice->GetState(&state);
 
                if (state.BuffersQueued <= 1) //to avoid saturation
                {
                    //feeds one frame
                    buffer = (u8*)soundSource->getFrame(currentFrame, length);
                    
                    ++currentFrame;//pronto no importara...
                    ended = isLoop ? false : currentFrame >= soundSource->getFrameCount();
 
                    if (isLoop && currentFrame >= soundSource->getFrameCount())
                        currentFrame = 0;
 
                    if (buffer)
                    {
                        XAUDIO2_BUFFER buff = {};
                        buff.AudioBytes = (u32)length;
                        buff.Flags = ended ? XAUDIO2_END_OF_STREAM : 0;
                        buff.pAudioData = buffer;
                        soundVoice->SubmitSourceBuffer(&buff);
                        if (state.BuffersQueued == 1)
                            soundVoice->Start();
                    }
                }
            }
            return (buffer != nullptr) & (!isPaused);
        }
 
and the setup I use for reading is this:

Code: Select all

 
        size_t COggVorbisSoundSource::read(void* ptr, size_t size, size_t nmemb, void* datasource)
        {
            if (datasource == nullptr)
                return 0;
            readerData* reader = (readerData*)datasource;
 
            const s8* readerPointer = (s8*)reader->file + reader->fileIndex;
            const size_t fileSize = reader->fileSize;
            const size_t fileRemainder = reader->fileSize - reader->fileIndex;
            size_t correctRead = size*nmemb;
            
            if (correctRead > fileRemainder)
                correctRead = fileRemainder;
 
            memcpy(ptr, readerPointer, correctRead);
            
            reader->fileIndex += correctRead;
            
            return correctRead;
        }
 

Code: Select all

 
        int COggVorbisSoundSource::seek(void* datasource, ogg_int64_t offset, int whence)
        {
            if (datasource == nullptr)
                return 0;
            readerData* reader = (readerData*)datasource;
            const Size fileSize = reader->fileSize;
 
            switch (whence)
            {
            case SEEK_SET:
                reader->fileIndex = offset;
                break;
            case SEEK_CUR:
                reader->fileIndex += offset;
                break;
            case SEEK_END:
                reader->fileIndex = fileSize + offset;
                break;
            }
 
            return (int)(reader->fileIndex);
        }
 

Code: Select all

 
        int COggVorbisSoundSource::close(void* datasource)
        {
            if (datasource == nullptr)
                return 0;
            readerData* reader = (readerData*)datasource;
            reader->fileIndex = 0;
            return 0;
        }
 

Code: Select all

 
        long COggVorbisSoundSource::tell(void* datasource)
        {
            if (datasource == nullptr)
                return 0;
            readerData* reader = (readerData*)datasource;
            return (long)(reader->fileIndex);
        }
 
Maybe a compile setting i might be forgetting so the libVorbis uses more precission? I really don't know :/

Re: Playing Vorbis produces some noise

Posted: Thu Oct 26, 2017 2:43 pm
by MartinVee
Do you playback at 48000 khz? If so, try it at 44100 khz.

Re: Playing Vorbis produces some noise

Posted: Thu Oct 26, 2017 10:34 pm
by CuteAlien
Do you do other stuff as well? Maybe you don't manage to fill your buffer often enough (too large pauses between calls of play()). You can experiment by doing less other stuff or maybe also by increasing the buffer (not sure what's the max for an audio-buffer really...).

Re: Playing Vorbis produces some noise

Posted: Fri Oct 27, 2017 12:41 am
by Mel
No, I take the rate and the channels from the file, so, it is correct, it plays at 44100Hz. I've changed the samples settings as well, and i only get either slower or faster playing, but the noise is also slown down (or sped up!)

And no, there is a sound worker is in its own thread, playing all the sounds, each sound uses a very light amount of data only 4096 bytes each, so it can do it very often with no impact in performance. reducing this buffer only makes things worse, so it is in the tightest, lowest limit. Vorbis will only fill up to 4096 bytes buffers, so it doesn't seem to be a buffer issue. The sound plays, besides the noise, as if it was a tape which has been played too often, scratched. I'm starting to believe it is a compiler issue, in the code, the vorbis folks use way too often the scopes to place local variables whose names are the same as variables outside of the scopes, and that behavior is on a compiler basis (GCC will produce one result, MSVC will produce other... ) so, well, i don't know. Have you compiled the vorbis codec from its sources any time?

Re: Playing Vorbis produces some noise

Posted: Fri Oct 27, 2017 9:51 am
by hendu
Did you dump the buffers to check?

Re: Playing Vorbis produces some noise

Posted: Fri Oct 27, 2017 2:24 pm
by Mel
I've just dumped the file into memory and plays perfectly even with my own setup.

I've just realized something. ov_read will never provide a buffer larger than 4KB, but will produce buffers as small as 512 bytes, and smaller buffers tended to worsen the problem, but i sent them out as they were none the less. XAUDIO2 can't play very small buffers (512-4096 bytes) properly. Go figure... I'll have to prepare a bigger buffer to transfer then. Interesting! thanks for your help! :)

Image