AudioInputStream:macOS和8位wav文件上Java 1.7和1.8的弹出噪音

AudioInputStream:macOS和8位wav文件上Java 1.7和1.8的弹出噪音,java,macos,audio,java-8,Java,Macos,Audio,Java 8,我在使用AudioInputStream播放样本时遇到了一个奇怪的问题。 三种情况: macOS,Java1.6:工作完美 win,Java1.8:工作完美 macOS,java 1.8:沉重的流行音乐 我为测试而创建的代码是直截了当的。样品是干净的(起点和终点的零交叉)。第一个pop已经出现在soundLine.start()上,它完全独立于示例。最后一次弹出发生在soundLine.close()上,在该位置上,采样已在几秒钟后完成。我在代码中添加了一些延迟,因此很容易识别代码所在的位置

我在使用AudioInputStream播放样本时遇到了一个奇怪的问题。 三种情况:

  • macOS,Java1.6:工作完美
  • win,Java1.8:工作完美
  • macOS,java 1.8:沉重的流行音乐
我为测试而创建的代码是直截了当的。样品是干净的(起点和终点的零交叉)。第一个pop已经出现在soundLine.start()上,它完全独立于示例。最后一次弹出发生在soundLine.close()上,在该位置上,采样已在几秒钟后完成。我在代码中添加了一些延迟,因此很容易识别代码所在的位置

我创建了演示视频,您可以在其中听到发生了什么:

  • 在macOS Sierra上(在MBP和iMac上测试。第一次使用Java-8运行,第二次使用Java-6运行。您可以在屏幕上看到使用的Java版本):
  • win上(win7并行运行):
正如您所看到(听到)的,唯一的问题是macOS下的Java1.8。我还用同样的结果测试了Java1.7。只有在1.6上,播放才是正确的。 pop声音听起来很奇怪,因为声音是用我的MBP的内部micro录制的。这是一种典型的流行音乐,当打开/关闭设计糟糕的放大器时,你可以听到这种声音

附录:问题似乎只出现在8位wav文件中。16位工作正常。

附录:平均时间列为错误:

有人能重现这个问题吗?知道原因是什么吗?我目前假设Java中有一个bug

import java.io.File;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;

public class Soundtest
{
    protected File sample=new File("user1.wav");

    public Soundtest()
    {                   
        SourceDataLine soundLine = null;
        int BUFFER_SIZE = 1024; 

        System.out.println("AudioInputStream test with "+System.getProperty("java.version")+" on "+System.getProperty("os.name"));
        // Set up an audio input stream piped from the sound file.
        try 
        {       

            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(sample);
            AudioFormat audioFormat = audioInputStream.getFormat();
            DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);

            //Soundline ist noch nicht angelegt -> angelegen.
            if(soundLine==null)
            {
                soundLine = (SourceDataLine) AudioSystem.getLine(info);
                soundLine.open(audioFormat);
                soundLine.start();
            }
            System.out.println("Started");
            Thread.sleep(2000);

            System.out.println("Playing");
            int nBytesRead = 0;
            byte[] sampledData = new byte[BUFFER_SIZE];
            while (nBytesRead != -1) 
            {
                nBytesRead = audioInputStream.read(sampledData, 0, sampledData.length);
                if (nBytesRead >= 0) 
                {                           
                    soundLine.write(sampledData, 0, nBytesRead);                        
                }                               
            }           
            Thread.sleep(2000);
            System.out.println("Draining");
            soundLine.drain();

            Thread.sleep(2000);
            System.out.println("Closing");
            soundLine.close();
        }           
        catch (Exception e) 
        {
           e.printStackTrace();
        } 

    }

    public static void main(String[] args) 
    {          
        new Soundtest();
    }
}


我看得出你的代码没有问题。我自己在macOS Sierra 10.12.2上用Java 1.8.060运行过,耳机中没有弹出的声音,内部扬声器中也没有弹出的声音。我现在能想到的唯一原因是,出于某种原因,Java 1.8不喜欢您使用的音频接口或媒体,如果它与Mac上的通用扬声器有任何不同的话。甚至有可能在1.8中音频缓冲的方式有所不同。尝试提高缓冲区大小以防止运行不足(这可能是弹出的原因)。

我可以看出您的代码没有任何问题。我自己在macOS Sierra 10.12.2上用Java 1.8.060运行过,耳机中没有弹出的声音,内部扬声器中也没有弹出的声音。我现在能想到的唯一原因是,出于某种原因,Java 1.8不喜欢您使用的音频接口或媒体,如果它与Mac上的通用扬声器有任何不同的话。甚至有可能在1.8中音频缓冲的方式有所不同。尝试提高缓冲区大小以防止运行不足(这可能是弹出的原因)。

这在我的Mac电脑上运行良好。谢谢!我发现它只发生在8位wav文件中。你能确认一下吗?是的,看起来只有8位。这在我的Mac电脑上很好用。谢谢!我发现它只发生在8位wav文件中。你能确认一下吗?是的,它看起来确实是8位OnlyTanks!我不认为这是硬件。MBP、一个旧的MBA和我的iMac也是如此。缓冲区大小没有影响。已经测试过了。除此之外,pop发生在向流提供数据之前。我可以在soundLine.start()之后减少代码并将其剪切,以引发第一次流行。你给了我一个主意!它只发生在8位wav文件中@黑暗骑士,很高兴你能弄明白!谢谢,但是没有用。。。我需要工作8位波形。@Dark.Rider为什么必须是8位?谢谢!我不认为这是硬件。MBP、一个旧的MBA和我的iMac也是如此。缓冲区大小没有影响。已经测试过了。除此之外,pop发生在向流提供数据之前。我可以在soundLine.start()之后减少代码并将其剪切,以引发第一次流行。你给了我一个主意!它只发生在8位wav文件中@黑暗骑士,很高兴你能弄明白!谢谢,但是没有用。。。我需要8位波形。@Dark.Rider为什么必须是8位?