【问题标题】:Sound class sounds layered and screechy on Windows声音类在 Windows 上听起来分层且刺耳
【发布时间】:2017-07-23 01:39:49
【问题描述】:

所以,当我在 Mac 上时,这个错误并没有发生。但是,当我在 Windows 上时,我多次播放的任何声音开始听起来像是变得刺耳并以令人不快的方式相互叠加。

这是我的 Sound 类中的相关代码:

public class NewerSound {
    private boolean stop = true;
    private boolean loopable;
    private boolean isUrl;
    private URL fileUrl;
    private Thread sound;
    private double volume = 1.0;

    public NewerSound(URL url, boolean loopable) throws UnsupportedAudioFileException, IOException {
        isUrl = true;
        fileUrl = url;
        this.loopable = loopable;
    }

    public void play() {
        stop = false;
        Runnable r = new Runnable() {
            @Override
            public void run() {
                do {
                    try {
                        AudioInputStream in;
                        if(!isUrl)
                            in = getAudioInputStream(new File(fileName));
                        else
                            in = getAudioInputStream(fileUrl);
                        final AudioFormat outFormat = getOutFormat(in.getFormat());
                        final Info info = new Info(SourceDataLine.class, outFormat);
                        try(final SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info)) {
                            if(line != null) {
                                line.open(outFormat);
                                line.start();
                                AudioInputStream inputMystream = AudioSystem.getAudioInputStream(outFormat, in);
                                stream(inputMystream, line);
                                line.drain();
                                line.stop();
                            }
                        }
                    }
                    catch(UnsupportedAudioFileException | LineUnavailableException | IOException e) {
                        throw new IllegalStateException(e);
                    }
                } while(loopable && !stop);
            }
        };
        sound = new Thread(r);
        sound.start();
    }

    private AudioFormat getOutFormat(AudioFormat inFormat) {
        final int ch = inFormat.getChannels();
        final float rate = inFormat.getSampleRate();
        return new AudioFormat(PCM_SIGNED, rate, 16, ch, ch * 2, rate, false);
    }

    private void stream(AudioInputStream in, SourceDataLine line) throws IOException {
        byte[] buffer = new byte[4];
        for(int n = 0; n != -1 && !stop; n = in.read(buffer, 0, buffer.length)) {
            byte[] bufferTemp = new byte[buffer.length];
            for(int i = 0; i < bufferTemp.length; i += 2) {
                short audioSample = (short) ((short) ((buffer[i + 1] & 0xff) << 8) | (buffer[i] & 0xff));
                audioSample = (short) (audioSample * volume);
                bufferTemp[i] = (byte) audioSample;
                bufferTemp[i + 1] = (byte) (audioSample >> 8);
            }
            buffer = bufferTemp;
            line.write(buffer, 0, n);
        }
    }
}

当我使用 NewerSound.play() 方法多次播放相同的声音时,访问相同的资源可能是个问题。

如果需要任何其他详细信息,请告诉我。非常感谢:)

【问题讨论】:

    标签: java windows audio wav


    【解决方案1】:

    您在“流”方法中用于更改音量的方法存在缺陷。您有 16 位编码,因此需要两个字节来导出单个音频值。您需要在乘法之前将两个字节对中的值组合起来,然后将 16 位结果拆分回两个字节。有许多 StackOverflow 线程都有执行此操作的代码。

    我不知道这是否是您描述的问题的全部原因,但绝对有可能,而且肯定需要解决。

    【讨论】:

    • 如果我减去体积的乘法,则不会出现问题。不过,感谢您指出的内容!我已经修改了我的代码以使用上面的 16 位音频。
    猜你喜欢
    • 2019-07-17
    • 2021-12-01
    • 2017-11-15
    • 1970-01-01
    • 2020-04-24
    • 1970-01-01
    • 2014-03-19
    • 1970-01-01
    • 2013-01-26
    相关资源
    最近更新 更多