0

I am trying to receive sound from an android app. So far i'm able to send DatagramPacket from the android app. But when i try to receive that DatagramPacket in my JAVA server in my localhost java.lang.IllegalArgumentException is shown.

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();
    }
}

}

When i try to send the audio to the server the Java class server throws this exception. This is produced by volumeControl.setValue(100.0f);. Because when i set volumeControl.setValue(6.0);, this all works perfectly fine. What is causing this error and is there any way to fix it?

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)
  • Obviously the maximum value is 6.0206. Why do you want to set the value to 100.0? – Seelenvirtuose Sep 19 '14 at 06:53
  • http://stackoverflow.com/questions/15955958/android-audiorecord-to-server-over-udp-playback-issues here they set the value 100.0f and it works. So i think this can be set. –  Sep 19 '14 at 06:56
  • That would depend on the maximum that was set when the `FloatControl` was created. You can query the maximum by first getting the `MASTER_GAIN` `FloatControl` with `line.getControl(FloatControl.Type.MASTER_GAIN)` and then call `getMaximum()` on the returned object. I can't say that I understand why you'd even want to try applying 100dB of gain on a stream. – Michael Sep 19 '14 at 07:20

1 Answers1

0

The range of a FloatControl may vary depending on the SourceDataLine so you must use the FloatControl.getMinimum() and FloatControl.getMaximum() methods to find out the range you are allowed to set.

You can also call FloatControl.getUnits() to get a string telling you the units of the control (usually dB).

FloatControl.getPrecision() gives you the precision of the control.

As an example on my Mac speakers the Master Gain range is -80.0 - 6.0206 dB.

greg-449
  • 109,219
  • 232
  • 102
  • 145