Re: [sdljava-users] Problem with SDLMixer
Status: Beta
Brought to you by:
ivan_ganza
From: Ivan Z. G. <iva...@ya...> - 2005-01-22 23:53:13
|
Sweet! Thank you very much for the patch. I have integrated this code. That is a really nice way to do it. I was wracking my brain for an elegant solution. Its been tested and the changes are committed to CVS. I made one small change which was to call order(ByteOrder.nativeOrder()) on the byte buffers. I think this is required in the case when the buffers might be accessed from the C code. BTW: let me know if you want dev access. Or feel free to keep sending me patches as you have them. Also finally I have moved the location of BufferUtils to src/sdljava/util; it used to be in just "src" which was the wrong place. Thanks again! -Ivan/ Robert Schuster wrote: > Great! That was the problem. > > Along with that I fixed the problem with the loading of URLs from the > net (or arbitrary slow locations). The problem with your > implementation was that you asserted that InputStream.available() > returns the complete size of the stream. However available() returns > only the amount of bytes that can be read without blocking. > > I fixed BufferUtil.readInputStream() in the following way: > I am reading the parts of the stream into separate ByteBuffers until > the stream is really finished. Afterwards I merge the buffers into one > big buffer and return that. > The implementation uses Channel.newChannel() to retrieve a > ReadableByteChannel which allows a ByteBuffer for its read() method. > The behavior of this method is otherwise the same as > InputStream.read(). The important bit is that -1 is returned when the > end of the stream is reached. > > I have attached the patch to this mail. Tell me if the list daemon > rips it away to send it to you directly. > > If you are using BeanShell try this snippet as a proof of concept: > > import sdljava.*; > import sdljava.mixer.*; > SDLMain.init(SDLMain.SDL_INIT_AUDIO); > SDLMixer.openAudio(44100, SDLMixer.AUDIO_S16SYS, 2, 4096); > imc = SDLMixer.loadWAV(new > URL("http://www.barbneal.com/wav/lucy/lucy01.wav")); > SDLMixer.playChannel(0, imc, 0); > > However you can add type information and make that a real Java class, > too. :-) > > cu > Robert > > Btw: Thanks again for reviving the Java binding for SDL. sdljava is > the first library that allows me to do portable sound output in Java > without having to sacrifice other useful Java API (like resource > loading system which is essential for JNLP!). > > Ivan Z. Ganza wrote: > >> Make sure you have at least SDL Mixer 1.2.6 as the Mix_LoadMUS_RW was >> added for 1.2.6. Its strange though that you were able to compile if >> this function wasn't present. >> >> BTW I've found that loading over the network doesn't work, filebased >> urls are fine though. I need to find an example of the proper way to >> load a byte stream from a URL.... >> >> Let me know if this helped. >> -Ivan/ >> >> Robert Schuster wrote: >> >>> Hi, >>> I wanted to try the new URL based loading of WAV file and was >>> stopped by this: >>> >>> java.lang.UnsatisfiedLinkError: >>> /home/rob/tmp/lwtest/libsdljava_mixer.so: >>> /home/rob/tmp/lwtest/libsdljava_mixer.so: undefined symbol: >>> Mix_LoadMUS_RW >>> at java.lang.ClassLoader$NativeLibrary.load(Native Method) >>> at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1586) >>> at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1511) >>> at java.lang.Runtime.loadLibrary0(Runtime.java:788) >>> at java.lang.System.loadLibrary(System.java:834) >>> at sdljava.mixer.SDLMixer.<clinit>(SDLMixer.java:1184) >>> >>> I took sdljava from CVS (01.22.05) and compiled all files (using >>> Blackdown 1.4.2 for GNU/Linux). >>> >>> cu >>> Robert >>> >>> >>> ------------------------------------------------------- >>> This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting >>> Tool for open source databases. Create drag-&-drop reports. Save time >>> by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc. >>> Download a FREE copy at http://www.intelliview.com/go/osdn_nl >>> _______________________________________________ >>> sdljava-users mailing list >>> sdl...@li... >>> https://lists.sourceforge.net/lists/listinfo/sdljava-users >> >> >> >> >> >> >> ------------------------------------------------------- >> This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting >> Tool for open source databases. Create drag-&-drop reports. Save time >> by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc. >> Download a FREE copy at http://www.intelliview.com/go/osdn_nl >> _______________________________________________ >> sdljava-users mailing list >> sdl...@li... >> https://lists.sourceforge.net/lists/listinfo/sdljava-users >> >> >------------------------------------------------------------------------ > >Index: src/util/BufferUtil.java >=================================================================== >RCS file: /cvsroot/sdljava/sdljava/src/util/BufferUtil.java,v >retrieving revision 1.2 >diff -u -r1.2 BufferUtil.java >--- src/util/BufferUtil.java 7 Jan 2005 03:11:49 -0000 1.2 >+++ src/util/BufferUtil.java 22 Jan 2005 22:20:40 -0000 >@@ -7,15 +7,23 @@ > import java.net.URLConnection; > import java.net.MalformedURLException; > import java.nio.ByteBuffer; >+import java.nio.channels.Channels; >+import java.nio.channels.ReadableByteChannel; >+import java.util.Iterator; >+import java.util.List; >+import java.util.LinkedList; > > /** > * Some usefull methods for reading URLs or streams and returning the data as Direct Buffers > * >- * @author Ivan Z. Ganza >+ * @author Ivan Z. Ganza >+ * @author Robert Schuster > * @version $Id: BufferUtil.java,v 1.2 2005/01/07 03:11:49 ivan_ganza Exp $ > */ > public class BufferUtil { > >+ private static final int BUFFER_SIZE = 1024; >+ > /** > * Tries to open the given URL, get its input stream, returns the data in a <I><B>direct</I></B> ByteBuffer > * >@@ -48,14 +56,48 @@ > * @exception IOException if an error occurs > */ > public static ByteBuffer readInputStream(InputStream in) throws IOException { >- int avail = in.available(); >- byte buf[] = new byte[avail]; >+ /* Converts the InputStream into a channels which allows >+ * us to read into a ByteBuffer. >+ */ >+ ReadableByteChannel ch = Channels.newChannel(in); >+ >+ // Creates a list that stores the intermediate buffers. >+ List list = new LinkedList(); > >- int read = in.read(buf); >- if (read != avail) throw new IOException("needed to read: " + avail + " bytes, but actually read: " + read); >+ // A variable storing the accumulated size of the data. >+ int sum = 0, read = 0; > >- ByteBuffer byteBuffer = ByteBuffer.allocateDirect(buf.length); >- byteBuffer.put(buf); >- return byteBuffer; >- } >-} >\ No newline at end of file >+ /* Reads all the bytes from the channel and stores them >+ * in various buffer objects. >+ */ >+ do { >+ ByteBuffer b = ByteBuffer.allocateDirect(BUFFER_SIZE); >+ read = ch.read(b); >+ >+ if(read > 0) { >+ b.flip(); // make ready for reading later >+ list.add(b); >+ sum += read; >+ } >+ } while(read != -1); >+ >+ /* If there is only one buffer used we do not >+ * need to merge the data. >+ */ >+ if(list.size() == 1) { >+ return (ByteBuffer) list.get(0); >+ } >+ >+ ByteBuffer bb = ByteBuffer.allocateDirect(sum); >+ >+ /* Merges all buffers into the Buffer bb */ >+ Iterator ite = list.iterator(); >+ while(ite.hasNext()){ >+ bb.put((ByteBuffer) ite.next()); >+ } >+ >+ list.clear(); >+ >+ return bb; >+ } >+} > > |