aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/java/com/jogamp/common/av/AudioSink.java65
-rw-r--r--src/java/jogamp/common/av/JavaSoundAudioSink.java43
-rw-r--r--src/java/jogamp/common/av/NullAudioSink.java14
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 ..