On May 9, 11:58 am, Julien <[email protected]> wrote:
> Hello all,
>
> A quick newbie question about getting hold of an object implementing
> interface from the Java sound API.
> The static method AudioSystem/getSourceDataLine returns an object
> implementing the SourceDataLine interface.
> But the returned object in clojure doesn't seem to fully implement the
> interface.
>
> (ns sample.main
> (:import (javax.sound.sampled AudioFormat AudioSystem
> LineUnavailableException SourceDataLine)
> ))
>
> (try
> (def sourceDataLine (AudioSystem/getSourceDataLine
> audioFormat)) ;audioFormat is defined above
> (println "sourceDataLine :" sourceDataLine)
> (.open sourceDataLine audioFormat)
> (catch LineUnavailableException ex
> (. ex printStackTrace))
> )
>
> outputs: sourceDataLine : #<DirectSDL
> com.sun.media.sound.directaudiodevice$direct...@9cb0f4>
>
> sourceDataLine resolve to a DirectSDL object, but apparently does not
> fully implement the interface SourceDataLine.
> -stack trace:
> java.lang.IllegalArgumentException: No matching method found: open
> for class com.sun.media.sound.DirectAudioDevice$DirectSDL
>
> -here's interface SourceDataLine:
> package javax.sound.sampled;
>
> public abstract interface SourceDataLine extends DataLine
> {
> public abstract void open(AudioFormat paramAudioFormat, int
> paramInt)
> throws LineUnavailableException;
>
> public abstract void open(AudioFormat paramAudioFormat)
> throws LineUnavailableException;
>
> public abstract int write(byte[] paramArrayOfByte, int paramInt1,
> int paramInt2);
> }
>
> + calling the open method without argument works fine
> + a java version of this code works fine
> + a write method isn't implemented either
>
> Is this the expected clojure behavior? or what I am doing wrong?
>
This works fine for me:
(import '(javax.sound.sampled AudioFormat AudioSystem
LineUnavailableException SourceDataLine))
(try
(let [audioFormat (AudioFormat. 44100.0 16 2 true true)
sourceDataLine (AudioSystem/getSourceDataLine audioFormat)]
(println "sourceDataLine :" sourceDataLine)
(.open sourceDataLine audioFormat)
(.isOpen sourceDataLine))
(catch LineUnavailableException ex
(. ex printStackTrace)))
-> sourceDataLine : #<MixerSourceLine
com.sun.media.sound.mixersourcel...@3ae490fa>
-> true
A few things:
It's always best to post a complete example - it makes it easier for
people to help you, e.g. ";audioFormat is defined above" just leaves
me having to figure out how to make one in order to reproduce your
problem.
The objects returned by Clojure are the actual Java objects, there are
no wrappers.
Sometimes an implementation class is private, and thus reflection
can't access its methods.
You are definitely getting a reflective call to open due to your use
of 'def' (def is almost always wrong non-top-level in Clojure). Using
'let' will allow the compiler to infer that the type of sourceDataLine
is SourceDataLine. If you want a top level def, do it outside and use
a type hint:
(def #^SourceDataLine sourceDataLine (AudioSystem/getSourceDataLine
audioFormat))
Use of camelCase in Clojure code is non-idiomatic - better audio-
format, source-data-line etc. That also helps make it easier to
distinguish Java-originated names from Clojure names.
Rich
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---