/*
* @(#)SunAudioRenderer.java 1.16 02/08/21
*
* Copyright (c) 1996-2002 Sun Microsystems, Inc. All rights reserved.
*/
package com.sun.media.renderer.audio;
import java.util.*;
import java.io.*;
//import java.lang.reflect.Constructor;
import javax.media.*;
import javax.media.format.*;
import javax.media.format.AudioFormat;
import com.sun.media.*;
import com.sun.media.util.*;
import com.sun.media.controls.*;
import com.sun.media.renderer.audio.device.*;
/**
* SunAudioRenderer
* @version
*/
public class SunAudioRenderer extends AudioRenderer {
static String NAME = "SunAudio Renderer";
static public String vendor = null;
static public String version = null;
static public boolean runningOnMac = false;
static public boolean useSystemTime = false;
static {
try {
vendor = System.getProperty("java.vendor");
version = System.getProperty("java.version");
if (vendor != null) {
vendor = vendor.toUpperCase();
if (vendor.startsWith("APPLE") && version.startsWith("1.1")) {
runningOnMac = true;
useSystemTime = true;
}
}
} catch (Throwable e) {
// Non-fatal error. No need to do anything.
}
}
private BasicClock clock = null;
private long startMediaTime = 0;
public SunAudioRenderer() {
super();
if (useSystemTime) {
timeBase = new SystemTimeBase();
clock = new BasicClock();
}
supportedFormats = new Format[1];
supportedFormats[0] = new AudioFormat(
AudioFormat.ULAW,
8000,
8,
1,
Format.NOT_SPECIFIED,
Format.NOT_SPECIFIED
);
gainControl = new MCA(this);
}
public String getName() {
return NAME;
}
public void open() throws ResourceUnavailableException {
if (!grabDevice()) {
throw new ResourceUnavailableException("AudioRenderer: Failed to initialize audio device.");
}
}
public void close() {
super.close();
}
protected AudioOutput createDevice(AudioFormat format) {
return (new SunAudioOutput());
}
private static synchronized boolean grabDevice() {
/*
The following lines cause JMF to crash on the Mac.
Check to make sure we are not running on the Mac.
*/
if (runningOnMac) {
if (!sun.audio.AudioPlayer.player.isAlive()) {
System.out.println("Audio device is busy");
return false;
}
}
return true;
}
/**
* Specialized clock methods to use system timebase instead
* of audio timebase for the mac.
*/
public void setTimeBase(TimeBase master) throws IncompatibleTimeBaseException {
if (useSystemTime) {
if (!(master instanceof SystemTimeBase)) {
Log.warning("AudioRenderer cannot be controlled by time bases other than its own: " + master);
/**
Silently allows the time base to be set to make
addController slightly more useful.
-ivg
throw new IncompatibleTimeBaseException();
*/
}
clock.setTimeBase(master);
} else {
super.setTimeBase(master);
}
}
public void syncStart(Time at) {
super.syncStart(at);
if (useSystemTime)
clock.syncStart(at);
}
public void stop() {
super.stop();
if (useSystemTime)
clock.stop();
}
public void setStopTime(Time t) {
if (useSystemTime)
clock.setStopTime(t);
else
super.setStopTime(t);
}
public Time getStopTime() {
if (useSystemTime)
return clock.getStopTime();
else
return super.getStopTime();
}
public void setMediaTime(Time now) {
if (useSystemTime) {
clock.setMediaTime(now);
startMediaTime = now.getNanoseconds();
} else
super.setMediaTime(now);
}
public Time getMediaTime() {
return (useSystemTime ? clock.getMediaTime() : super.getMediaTime());
}
static public long DEVICE_LATENCY = (runningOnMac ? 7000000000L : 0);
public long getMediaNanoseconds() {
if (useSystemTime) {
long t = clock.getMediaNanoseconds();
if (t - startMediaTime < DEVICE_LATENCY) {
return startMediaTime;
}
return t - DEVICE_LATENCY;
}
return super.getMediaNanoseconds();
}
public Time getSyncTime() {
return (useSystemTime ? clock.getSyncTime() : super.getSyncTime());
}
public TimeBase getTimeBase() {
return (useSystemTime ? clock.getTimeBase() : super.getTimeBase());
}
public Time mapToTimeBase(Time t) throws ClockStoppedException {
return (useSystemTime ? clock.mapToTimeBase(t) : super.mapToTimeBase(t));
}
public float getRate() {
return (useSystemTime ? clock.getRate() : super.getRate());
}
public float setRate(float factor) {
// sun.audio does not support rate change.
return super.setRate(1.0f);
}
class MCA extends GainControlAdapter {
AudioRenderer renderer;
protected MCA(AudioRenderer r) {
super(false);
renderer = r;
}
public void setMute(boolean mute) {
if (renderer != null && renderer.device != null)
renderer.device.setMute(mute);
super.setMute(mute);
}
public float getLevel() {
return -1f; // this is a dummy negative value for GainControlComponent usage
}
}
}
|