Index: modules/sound/src/main/java/org/apache/harmony/sound/internal/nls/messages.properties =================================================================== --- modules/sound/src/main/java/org/apache/harmony/sound/internal/nls/messages.properties (revision 472412) +++ modules/sound/src/main/java/org/apache/harmony/sound/internal/nls/messages.properties (working copy) @@ -26,3 +26,5 @@ sound.09=Invalid status byte for sysex message: {0} sound.0A=Invalid meta event with type {0} sound.0B=Unsupported division type: {0} +sound.0C=Frame size must be one byte +sound.0D=The value is not supported Index: modules/sound/src/main/java/javax/sound/sampled/EnumControl.java =================================================================== --- modules/sound/src/main/java/javax/sound/sampled/EnumControl.java (revision 472412) +++ modules/sound/src/main/java/javax/sound/sampled/EnumControl.java (working copy) @@ -17,9 +17,11 @@ package javax.sound.sampled; +import org.apache.harmony.sound.internal.nls.Messages; + public abstract class EnumControl extends Control { public static class Type extends Control.Type { - public static final Type REVERB = new Type("REVERB"); + public static final Type REVERB = new Type("REVERB"); //$NON-NLS-1$ protected Type(String name) { super(name); @@ -37,7 +39,14 @@ } public void setValue(Object value) { - this.value = value; + for (Object val : values) { + if (val.equals(value)) { + this.value = value; + return; + } + } + // sound.0D=The value is not supported + throw new IllegalArgumentException(Messages.getString("sound.0D")); //$NON-NLS-1$ } public Object getValue() { @@ -49,6 +58,6 @@ } public String toString() { - throw new Error("Not yet implemented"); + return getType() + " with current value: " + value; //$NON-NLS-1$ } } Index: modules/sound/src/main/java/javax/sound/sampled/AudioFormat.java =================================================================== --- modules/sound/src/main/java/javax/sound/sampled/AudioFormat.java (revision 472412) +++ modules/sound/src/main/java/javax/sound/sampled/AudioFormat.java (working copy) @@ -17,6 +17,10 @@ package javax.sound.sampled; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + public class AudioFormat { public static class Encoding { @@ -73,7 +77,144 @@ protected int sampleSizeInBits; + private HashMap prop; + + public AudioFormat(AudioFormat.Encoding encoding, + float sampleRate, + int sampleSizeInBits, + int channels, + int frameSize, + float frameRate, + boolean bigEndian) { + + this.encoding = encoding; + this.sampleRate = sampleRate; + this.sampleSizeInBits = sampleSizeInBits; + this.channels = channels; + this.frameSize = frameSize; + this.frameRate = frameRate; + this.bigEndian = bigEndian; + + } + + public AudioFormat(AudioFormat.Encoding encoding, + float sampleRate, + int sampleSizeInBits, + int channels, + int frameSize, + float frameRate, + boolean bigEndian, + Map properties) { + + this.encoding = encoding; + this.sampleRate = sampleRate; + this.sampleSizeInBits = sampleSizeInBits; + this.channels = channels; + this.frameSize = frameSize; + this.frameRate = frameRate; + this.bigEndian = bigEndian; + prop = new HashMap(); + prop.putAll(properties); + + } + + public AudioFormat(float sampleRate, + int sampleSizeInBits, + int channels, + boolean signed, + boolean bigEndian) { + + this.encoding = (signed? Encoding.PCM_SIGNED : Encoding.PCM_UNSIGNED); + this.sampleRate = sampleRate; + this.sampleSizeInBits = sampleSizeInBits; + this.channels = channels; + this.frameSize = sampleSizeInBits >> 3; + if ((sampleSizeInBits & 0x7) == 0) { + this.frameSize++; + } + this.frameRate = sampleRate; + this.bigEndian = bigEndian; + + } + public Encoding getEncoding() { - throw new Error("not yet implemented"); + return encoding; } + + public float getSampleRate() { + return sampleRate; + } + + public int getSampleSizeInBits() { + return sampleSizeInBits; + } + + public int getChannels() { + return channels; + } + + public int getFrameSize() { + return frameSize; + } + + public float getFrameRate() { + return frameRate; + } + + public boolean isBigEndian() { + return bigEndian; + } + + public Map properties() { + if (prop != null) { + return Collections.unmodifiableMap(prop); + } else { + return Collections.emptyMap(); + } + } + + public Object getProperty(String key) { + if (prop == null) { + return null; + } + return prop.get(key); + } + + public boolean matches(AudioFormat format) { + if (!encoding.equals(format.getEncoding()) || + channels != format.getChannels() || + sampleSizeInBits != format.getSampleSizeInBits() || + frameSize != format.getFrameSize()) { + return false; + } + if (format.getSampleRate() != AudioSystem.NOT_SPECIFIED && + sampleRate != format.getSampleRate()) { + return false; + } + + if (format.getFrameRate() != AudioSystem.NOT_SPECIFIED && + frameRate != format.getFrameRate()) { + return false; + } + return true; + + } + + public String toString() { + + String ch; + switch (channels) { + case 1: + ch = "mono,"; //$NON-NLS-1$ + break; + case 2: + ch = "stereo,"; //$NON-NLS-1$ + default: + ch = channels + " channels, "; //$NON-NLS-1$ + } + + return encoding + " " + sampleRate + " Hz, " + sampleSizeInBits + " bit, " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + ch + frameSize + " bytes/frame, " + frameRate + " frames/second"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } Index: modules/sound/src/main/java/javax/sound/sampled/AudioFileFormat.java =================================================================== --- modules/sound/src/main/java/javax/sound/sampled/AudioFileFormat.java (revision 472412) +++ modules/sound/src/main/java/javax/sound/sampled/AudioFileFormat.java (working copy) @@ -17,8 +17,75 @@ package javax.sound.sampled; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + public class AudioFileFormat { + private AudioFileFormat.Type type; + private int byteLength = AudioSystem.NOT_SPECIFIED; + private AudioFormat format; + private int frameLength; + private HashMap prop; + + protected AudioFileFormat(AudioFileFormat.Type type, + int byteLength, + AudioFormat format, + int frameLength) { + this.type = type; + this.byteLength = byteLength; + this.format = format; + this.frameLength = frameLength; + } + + public AudioFileFormat(AudioFileFormat.Type type, + AudioFormat format, + int frameLength) { + this.type = type; + this.format = format; + this.frameLength = frameLength; + } + + public AudioFileFormat(AudioFileFormat.Type type, + AudioFormat format, + int frameLength, + Map properties) { + this.type = type; + this.format = format; + this.frameLength = frameLength; + prop = new HashMap(); + prop.putAll(properties); + } + + public AudioFileFormat.Type getType() { + return type; + } + + public int getByteLength() { + return byteLength; + } + + public AudioFormat getFormat() { + return format; + } + + public int getFrameLength() { + return frameLength; + } + + public Map properties() { + if (prop == null) { + return null; + } + return Collections.unmodifiableMap(prop); + } + + public String toString() { + return type + " (." + type.getExtension() + ") file, data format: " + format + //$NON-NLS-1$ //$NON-NLS-2$ + " frame length: " + frameLength; //$NON-NLS-1$ + } + public static class Type { private String name; Index: modules/sound/src/main/java/javax/sound/sampled/Control.java =================================================================== --- modules/sound/src/main/java/javax/sound/sampled/Control.java (revision 472412) +++ modules/sound/src/main/java/javax/sound/sampled/Control.java (working copy) @@ -63,6 +63,6 @@ } public String toString() { - throw new Error("Not yet imlemented"); + return type + " Control"; //$NON-NLS-1$ } } Index: modules/sound/src/main/java/javax/sound/sampled/BooleanControl.java =================================================================== --- modules/sound/src/main/java/javax/sound/sampled/BooleanControl.java (revision 472412) +++ modules/sound/src/main/java/javax/sound/sampled/BooleanControl.java (working copy) @@ -20,16 +20,16 @@ public abstract class BooleanControl extends Control { public static class Type extends Control.Type { - public static final Type APPLY_REVERB = new Type("APPLY_REVERB"); + public static final Type APPLY_REVERB = new Type("Apply Reverb"); //$NON-NLS-1$ - public static final Type MUTE = new Type("MUTE"); + public static final Type MUTE = new Type("Mute"); //$NON-NLS-1$ protected Type(String name) { super(name); } } - protected boolean value; + private boolean value; private String trueStateLabel; @@ -44,8 +44,7 @@ } protected BooleanControl(BooleanControl.Type type, boolean initialValue) { - super(type); - this.value = initialValue; + this(type, initialValue, "true", "false"); //$NON-NLS-1$ //$NON-NLS-2$ } public void setValue(boolean value) { @@ -57,7 +56,7 @@ } public String getStateLabel(boolean state) { - if (state == true) { + if (state) { return this.trueStateLabel; } else { return this.falseStateLabel; @@ -65,6 +64,6 @@ } public String toString() { - throw new Error("Not yet implemented"); + return getType() + " Control with current value: " + value; //$NON-NLS-1$ } } Index: modules/sound/src/main/java/javax/sound/sampled/DataLine.java =================================================================== --- modules/sound/src/main/java/javax/sound/sampled/DataLine.java (revision 472412) +++ modules/sound/src/main/java/javax/sound/sampled/DataLine.java (working copy) @@ -53,7 +53,15 @@ } public boolean isFormatSupported(AudioFormat format) { - throw new Error("not yet implemented"); + if (formats == null) { + return false; + } + for (AudioFormat supported : formats) { + if (format.matches(supported)) { + return true; + } + } + return false; } public int getMinBufferSize() { @@ -66,12 +74,36 @@ @Override public boolean matches(Line.Info info) { - throw new Error("not yet implemented"); + + if (!super.matches(info)) { + return false; + } + + DataLine.Info inf = (DataLine.Info)info; + if (minBufferSize < inf.getMinBufferSize() || + maxBufferSize > inf.getMaxBufferSize()) { + return false; + } + + for (AudioFormat supported : formats) { + if (!inf.isFormatSupported(supported)) { + return false; + } + } + + return true; } @Override public String toString() { - throw new Error("not yet implemented"); + String formatStr = (formats.length == 1? formats[0].toString() + : formats.length + " audio formats"); //$NON-NLS-1$ + String bufStr = ""; //$NON-NLS-1$ + if (minBufferSize != AudioSystem.NOT_SPECIFIED) { + bufStr = ", and buffers of " + minBufferSize + //$NON-NLS-1$ + "to " + maxBufferSize + " bytes"; //$NON-NLS-1$ //$NON-NLS-2$ + } + return getLineClass() + " supporting " + formatStr + bufStr; //$NON-NLS-1$ } } Index: modules/sound/src/main/java/javax/sound/sampled/Mixer.java =================================================================== --- modules/sound/src/main/java/javax/sound/sampled/Mixer.java (revision 472412) +++ modules/sound/src/main/java/javax/sound/sampled/Mixer.java (working copy) @@ -63,7 +63,7 @@ } } - Line getLine(Line.Info info); + Line getLine(Line.Info info) throws LineUnavailableException; int getMaxLines(Line.Info info); Index: modules/sound/src/main/java/javax/sound/sampled/CompoundControl.java =================================================================== --- modules/sound/src/main/java/javax/sound/sampled/CompoundControl.java (revision 472412) +++ modules/sound/src/main/java/javax/sound/sampled/CompoundControl.java (working copy) @@ -37,6 +37,7 @@ } public String toString() { - throw new Error("Not yet implemented"); + return getType() + "CompoundControl containing " //$NON-NLS-1$ + + String.valueOf(memberControls) + " Controls."; //$NON-NLS-1$ } } Index: modules/sound/src/main/java/javax/sound/sampled/LineEvent.java =================================================================== --- modules/sound/src/main/java/javax/sound/sampled/LineEvent.java (revision 472412) +++ modules/sound/src/main/java/javax/sound/sampled/LineEvent.java (working copy) @@ -62,7 +62,7 @@ } @Override - public final String toString() { + public String toString() { return name; } } Index: modules/sound/src/main/java/javax/sound/sampled/AudioInputStream.java =================================================================== --- modules/sound/src/main/java/javax/sound/sampled/AudioInputStream.java (revision 472412) +++ modules/sound/src/main/java/javax/sound/sampled/AudioInputStream.java (working copy) @@ -20,6 +20,8 @@ import java.io.IOException; import java.io.InputStream; +import org.apache.harmony.sound.internal.nls.Messages; + public class AudioInputStream extends InputStream { protected AudioFormat format; @@ -30,8 +32,140 @@ protected int frameSize; - @Override + private InputStream stream; + + private TargetDataLine line; + + private byte[] oneByte = new byte[1]; + + public AudioInputStream(InputStream stream, AudioFormat format, long length) { + this.stream = stream; + this.format = format; + this.frameLength = length; + this.frameSize = format.getFrameSize(); + } + + public AudioInputStream(TargetDataLine line) { + this.line = line; + this.format = line.getFormat(); + this.frameLength = AudioSystem.NOT_SPECIFIED; //TODO + this.frameSize = this.format.getFrameSize(); + } + + public AudioFormat getFormat() { + return format; + } + + public long getFrameLength() { + return frameLength; + } + public int read() throws IOException { - throw new Error("not yet implemented"); + if (frameSize != 1) { + // sound.0C=Frame size must be one byte + throw new IOException(Messages.getString("sound.0C")); //$NON-NLS-1$ + } + int res; + if (stream != null) { // InputStream + res = stream.read(); + if (res == -1) { + return -1; + } + framePos = +1; + return res; + } else { // TargetDataLine + if (line.read(oneByte, 0, 1) == 0) { + return -1; + } + framePos = line.getLongFramePosition(); + return oneByte[0]; + } } + + public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } + + public int read(byte[] b, int off, int len) throws IOException { + int l = len - (len % frameSize); + int res; + if (stream != null) { // InputStream + res = stream.read(b, off, l); + if (res == -1) { + return -1; + } + framePos = framePos + res / frameSize; + return res; + } else { // TargetDataLine + res = line.read(b, off, l); + if (res == 0) { + return -1; + } + framePos = line.getLongFramePosition(); + return res; + } + + } + + public long skip(long n) throws IOException { + + if (n < frameSize) { + return 0; + } + byte[] skipBuf = new byte[frameSize]; + long skipped = 0; + while (skipped < n) { + int read = read(skipBuf, 0, frameSize); + if (read == -1) { + return skipped; + } + skipped += read; + if (n - skipped < frameSize) { + return skipped; + } + } + return skipped; + + } + + public int available() throws IOException { + if (stream != null) { // InputStream + return stream.available(); + } else { // TargetDataLine + return line.available(); + } + } + + public void close() throws IOException { + if (stream != null) { // InputStream + stream.close(); + } else { // TargetDataLine + line.close(); + } + } + + public void mark(int readlimit) { + if (stream != null) { //I nputStream + stream.mark(readlimit); + } else { // TargetDataLine + // do nothing + } + } + + public void reset() throws IOException { + if (stream != null) { //InputStream + stream.reset(); + } else { // TargetDataLine + // do nothing + } + } + + public boolean markSupported() { + if (stream != null) { //InputStream + return stream.markSupported(); + } else { // TargetDataLine + return false; + } + } + }