fictiveLaark's picture

Trying to translate a Java Ogg decoder

I have code for playing an ogg vorbis file that uses JOrbis and the OggInputStream.java from here

http://home.halden.net/tombr/ogg/ogg.html
(I wouldn't want to be accused of stealing code, is this sufficient credit?)

I looked at the source for csvorbis and I saw a lot of familar classes so I thought I would try to translate OggInputStream.java to a C# file. I was hoping I would just have to change some syntax but the java version extends FilterInputStream and I think I might need help from somebody who knows C# and Java better than I do.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
fictiveLaark's picture

I think I figured it out on my own, I just didn't extend any classes and used a FileStream internally. So far I can load an Ogg file and my ToString methods writes this

version 0
channels 2
rate (hz) 44100

Now I'm trying to play the file. In my Java code I have a class Stream that wraps an OggInputStream and handles streaming to OpenAL(mostly translated to Java from this C tutorial http://www.devmaster.net/articles/openal-tutorials/lesson8.php). But in Stream.java I have the following line

format = stream.getFormat() == OggInputStream.FORMAT_MONO16 ? AL10.AL_FORMAT_MONO16 : AL10.AL_FORMAT_STEREO16;

And I can't find any mention of AL_FORMAT_MONO16 or AL_FORMAT_STEREO16 in the OpenTK documentation.

Mincus's picture

Try the OpenTK.Audio.ALFormat enum. Pretty sure that's the one you want.

Are you planning on releasing this work? Would be a very useful addition to the OpenTK site even if not to OpenTK itself.

fictiveLaark's picture

There's no way, I'm far too much of an idiot to have made this work. =P Here's my code, you need csvorbis for it to work.

AttachmentSize
Stream.cs4.28 KB
OggInputStream.cs14.75 KB
Main.cs729 bytes
the Fiddler's picture

Something very interesting is brewing here: an open-source, fully managed Theora audio / video decoder. It hasn't been released yet, but I am very excited about this development. This is the last missing piece of the puzzle for cross-platform, fully managed game development.

migueltk's picture

I tried to compile the code you provide (Stream.cs, OggInputStream.cs and Main.cs) to generate an executable that reproduces a *. ogg but I do not work, tells me "OverflowException" at line 424 of file "OggInputStream. cs ". Could you provide a compressed file with the solution and project that you have used?

If the file is over 512 Kbytes you can send me "bitiopiasite@gmail.com.

Regards, ...

fictiveLaark's picture

That line and the one after are kind of ugly, the code in Java was this

convbuffer[ptr + 0] = (byte) (bigEndian ? val >>> 8 : val);
convbuffer[ptr + 1] = (byte) (bigEndian ? val : val >>> 8);

The >>> is different from >> in that it it doesn't reserve the sign bit in signed numbers. I looked around and the C# version I found was this.

convbuffer[ptr + 0] = (byte) (bigEndian ? unchecked((int)((uint)val >>  8)) : val);
convbuffer[ptr + 1] = (byte) (bigEndian ? val : unchecked((int)((uint)val >>  8)));

But I don't see why the shift would cause problems when it's in unchecked(...), maybe it's the cast to byte. I tried this and it still worked for me.

convbuffer[ptr + 0] = unchecked((byte) (bigEndian ? (int)((uint)val >>  8) : val));
convbuffer[ptr + 1] = unchecked((byte) (bigEndian ? val : (int)((uint)val >>  8)));

I've also attached the solution.

AttachmentSize
Ogg.rar159.65 KB
migueltk's picture

really cool, works perfectly, I regret not having more time to understand how it works, I hope to keep working on this project sound.

Thanks, greetings, ...

P.D: I attach a sound file that sounds good

AttachmentSize
test2.7z257.69 KB
c2woody's picture
Quote:

But I don't see why the shift would cause problems when it's in unchecked(...), maybe it's the cast to byte. I tried this and it still worked for me.

The shift of unsigned int as well as the cast to int are fine (the cast to int does not overflow because the values are in the -32768 to 32767 range anyways), but the cast to byte may overflow. Since this overflow is intentional it is fine, and the unchecked() should be around the whole expression (actually only the byte cast but there's no point in separating that) like in your last suggestion.