我正在尝试从Android应用程序接收声音。到目前为止,我已经能够从android应用程序发送DatagramPacket。但是,当我尝试在我的本地主机java.lang.IllegalArgumentException的JAVA服务器中接收该DatagramPacket时,将显示该消息。

public class Server {

AudioInputStream audioInputStream;
static AudioInputStream ais;
static AudioFormat format;
static boolean status = true;
static int port = 8888;
static int sampleRate = 44100;

public static void main(String args[]) throws Exception {

    System.out.println("entering");
    DatagramSocket serverSocket = new DatagramSocket(8888);

    /**
     * Formula for lag = (byte_size/sample_rate)*2 Byte size 9728 will
     * produce ~ 0.45 seconds of lag. Voice slightly broken. Byte size 1400
     * will produce ~ 0.06 seconds of lag. Voice extremely broken. Byte size
     * 4000 will produce ~ 0.18 seconds of lag. Voice slightly more broken
     * then 9728.
     */

    byte[] receiveData = new byte[4000];

    format = new AudioFormat(sampleRate, 16, 1, true, false);

    while (status == true) {
        DatagramPacket receivePacket = new DatagramPacket(receiveData,
                receiveData.length);

        serverSocket.receive(receivePacket);

        ByteArrayInputStream baiss = new ByteArrayInputStream(
                receivePacket.getData());

        ais = new AudioInputStream(baiss, format, receivePacket.getLength());

        toSpeaker(receivePacket.getData());


    }
}

public static void toSpeaker(byte soundbytes[]) {
    try {
        System.out.println("I am in to speaker");
        DataLine.Info dataLineInfo = new DataLine.Info(
                SourceDataLine.class, format);
        SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem
                .getLine(dataLineInfo);

        sourceDataLine.open(format);

        FloatControl volumeControl = (FloatControl) sourceDataLine
                .getControl(FloatControl.Type.MASTER_GAIN);
        volumeControl.setValue(100.0f);

        sourceDataLine.start();
        sourceDataLine.open(format);

        sourceDataLine.start();

        System.out.println("format? :" + sourceDataLine.getFormat());

        sourceDataLine.write(soundbytes, 0, soundbytes.length);
        System.out.println(soundbytes.toString());
        sourceDataLine.drain();
        sourceDataLine.close();
    } catch (Exception e) {
        System.out.println("Not working in speakers...");
        e.printStackTrace();
    }
}

}

当我尝试将音频发送到服务器时,Java类server抛出此异常。这是由volumeControl.setValue(100.0f);产生的。因为当我设置volumeControl.setValue(6.0);时,这一切都很好。是什么导致此错误,有什么办法可以解决?
java.lang.IllegalArgumentException: Requested value 100.0 exceeds allowable maximum value 6.0206.
at javax.sound.sampled.FloatControl.setValue(FloatControl.java:218)
at com.sun.media.sound.DirectAudioDevice$DirectDL$Gain.setValue(DirectAudioDevice.java:853)
at com.company.Server.toSpeaker(Server.java:72)
at com.company.Server.main(Server.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

最佳答案

FloatControl的范围可能随SourceDataLine的不同而有所不同,因此您必须使用FloatControl.getMinimum()FloatControl.getMaximum()方法来找出允许设置的范围。

您还可以调用FloatControl.getUnits()以获取一个字符串,告诉您控件的单位(通常为dB)。
FloatControl.getPrecision()为您提供控件的精度。

例如,在我的Mac扬声器上,主增益范围是-80.0-6.0206 dB。

08-28 13:55