diff options
Diffstat (limited to 'src/java')
-rw-r--r-- | src/java/com/jogamp/common/av/AudioSink.java | 65 | ||||
-rw-r--r-- | src/java/jogamp/common/av/JavaSoundAudioSink.java | 43 | ||||
-rw-r--r-- | src/java/jogamp/common/av/NullAudioSink.java | 14 |
3 files changed, 83 insertions, 39 deletions
diff --git a/src/java/com/jogamp/common/av/AudioSink.java b/src/java/com/jogamp/common/av/AudioSink.java index 9c31244..ac6441a 100644 --- a/src/java/com/jogamp/common/av/AudioSink.java +++ b/src/java/com/jogamp/common/av/AudioSink.java @@ -197,21 +197,6 @@ public interface AudioSink { public boolean setVolume(float v); /** - * Returns the preferred sample-rate of this sink, i.e. mixer frequency in Hz, e.g. 41000 or 48000. - * <p> - * The preferred sample-rate is guaranteed to be supported - * and shall reflect this sinks most native format, - * i.e. best performance w/o data conversion. - * </p> - * <p> - * May return {@link AudioSink#DefaultFormat}'s 44100 default if undefined. - * </p> - * @see #init(AudioFormat, float, int, int, int) - * @see #isSupported(AudioFormat) - */ - public int getPreferredSampleRate(); - - /** * Returns the number of sources the used device is capable to mix. * <p> * This device attribute is only formally exposed and not used, @@ -236,32 +221,64 @@ public interface AudioSink { public float getDefaultLatency(); /** - * Returns the preferred {@link AudioFormat} by this sink. + * Returns the native {@link AudioFormat} by this sink. * <p> - * The preferred format is guaranteed to be supported + * The native format is guaranteed to be supported * and shall reflect this sinks most native format, * i.e. best performance w/o data conversion. * </p> * <p> + * The native format is not impacted by {@link #setChannelLimit(int)}. + * </p> + * <p> + * May return {@link AudioSink#DefaultFormat} if undefined. + * </p> + * @see #init(AudioFormat, float, int, int, int) + */ + public AudioFormat getNativeFormat(); + + /** + * Returns the preferred {@link AudioFormat} by this sink. + * <p> + * The preferred format is a subset of {@link #getNativeFormat()}, + * impacted by {@link #setChannelLimit(int)}. + * </p> + * <p> * Known {@link #AudioFormat} attributes considered by implementations: * <ul> * <li>ALAudioSink: {@link AudioFormat#sampleRate}. + * <li>ALAudioSink: {@link AudioFormat#channelCount} * </ul> * </p> - * <p> - * May return {@link AudioSink#DefaultFormat} if undefined. - * </p> + * @see #getNativeFormat() * @see #init(AudioFormat, float, int, int, int) + * @see #setChannelLimit(int) * @see #isSupported(AudioFormat) - * @see #getPreferredSampleRate() */ public AudioFormat getPreferredFormat(); - /** Return the maximum number of supported channels, e.g. 1 for mono, 2 for stereo, etc. */ - public int getMaxSupportedChannels(); + /** + * Limit maximum supported audio channels by user. + * <p> + * Must be set before {@link #getPreferredFormat()}, {@link #isSupported(AudioFormat)} and naturally {@link #init(AudioFormat, int, int, int, int)}. + * </p> + * <p> + * May be utilized to enforce 1 channel (mono) downsampling + * in combination with JOAL/OpenAL to experience spatial 3D position effects. + * </p> + * @param cc maximum supported audio channels, will be clipped [1..{@link #getNativeFormat()}.{@link AudioFormat#channelCount channelCount}] + * @see #getNativeFormat() + * @see #getPreferredFormat() + * @see #isSupported(AudioFormat) + * @see #init(AudioFormat, int, int, int, int) + */ + public void setChannelLimit(final int cc); /** * Returns true if the given format is supported by the sink, otherwise false. + * <p> + * The {@link #getPreferredFormat()} is used to validate compatibility with the given format. + * </p> * @see #init(AudioFormat, float, int, int, int) * @see #getPreferredFormat() */ @@ -275,7 +292,7 @@ public interface AudioSink { * <p> * Caller shall validate <code>requestedFormat</code> via {@link #isSupported(AudioFormat)} * beforehand and try to find a suitable supported one. - * {@link #getPreferredFormat()} and {@link #getMaxSupportedChannels()} may help. + * {@link #getPreferredFormat()} may help. * </p> * @param requestedFormat the requested {@link AudioFormat}. * @param frameDurationHint average {@link AudioFrame} duration hint in milliseconds. diff --git a/src/java/jogamp/common/av/JavaSoundAudioSink.java b/src/java/jogamp/common/av/JavaSoundAudioSink.java index d3ddda9..58f0fec 100644 --- a/src/java/jogamp/common/av/JavaSoundAudioSink.java +++ b/src/java/jogamp/common/av/JavaSoundAudioSink.java @@ -61,6 +61,9 @@ public final class JavaSoundAudioSink implements AudioSink { private int bufferCount; private final byte [] sampleData = new byte[BUFFER_SIZE]; private boolean available = false; + private final AudioFormat nativeFormat; + private int userMaxChannels = 8; + private AudioFormat preferredFormat = null; private AudioFormat chosenFormat = null; private volatile boolean playRequested = false; @@ -79,8 +82,12 @@ public final class JavaSoundAudioSink implements AudioSink { public JavaSoundAudioSink() { available = false; if( !staticAvailable ) { + nativeFormat = DefaultFormat; return; } + nativeFormat = new AudioFormat(DefaultFormat.sampleRate, DefaultFormat.sampleSize, getMaxSupportedChannels(), + DefaultFormat.signed, DefaultFormat.fixedP, DefaultFormat.planar, DefaultFormat.littleEndian); + preferredFormat = nativeFormat; available = true; } @@ -118,11 +125,6 @@ public final class JavaSoundAudioSink implements AudioSink { } @Override - public int getPreferredSampleRate() { - return DefaultFormat.sampleRate; - } - - @Override public int getSourceCount() { return -1; } @@ -138,17 +140,41 @@ public final class JavaSoundAudioSink implements AudioSink { } @Override + public final AudioFormat getNativeFormat() { + return nativeFormat; + } + + @Override public AudioFormat getPreferredFormat() { return DefaultFormat; } @Override - public final int getMaxSupportedChannels() { - return 2; + public final void setChannelLimit(final int cc) { + userMaxChannels = Math.min(8, Math.max(1, cc)); + preferredFormat = new AudioFormat(nativeFormat.sampleRate, + nativeFormat.sampleSize, getMaxSupportedChannels(), + nativeFormat.signed, nativeFormat.fixedP, + nativeFormat.planar, nativeFormat.littleEndian); + if( DEBUG ) { + System.out.println("ALAudioSink: channelLimit "+userMaxChannels+", preferredFormat "+preferredFormat); + } + } + + private final int getMaxSupportedChannels() { + final int cc = 2; + return Math.min(userMaxChannels, cc); } @Override public final boolean isSupported(final AudioFormat format) { + if( format.planar != preferredFormat.planar || + format.fixedP != preferredFormat.fixedP || + format.sampleRate > preferredFormat.sampleRate || + format.channelCount > preferredFormat.channelCount ) + { + return false; + } return true; } @@ -157,6 +183,9 @@ public final class JavaSoundAudioSink implements AudioSink { if( !staticAvailable ) { return false; } + if( !isSupported(requestedFormat) ) { + return false; + } // Create the audio format we wish to use format = new javax.sound.sampled.AudioFormat(requestedFormat.sampleRate, requestedFormat.sampleSize, requestedFormat.channelCount, requestedFormat.signed, !requestedFormat.littleEndian); diff --git a/src/java/jogamp/common/av/NullAudioSink.java b/src/java/jogamp/common/av/NullAudioSink.java index 19b0acb..904b863 100644 --- a/src/java/jogamp/common/av/NullAudioSink.java +++ b/src/java/jogamp/common/av/NullAudioSink.java @@ -84,11 +84,6 @@ public final class NullAudioSink implements AudioSink { } @Override - public int getPreferredSampleRate() { - return DefaultFormat.sampleRate; - } - - @Override public int getSourceCount() { return -1; } @@ -104,16 +99,19 @@ public final class NullAudioSink implements AudioSink { } @Override - public AudioFormat getPreferredFormat() { + public AudioFormat getNativeFormat() { return DefaultFormat; } @Override - public final int getMaxSupportedChannels() { - return 8; + public AudioFormat getPreferredFormat() { + return DefaultFormat; } @Override + public void setChannelLimit(final int cc) { } + + @Override public final boolean isSupported(final AudioFormat format) { /** * If we like to emulate constraints .. |