Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Music.openFromStream fails (Recreated on both Windows and Linux)  (Read 8633 times)

0 Members and 1 Guest are viewing this topic.

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
#include <SFML/Audio.hpp>
#include <SFML/System/FileInputStream.hpp>
#include <iostream>
#include <cstdio>

int main() {
    std::cout << "Starting..." << std::endl;
    sf::Music fileMusic;
    if (!fileMusic.openFromFile("sample.ogg")) {
        std::cerr << "Too early boom?"  << std::endl;
        return 3;
    }

    sf::Music music;
    sf::FileInputStream stream;
    if (!stream.open("sample.ogg")) {
        std::cerr << "Too early boom?"  << std::endl;
        return 2;
    }
    if (!music.openFromStream(stream)) {
        std::cerr << "BOOM!"  << std::endl;
        return 1;
    }
    std::cout << "Done" << std::endl;
    return 0;
}

 

sample.ogg is orchestra.ogg from the examples folder.

Loading from a file works, but trying to load music from an InputStream seems to fail. Am I doing something wrong, or has this broken on master? This used to work until I updated to the latest master.
« Last Edit: March 12, 2015, 09:22:30 am by MorleyDev »
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Music.openFromStream fails: Failed to set 44100hz, got 48000hz
« Reply #1 on: March 11, 2015, 09:55:34 pm »
A big chunk of the audio module has been changed to remove libsndfile as such there might well be an issue on the current master.

Can you provide the ogg file?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Re: Music.openFromStream fails: Failed to set 44100hz, got 48000hz
« Reply #2 on: March 11, 2015, 09:56:22 pm »
Well the majority of the audio module has been rewritten to remove libsndfile as such there might well be an issue on the current master.

Can you provide the ogg file?

It's orchestra.ogg from the sound example in the SFML examples folder, though I can recreate it by converting to an MP3 file as well, and in the code that I found this issue in originally WAV files from loading SoundEffects from a stream also falls down.

Porting to a FLAC file via Audacity, interestingly, does seem to work. So this stands as a temporary fix for me, but obviously not ideal.

Commenting out the openFromStream logic logs:
Quote

Starting...
AL lib: (EE) UpdateDeviceParams: Failed to set 44100hz, got 48000hz instead
AL lib: (EE) GetHrtf: Incompatible format: Stereo 48000hz
Done

And the AL lib stuff still gets logged if commenting out the stream loading, so I suspect it's a red-herring and it's the stream reading logic that falls down (Graphics still load from streams correctly).
« Last Edit: March 11, 2015, 10:45:52 pm by MorleyDev »
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Sorry to double post but to add more to the current state of Audio playing:
So FLAC files can play from a stream, but they do not loop successfully. Changing the above code to setLoop(true) and call .play() results in music playing once and never looping, and the exiting of the application to hang on exit.

Hitting CTRL+C results in "AL lib: (EE) alc_cleanup: 1 device not closed" being logged.

Calling getStatus() on the music file still reports a status of sf::Sound::Playing

The above applies to both openFromStream and openFromFile music.
« Last Edit: March 11, 2015, 11:06:42 pm by MorleyDev »
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
FLAC streams in master have an issue.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
FLAC streams in master have an issue.

So that's an unrelated issue, good to know.

Btw I've tried the openFromStream on Ubuntu with the orchestra.ogg and I get the same error so...yeah, github issue time? :) Using streams instead of files is a fairly common usecase I reckon, since it lets you write a generic file loader that can abstract away reading from zip files and file files.
« Last Edit: March 11, 2015, 11:52:31 pm by MorleyDev »
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Quote
so...yeah, github issue time?
I don't think so... you should have waited for our answer ;)

Now everything internally uses streams, so openFromFile and the others all use the same stream-based implementation. If your stream doesn't work, I'd say check its implementation first. You can compare it to the new FileInputStream class of SFML (which works, if openFromFile works):
https://github.com/SFML/SFML/blob/master/src/SFML/System/FileInputStream.cpp

And by the way, OpenAL logs are unlikely to be related to what we changed in the management of sound files -- we didn't touch playback at all. Are you sure that you didn't get an OpenAL update recently?
« Last Edit: March 12, 2015, 08:22:24 am by Laurent »
Laurent Gomila - SFML developer

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Ah fair enough :) Sorry, still unsure on proper protocol with github issues but you're right, should of waited ^^

The InputStream in the original example was taken from http://www.sfml-dev.org/tutorials/2.2/system-stream.php, but I updated the code above to use sf::FileInputStream and re-ran it. Still goes "BOOM!", so the internal openFromStream implementation falls own on something the openFromFile does not.

This used to work perfectly and still does for images, and (known issue aside) FLAC files. I haven't touched this part of the code, updating SFML to a new build of master broke what was previously working. And this happens on both Windows and Linux for me.
« Last Edit: March 12, 2015, 09:38:01 am by MorleyDev »
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Music.openFromStream fails (Recreated on both Windows and Linux)
« Reply #8 on: March 12, 2015, 09:46:55 am »
So far I've narrowed it down to ov_test_callback which returns OV_ENOTVORBIS (Bitstream contains no Vorbis data).

I'm not sure how one would now validate that the data from the stream is valid/invalid...

One difference I noticed is, that when calling stream.tell() within the SoundFileReaderOgg::check(InputStream& stream) function, it will report different values for sf::Music file and sf::FileInputStream.

(sf::Music)
size: 153776
tell: 0

size: 153776
tell: 4096
err: 0

(sf::FileInputStream)
size: 153776
tell: 8192

size: 153776
tell: 18432
err: -132

Modification:
bool SoundFileReaderOgg::check(InputStream& stream)
{
    OggVorbis_File file;
        sf::err() << "size: " << stream.getSize() << "\ntell: " << stream.tell() << "\n\n";
    int check = ov_test_callbacks(&stream, &file, NULL, 0, callbacks);
    sf::err() << "size: " << stream.getSize() << "\ntell: " << stream.tell() << "\nerr: " << check << "\n\n";
    if (check == 0)
    {
        ov_clear(&file);
        return true;
    }
    else
    {
        return false;
    }
}

So to me it seems that ov_test_callbacks isn't reading from the start or similar...
« Last Edit: March 12, 2015, 10:13:02 am by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Music.openFromStream fails (Recreated on both Windows and Linux)
« Reply #9 on: March 12, 2015, 10:17:59 am »
It's indeed an issue in SFML.

In SoundFileFactory.cpp:
SoundFileReader* SoundFileFactory::createReaderFromStream(InputStream& stream)
{
    // Register the built-in readers/writers on first call
    ensureDefaultReadersWritersRegistered();

    // Test the filename in all the registered factories
    for (ReaderFactoryArray::const_iterator it = s_readers.begin(); it != s_readers.end(); ++it)
    {
        if (it->check(stream))
            return it->create();
    }

    // No suitable reader found
    return NULL;
}

Should be:
SoundFileReader* SoundFileFactory::createReaderFromStream(InputStream& stream)
{
    // Register the built-in readers/writers on first call
    ensureDefaultReadersWritersRegistered();

    // Test the stream for all the registered factories
    for (ReaderFactoryArray::const_iterator it = s_readers.begin(); it != s_readers.end(); ++it)
    {
        stream.seek(0);
        if (it->check(stream))
            return it->create();
    }

    // No suitable reader found
    return NULL;
}
« Last Edit: March 12, 2015, 10:20:36 am by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/