Re: Java Audio Help (Mixers and Ports)
KWhat4 wrote:
On Aug 11, 4:55 pm, "Andrew Thompson" <u32984@uwe> wrote:
KWhat4 wrote:
..
Any Ideas?
Post code* rather than..
objOutputDataLine = (SourceDataLine) objMixer.getLine(objPort);
.vague snippets.
And by 'code' I mean a specific form, an SSCCE.
<http://www.physci.org/codes/sscce.html>
I am not sure it will help you, but here is a small sound
based tool I wrote to plot the sound traces on-screen,
an oscilloscope.
<http://www.physci.org/test/oscilloscope/AudioTrace.java>
It's homepage is here..
<http://www.physci.org/sound/audiotrace.html>
--
Andrew Thompsonhttp://www.athompson.info/andrew/
Message posted via JavaKB.comhttp://www.javakb.com/Uwe/Forums.aspx/java-general/200708/1
Hopefully this will illustrate my insanity more effectively... I know
its dirty, but the problem is at the very end when i try to read/write
to an audio port. FYI I am using Java 1.5
package com.jargon.client.audio;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.Port;
import javax.sound.sampled.TargetDataLine;
public class Test {
/**
* @param args
* @throws LineUnavailableException
*/
public static void main(String[] args) throws
LineUnavailableException {
AudioFormat objAudioFormat = new AudioFormat(8000.0F, 16, 1, true,
false);
Mixer objTargetMixer = null;
Line objTargetLine = null;
System.out.println("Mixers:");
Mixer.Info[] aMixerInfo = AudioSystem.getMixerInfo();
for (int i = 0; i < aMixerInfo.length; i++) {
/* Possible mixers for this computer
ICH6 [plughw:0,0]
ICH6 [plughw:0,1]
ICH6 [plughw:0,2]
ICH6 [plughw:0,3]
ICH6 [plughw:0,4]
Modem [plughw:1,0]
Port ICH6 [hw:0]
Port Modem [hw:1]
*/
if (aMixerInfo[i].getName().equalsIgnoreCase("Port ICH6 [hw:0]")) {
objTargetMixer = AudioSystem.getMixer(aMixerInfo[i]);
}
System.out.println("\t" + aMixerInfo[i].getName());
}
System.out.println();
//Now try to get a port on our target mixer
System.out.println("Ports:");
Line.Info[] aLineInfo = objTargetMixer.getSourceLineInfo();
for (int i = 0; i < aLineInfo.length; i++) {
/* Possible Port for the Target Mixer for this computer
Capture source port
*/
if (aLineInfo[i] instanceof Port.Info) {
Port.Info objPort = (Port.Info) aLineInfo[i];
objTargetLine = objTargetMixer.getLine(objPort);
}
System.out.println("\t" + aLineInfo[i].toString());
}
//So now we have a mixer, we have a port... lets read/write data?
//TODO This is where i bork the process! Note that i have tried all
with no success.
//ClassCastException: com.sun.media.sound.PortMixer$PortMixerPort
//TargetDataLine objInputDataLine = (TargetDataLine)
objTargetMixer.getLine(objTargetLine.getLineInfo());
//TargetDataLine objInputDataLine = (TargetDataLine) objTargetLine;
//TargetDataLine objInputDataLine = (TargetDataLine)
AudioSystem.getLine(objTargetLine.getLineInfo());
//IllegalArgumentException: Line unsupported: interface
TargetDataLine supporting format PCM_SIGNED 8000.0 Hz, 16 bit, mono, 2
bytes/frame, little-endian
//TargetDataLine objInputDataLine = (TargetDataLine)
AudioSystem.getTargetDataLine(objAudioFormat,
objTargetMixer.getMixerInfo());
}
}
I don't know if you are a C programmer or not but there is an
incongruity between C and Java naming in the audio business. In Java
Ports are used to get controls, like volume and frame etc. Lines are
used to capture or play audio data. SourceDataLines play,
TargetDataLines capture. Mixers are really complicated as they can have
Ports, SDLs and TDLs associated with them but may not.
Below is a simple example that gets audio data from a URL and plays it
by sending it to a SourceDataLine. See the comments in the source for
details.
Below that is a Sun program to list the ports on your computer. I'm
sorry it is formatted so poorly but that is the way it is.
import javax.sound.sampled.*;
import java.io.*;
import java.net.*;
public class AudioExample {
public static void main(String[] args) throws Exception {
// get all the mixers
Mixer.Info[] mixInfo = AudioSystem.getMixerInfo();
System.out.println("Mixers");
for (int i=0; i<mixInfo.length; i++)
System.out.println(" " + mixInfo[i].toString());
// this is just source data, you can use whatever here
// this file is from JavaSound, it is over 400k so might
// take a while to download
URL url = new URL("http://www.knutejohnson.com/22-new.aif");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
// format will probably be determined by source as in this case
AudioFormat af = ais.getFormat();
System.out.println(af.toString());
// get a SDL with specified format from specified mixer
SourceDataLine sdl = AudioSystem.getSourceDataLine(af,mixInfo[0]);
// open requires the format too
sdl.open(af);
// no sound until SDL is started
sdl.start();
// read and write
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = ais.read(buf)) != -1)
sdl.write(buf,0,bytesRead);
ais.close();
// empty the buffer
sdl.drain();
// stop the line
sdl.stop();
// close it cause we're done
sdl.close();
}
}
/*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to
use, * modify and redistribute this software in source and binary code
form, * provided that i) this copyright notice and license appear on all
copies of * the software; and ii) Licensee does not utilize the software
in a manner * which is disparaging to Sun. * * This software is provided
"AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED
CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED
WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR *
NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
MODIFYING * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT
WILL SUN OR ITS * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR
DATA, OR FOR DIRECT, * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF
LIABILITY, ARISING OUT OF THE USE OF * OR INABILITY TO USE SOFTWARE, EVEN
IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * This
software is not designed or intended for use in on-line control of *
aircraft, air traffic, aircraft navigation or aircraft communications; or
in * the design, construction, operation or maintenance of any nuclear *
facility. Licensee represents and warrants that it will not use or *
redistribute the Software for such purposes. */
import javax.sound.sampled.*;
public class ListPorts {
public static void main(String[] args) {
Mixer.Info[] aInfos = AudioSystem.getMixerInfo();
for (int i = 0; i < aInfos.length; i++) {
try {
Mixer mixer = AudioSystem.getMixer(aInfos[i]);
mixer.open();
try {
System.out.println(aInfos[i]);
printPorts(mixer, mixer.getSourceLineInfo());
printPorts(mixer, mixer.getTargetLineInfo());
} finally {
mixer.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
if (aInfos.length == 0) {
System.out.println("[No mixers available]");
}
System.exit(0);
}
public static void printPorts(Mixer mixer, Line.Info[] infos) {
for (int i = 0; i<infos.length; i++) {
try {
if (infos[i] instanceof Port.Info) {
Port.Info info = (Port.Info) infos[i];
System.out.println(" Port "+info);
Port port = (Port) mixer.getLine(info);
port.open();
try {
printControls(port.getControls());
} finally {
port.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void printControls(Control[] controls) {
for (int i = 0; i<controls.length; i++) {
printControl(" ", "Controls["+i+"]: ", controls[i]);
}
if (controls.length == 0) {
System.out.println(" [no controls]");
}
}
static boolean balanceTested = false;
public static void printControl(String indent, String id, Control
control) {
if (control instanceof BooleanControl) {
BooleanControl ctrl = (BooleanControl) control;
System.out.println(indent+id+"BooleanControl: "+ctrl);
//try {
// Thread.sleep(500);
// ctrl.setValue(!ctrl.getValue());
// Thread.sleep(500);
// ctrl.setValue(!ctrl.getValue());
//} catch (Exception e) {}
}
else if (control instanceof CompoundControl) {
CompoundControl ctrl = (CompoundControl) control;
Control[] ctrls = ctrl.getMemberControls();
System.out.println(indent+id+"CompoundControl: "+control);
for (int i=0; i<ctrls.length; i++) {
printControl(indent+" ", "MemberControls["+i+"]: ", ctrls[i]);
}
}
else if (control instanceof EnumControl) {
EnumControl ctrl = (EnumControl) control;
Object[] values = ctrl.getValues();
Object value = ctrl.getValue();
System.out.println(indent+id+"EnumControl: "+control);
for (int i=0; i<values.length; i++) {
if (values[i] instanceof Control) {
printControl(indent+" ", "Values["+i+"]:"+
((values[i]==value)?"*":""), (Control) values[i]);
} else {
System.out.println(indent+" Values["+i+"]:"+
((values[i]==value)?"*":"")+values[i]);
}
}
}
else if (control instanceof FloatControl) {
FloatControl ctrl = (FloatControl) control;
System.out.println(indent+id+"FloatControl: "+ctrl);
//try {
// Thread.sleep(500);
// float x = ctrl.getValue();
// ctrl.setValue((float) (Math.random()*(ctrl.getMaximum() -
// ctrl.getMinimum()) + ctrl.getMinimum())); // Thread.sleep(1000);
// ctrl.setValue(x); //} catch (Exception e) {} //if (ctrl.getType() ==
// FloatControl.Type.BALANCE && !balanceTested) {
// balanceTested = true;
// for (float y = -1.0f; y<=1.0f; y+=0.02) { // ctrl.setValue(y);
// System.out.println(" Set to "+y);
// System.out.println(" res"+ctrl.getValue()); // } //}
} else {
System.out.println(indent+id+"Control: "+control);
}
}
}
--
Knute Johnson
email s/nospam/knute/