2

我正在玩麦克风来采样例如我的声音。为此,我使用 javax.sound.sampled 包。

但是,仅对麦克风进行采样时,我的 CPU 使用率非常高。该代码可在此处获得:

http://91.121.120.36:8081/root/gui-freq/blob/6b470aaf03038562578e4386c6774fbaca9f1fbc/src/main/java/fr/lelouet/audio/sampler/MicSampler.java

在 main 中执行的唯一代码如下:

        line = (TargetDataLine) AudioSystem.getLine(info);
        line.open();
        line.start();
        float[] newSamples = new float[samplesBufferSize];
        byte[] copybuffer = new byte[newSamples.length * SAMPLE_SIZE_BYTE];
        long lastTime = System.currentTimeMillis();
        while (run) {
            // synchronized so we don't have a problem of collecting the data when
            // we should be stopped.
            synchronized (LISTENLOCK) {
                long begin = System.currentTimeMillis();
                line.read(copybuffer, 0, copybuffer.length);
                long read = System.currentTimeMillis();
                for (int i = 0; i < newSamples.length; i++) {
                    // convert the buffer of 2 bytes to an int
                    newSamples[i] = copybuffer[SAMPLE_SIZE_BYTE * i] << 8
                            | copybuffer[SAMPLE_SIZE_BYTE * i + 1] & 0xFF;
                }
                long convert = System.currentTimeMillis();
                addSamples(newSamples);
                long add = System.currentTimeMillis();
                System.err.println("delay=" + (begin - lastTime) + " read="
                        + (read - begin) + " convert=" + (convert - read) + " add="
                        + (add - convert));
                lastTime = add;
            }
        }

我使用 System.err 来调试 CPU 使用率值,这给了我类似的东西:

delay=1 read=788 convert=0 add=0

这意味着代码大部分时间都在 line.read 调用中使用。

同时 top 为 java 返回 120% 的 CPU 时间。

我发现这种高 CPU 使用率太昂贵了。在我看来,代码将在 while(true) 循环中主动寻找数据。我错了吗 ?我应该如何更改我的代码?

编辑 :

我在读取数据之前添加了一个等待:

                long remaining = copybuffer.length - line.available();
                while (remaining > 0) {
                    long ms = (long) (1000 * remaining / format.getSampleRate() / SAMPLE_SIZE_BYTE);
                    if (ms > 5) {
                        try {
                            Thread.sleep(ms);
                        } catch (InterruptedException e) {
                        }
                    }
                    remaining = copybuffer.length - line.available();
                }

我现在的 CPU 使用率 <5%,大部分时间都花在等待循环而不是 read() 上。它确认 read() 包含一个活动循环。

4

0 回答 0