I would like to somehow convince FMOD to not scan/probe (near) end of the file OGG/Vorbis file while opening it -
it seems to be doing this starting backwards from end of the file towards beginning until it finds a valid frame (or so it hopes)-
after probing few of them ( based on (blockalign…) parameters ) it just gives up failing to recognize format despite the download/filesystem having enough data to start the playback at that point
Is this possible/supported in general for Vorbis codec ?
I have a custom filesystem set which retrieves encoded data progressively outside of FMOD and I try to playSound while download is in progress -
I tried few things, but everything seems to be failing for Vorbis files. - An MPEG with the very same setup plays without problems, however.
The files contain album artworks so I tried rather large blockalign buffers and initial downloads, OPENONLY/IGNORETAGS flags combinations, but everything seems to be successfully ignored X)
I’d be fine if this would not be possible at all, but I’d like to have confirmation if it’s indeed the case.
You can specify a suggestedsoundtype in the FMOD_CREATESOUNDEXINFO to tell FMOD to try to open as Ogg first though, otherwise it will scan around the file trying to figure it out.
Thank you for reply !
I should have mentioned this in OP, but I’m setting suggestedsoundtype already
It seems to be either ignored, or not behaving correctly though:
there are one/few initial scans starting backwards from supposed end of the file and after few failed attempts it looks like FMOD plays (few) ‘blockalign’ sized frame/s, then stops.
More precisely with e.g. 12MB OGG file if ‘blockalign’ is somewhat reasonable (say 16-64 kB) there are usually couple failed reads, then a single (correctly from start) frame is played, then it stops,
if ‘blockalign’ is left default (2048) FMOD tries to scan all the way until it hits valid data (probably hundreds of failes attempts for file of this size), then it plays a few starting frames and then stops.
Both files tested have non trivially sized tags at the beginning I think
The (obvious) workaround atm is to set ‘blockalign’ size at least to the size of the file - that way the ‘initial’ read frame covers the whole file which is acceptable for playback apparently ) - while no ideal it might be passable workaround for now though.
little update: while testing with NONBLOCKING opening after couple of failed reads from the end getOpenState returns ERR_FORMAT (after e.g. one LOADING state)
normal (blocking) open - used originally - depending on ‘blockalign’ size either plays first few frames, or ERR_FORMAT on createSound
so this seems to be probably consistent with FMOD trying to determine the format despite having suggestedtype set to OGGVORBIS
while using sync version of file system API, the seek position never seems to be advancing after failed read from the end, too (is reset to 0 and then never called again)
So at this point Im not sure how to proceed/if it’s possible to prevent reads near EOF at open time when media is not fully downloaded / available yet
I would like to - is a project approval needed to be able to upload files ?
otherwise I can’t see a way of uploading stuff in my profile, and the project I tried to register is pending for approval still
By using the FMOD.MODE.IGNORETAGS flag you can make FMOD not seek to the end, but unfortunately it appears that the oggvorbis codec wants to seek to the end internally. From what we can see, there does not appear to be a way around this at the moment.
FMOD itself can play Vorbis netstreams, e.g. this works (complete working snippet, with default parameters):
`
FMOD.System system;
FMOD.Sound sound;
FMOD.Channel channel;
var result = FMOD.Factory.System_Create(out system);
FMOD.INITFLAGS flags = FMOD.INITFLAGS.NORMAL;
result = system.init(100, flags, IntPtr.Zero);
FMOD.MODE mode = FMOD.MODE.CREATESTREAM;
var extInfo = new FMOD.CREATESOUNDEXINFO();
extInfo.cbsize = Marshal.SizeOf(typeof(FMOD.CREATESOUNDEXINFO));
result = system.createSound("http://allstream.rainwave.cc:8000/all.ogg", mode, ref extInfo, out sound);
FMOD.ChannelGroup master;
result = system.getMasterChannelGroup(out master);
result = system.playSound(sound, master, false, out channel);
`
(error checking omitted for brevity as well as sound release…)
However, as soon as I plug in a custom filesystem it can’t - with behavior which initiated original question.
While testing this with non blocking sound creation (which is prob. the only way of capturing original error state really) I noticed that posted code/url goes through ‘CONNECTING’, ‘BUFFERING’, ‘READY’ phases of getOpenState, whereas with custom filesystem it’s stuck in ‘LOADING’ phase -
which lead me to question if there is something different that FMOD does internally for streamed sounds which I can’t properly emulate with filesystem ?
It’s possible that my custom filesystem implementation is wrong, but note that it can play other formats successfully ( e.g. http://allstream.rainwave.cc:8000/all.mp3 reaches ‘READY’ state without problems )
. I set filesize to uint.MaxValue for streams with unknown length and FMOD tries to probe around this location, but I suspect that it doesn’t set it internally, or works around this in some way.
Is it possible to play Vorbis netstreams with custom filesystem ?
If there’s nothing preventing this I’ll upload my implementation later if needed.
Thank you very much for the support !
I’ve uploaded test project, both methods - playing Ogg/Vorbis netstream url directly via FMOD, and via separate download handler + custom file system - are included
Tags reading implementation referenced in the other thread is included too -
Hopefully everything needed can be seen in the console : I hope that it’ll help and you can make sense of it
As you have already found, if the source is an ogg/vorbis file your file system can handle it just fine. However if the source is a net stream, in this case an icy stream, FMOD does have a lot of internal code that is used to communicate with the stream. And since you are overriding the file system FMOD is assuming you are doing this too.
I think FMOD is doing something else internally even for finite sized ogg/vorbis files retrieved from network, not just icy streams though -
ogg/vorbis icy stream from the example fails to load/start at all, an ogg/vorbis files from network location (*) start playing but stop after few (blockalign) frames immediately -
(*) by network location I’m always assuming plain HTTP protocol
Is it possible to tell how should be ogg/vorbis format served to FMOD via custom filesystem to match its internal implementation of handling this format when streamed over network ?
/ In other words - is is possible to emulate what FMOD is doing internally ? /
The lack of secure transport support is really limiting - people can’t use FMOD networking on private VPS instances for example which are not accessible via plain HTTP nowadays
. of course, the most transparent/user friendly solution would be for FMOD to support secure transport, but that brings whole set of problems (that’s why I’m using UnityWebRequest which solved most of them)
If that isn’t possible right now though - can we at least follow some guidelines on how to provide compressed data over network to FMOD via custom filesystem so it can play all formats it supports ?
(or, at least most of them; thankfully MPEG seems to be more or less working with some more tweaks which can be automated)
try setting your length of your file to (unsigned int)-1 or 0xFFFFFFFF in FMOD_CREATESOUNDEXINFO to tell fmod that it is an endless stream, and it will stop trying to seek to the end of the file.
Thank you, but that unfortunately didn’t help at all :
/ netradio from above is stuck in LOADING getOpen state, and ogg/vorbis file on a local network via HTTP can’t be played – with either BAD_FORMAT error/s, or not going past LOADING state as well /
FWIW I set filesize in opening handler too (which is correctly carried over from extinfo though it seems)
forget trying to open a plain ogg file. it has chunks and data packets at the start and end and seeks all over the place. An /icecast/ stream on the other hand is set up for this, and doesnt seek. MP3 with IGNORETAGS can be opened over a network as a plain file, as it will not try to seek as part of the mp3 code. ogg has no such checking.
Your question was about ‘seek to end’. If the length is correctly set to -1, this callback will not happen.
yea the title is a bit misleading at this point (I naively thought if that can be eliminated FMOD would be happy - apparently it’s not so)
I can workaround vorbis files for now by having huge blockalign (essentially downloading them first - that’d work to some extent ), but note that the webradio [http://allstream.rainwave.cc:8000/all.ogg] doesn’t work even with filesize set to -1 and custom filesystem
and note that FMOD itself - when giving it resource url directly in createSound and not using filesystem -plays correctly in both cases
So what is there to implement in a custom filesystem in order to have identical behaviour ?
(this is probably related also to tags retrieval in different thread, but it’s not that critical since I think it depends on this working first)
for clarification: the callback at uint.MaxValue does happen initially even with filesize == -1 for that icy stream
btw @brett this all is done from c# wrapper from Unity - if you’re sure that setting filesize to -1 should help is it possible there’s a bug in the c#/c/c++ interop with this (esp. since all wrapper calls have respective parameters typed as uint) ?
FWIW I uploaded another test project (lowlevel_netradio_custom_filesystem_size_minus_1.zip) - there are two netradios in it, one mpeg, one ogg/vorbis mentioned previously, and you can see the read callbacks happening near uint.MaxValue in the Console when creating the sound in both cases (mpeg survives)
Hi, I would concentrate on the -1 thing, it is the first hurdle to make sure it is not thinking it can seek which is the biggest problem with netstreams.
Its possible it is not passing -1 from C# to C++ properly, try 0xffffffff or 4294967295 instead.