【问题标题】:Problem with reading wav file with Java用Java读取wav文件的问题
【发布时间】:2011-05-12 19:33:07
【问题描述】:

我使用该 API 在 Java 中读取 wav 文件:Reading and Writing Wav Files in Java

我用 Java 读取了一个 wav 文件,并希望将所有值放入一个数组列表中。我写道:

// Open the wav file specified as the first argument
     WavFile wavFile = WavFile.openWavFile(fileToRemoveSilence);
     List<Double> allBuffer = new ArrayList<Double>();

 ....
     do {
        // Read frames into buffer
        framesRead = wavFile.readFrames(buffer, 50);
        for (double aBuffer : buffer) {
           allBuffer.add(aBuffer);
        }

     } while (framesRead != 0);

当我在调试器中检查 allBuffer 的大小时,它会显示:

74700

但是在我使用的代码中:

wavFile.display();

它的输出:

....
... Frames: 74613
....

我的 allbuffer 大于该 API 显示的帧。它是怎么来的?

PS:我之前的问题:

Reading wav file in Java

How to divide a wav file into 1 second pieces with Java?

PS2: 我修复了错误,但是当我运行程序时,有时会出现该错误:可能是什么问题?

java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at sun.java2d.Disposer.run(Disposer.java:127)
at java.lang.Thread.run(Thread.java:662)

删除引用时出现异常:java.lang.InterruptedException

【问题讨论】:

  • 很好的文档并标记为很好的评论。还有一件事,那篇文章说原因与 Thread.sleep() 相关。但是代码中没有 sleep() 方法。它是从任何其他方法调用的吗?(即 FileInputStream 的 read 方法或其他任何方法?)
  • 这可能是 WavFile API 在内部执行的操作,除非以多线程方式进行这些调用。

标签: java audio wav


【解决方案1】:

我想你想要这样的东西:

// Open the wav file specified as the first argument
     WavFile wavFile = WavFile.openWavFile(fileToRemoveSilence);
     List<double[]> allBuffer = new List<double[]>();

    int bufferSize = 44100; // 1 second, probably
    double[] buffer;


 ....
     do {
        // Read frames into buffer

        buffer = new double[bufferSize];
        framesRead = wavFile.readFrames(buffer, bufferSize);
        if (framesRead == bufferSize)
        {
            allBuffer.add(buffer);
        }
        else
        {
            double[] crippleBuffer = new double[framesRead];
            Array.Copy(buffer, crippleBuffer, framesRead);
            allBuffer.add(crippleBuffer);
            break;
        }

     } 

这将为您留下一个 List 的 1 秒 double[] 样本数组(实际上,最后一个数组将小于一整秒)。然后,您可以遍历此数组集合并将每个数组转换为单独的 WAV 文件。

【讨论】:

  • 呃,我忘了这是java,不是C#。
【解决方案2】:

从缓冲区复制到列表时,您需要考虑 framesRead。在最后一次通话中,您复制的双精度数比实际从文件中读取的多。 (即与您的第一个链接中的示例代码完全相同)。

【讨论】:

  • 你是对的。我改变了 wavFile.readFrames(buffer, 50);进入 wavFile.readFrames(buffer, 1); (和双[]缓冲区=新双[1];)。但是 allBuffer 的新大小仍然是 74614 而不是 74613 并且 arrayList 的最后两个元素相同?
  • @kamaci,再次阅读我的答案。您无需更改缓冲区大小,只需在从缓冲区复制到 allBuffer 时使用 framesRead 结果值。查看第一个链接中的 ReadExample.java 代码,注意从缓冲区读取时如何使用 framesRead。
猜你喜欢
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 1970-01-01
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多