package com.sun.media.jfxmediaimpl;
import java.io.IOException;
import java.net.URI;
import com.sun.media.jfxmedia.AudioClip;
import com.sun.media.jfxmedia.MediaException;
import com.sun.media.jfxmedia.locator.Locator;
import java.net.URISyntaxException;
final class NativeAudioClip extends AudioClip {
private final Locator mediaSource;
private long nativeHandle = 0;
private static NativeAudioClipDisposer clipDisposer = new NativeAudioClipDisposer();
private static native boolean nacInit();
private static native long nacLoad(Locator source);
private static native long nacCreate(byte[] data, int dataOffset, int sampleCount, int sampleFormat, int channels, int sampleRate);
private static native void nacUnload(long handle);
private static native void nacStopAll();
public static synchronized boolean init() {
return nacInit();
}
public static AudioClip load(URI source) {
NativeAudioClip newClip = null;
try {
Locator locator = new Locator(source);
locator.init();
newClip = new NativeAudioClip(locator);
} catch (URISyntaxException ex) {
throw new MediaException("Non-compliant URI", ex);
} catch (IOException ex) {
throw new MediaException("Cannot connect to media", ex);
}
if (null != newClip && 0 != newClip.getNativeHandle()) {
MediaDisposer.addResourceDisposer(newClip, (Long)newClip.getNativeHandle(), clipDisposer);
} else {
newClip = null;
throw new MediaException("Cannot create audio clip");
}
return newClip;
}
public static AudioClip create(byte[] data, int dataOffset, int sampleCount, int sampleFormat, int channels, int sampleRate) {
NativeAudioClip newClip = new NativeAudioClip(data, dataOffset, sampleCount, sampleFormat, channels, sampleRate);
if (null != newClip && 0 != newClip.getNativeHandle()) {
MediaDisposer.addResourceDisposer(newClip, (Long)newClip.getNativeHandle(), clipDisposer);
} else {
newClip = null;
throw new MediaException("Cannot create audio clip");
}
return newClip;
}
private native NativeAudioClip nacCreateSegment(long handle, double startTime, double stopTime);
private native NativeAudioClip nacCreateSegment(long handle, int startSample, int endSample);
private native NativeAudioClip nacResample(long handle, int startSample, int endSample, int sampleRate);
private native NativeAudioClip nacAppend(long handle, long otherClip);
private native boolean nacIsPlaying(long handle);
private native void nacPlay(long handle, double volume, double balance, double pan, double rate, int loopCount, int priority);
private native void nacStop(long handle);
private NativeAudioClip(Locator source) {
mediaSource = source;
nativeHandle = nacLoad(mediaSource);
}
private NativeAudioClip(byte[] data, int dataOffset, int sampleCount, int sampleFormat, int channels, int sampleRate) {
mediaSource = null;
nativeHandle = nacCreate(data, dataOffset, sampleCount, sampleFormat, channels, sampleRate);
}
long getNativeHandle() {
return nativeHandle;
}
@Override
public AudioClip createSegment(double startTime, double stopTime) {
return nacCreateSegment(nativeHandle, startTime, stopTime);
}
@Override
public AudioClip createSegment(int startSample, int endSample) {
return nacCreateSegment(nativeHandle, startSample, endSample);
}
@Override
public AudioClip resample(int startSample, int endSample, int newSampleRate) {
return nacResample(nativeHandle, startSample, endSample, newSampleRate);
}
@Override
public AudioClip append(AudioClip clip) {
if (!(clip instanceof NativeAudioClip)) {
throw new IllegalArgumentException("AudioClip type mismatch, cannot append");
}
return nacAppend(nativeHandle, ((NativeAudioClip)clip).getNativeHandle());
}
@Override
public AudioClip flatten() {
return this;
}
@Override
public boolean isPlaying() {
return nacIsPlaying(nativeHandle);
}
@Override
public void play() {
nacPlay(nativeHandle, clipVolume, clipBalance, clipPan, clipRate, loopCount, clipPriority);
}
@Override
public void play(double volume) {
nacPlay(nativeHandle, volume, clipBalance, clipPan, clipRate, loopCount, clipPriority);
}
@Override
public void play(double volume, double balance, double rate, double pan, int loopCount, int priority) {
nacPlay(nativeHandle, volume, balance, pan, rate, loopCount, priority);
}
@Override
public void stop() {
nacStop(nativeHandle);
}
public static void stopAllClips() {
nacStopAll();
}
private static class NativeAudioClipDisposer implements MediaDisposer.ResourceDisposer {
public void disposeResource(Object resource) {
long nativeHandle = ((Long)resource).longValue();
if (0 != nativeHandle) {
nacUnload(nativeHandle);
}
}
}
}