【问题标题】:Trim wav file method using Javazoom sometimes works使用 Javazoom 修剪 wav 文件方法有时有效
【发布时间】:2014-10-08 00:12:39
【问题描述】:

我正在研究一种将 wav 文件修剪为用户选择的方法。基本思想是使用 Javazoom 的 WaveFile 类编写一个 wav 文件,该文件仅包含用户选择的声音数据。问题是,我编写的代码大约有一半的时间可以完美运行,而另一半的时间它会产生静态。在完全相同的情况下,它似乎可以工作,也可以不工作。 wav 文件在另一个时间由MediaPlayer 加载,并在其他方法中作为输入流。这是问题的可能根源吗?我尝试关闭流并释放MediaPlayer,但仍然遇到同样的问题。

public void TrimToSelection(double startTime, double endTime){ // Time in seconds
    InputStream wavStream = null; // InputStream to stream the wav to trim
    File trimmedSample = null;  // File to contain the trimmed down sample
    File sampleFile = new File(samplePath); // File pointer to the current wav sample

    // If the sample file exists, try to trim it
    if (sampleFile.isFile()){
        trimmedSample = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC), "trimmedSample.wav");
        if (trimmedSample.isFile()) trimmedSample.delete(); // Delete if already exists

        // Trim the sample down and write it to file
        try {
            wavStream = new BufferedInputStream(new FileInputStream(sampleFile));
            // Javazoom class WaveFile is used to write the wav
            WaveFile waveFile = new WaveFile();
            waveFile.OpenForWrite(trimmedSample.getAbsolutePath(), (int)audioFormat.getSampleRate(), (short)audioFormat.getSampleSizeInBits(), (short)audioFormat.getChannels());
            // The number of bytes of wav data to trim off the beginning
            long startOffset = (long)(startTime * audioFormat.getSampleSizeInBits() * audioFormat.getSampleRate() / 4);
            // The number of bytes to copy
            long length = (long)(endTime * audioFormat.getSampleSizeInBits() * audioFormat.getSampleRate() / 4) - startOffset;
            wavStream.skip(44); // Skip the header
            wavStream.skip(startOffset);
            byte[] buffer = new byte[1024 * 16];
            int bufferLength;
            for (long i = startOffset; i < length + startOffset; i += buffer.length){
                bufferLength = wavStream.read(buffer);
                short[] shorts = new short[buffer.length / 2];
                ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
                waveFile.WriteData(shorts, shorts.length);
            }
            waveFile.Close(); // Complete writing the wave file
            wavStream.close(); // Close the input stream
        } catch (IOException e) {e.printStackTrace();}
        finally {
            try {if (wavStream != null) wavStream.close();} catch (IOException e){}
        }
    }
    // Delete the original wav sample
    sampleFile.delete();
    // Copy the trimmed wav over to replace the sample
    trimmedSample.renameTo(sampleFile);
}

更新:我将long startOffset = (long)(startTime * audioFormat.getSampleSizeInBits() * audioFormat.getSampleRate() / 4); 更改为long startOffset = ((long)startTime * audioFormat.getSampleSizeInBits() * (long)audioFormat.getSampleRate() / 4);length 也是如此。出于某种原因,更改演员表的位置似乎已经解决了静态问题(我认为),尽管我不确定为什么。现在,我想我需要调整缓冲循环,因为样本的结尾被切断了。

【问题讨论】:

    标签: java android audio wav


    【解决方案1】:

    我不确定问题的根源,但这可能会帮助您解决问题:RingDroid 是一个开源铃声创建者。它内置了一个波形编辑器。我曾经下载过它并使用波形编辑器(并对其进行了自定义)来完成一个有趣的项目。这可能会帮助您到达您需要去的地方。享受。

    【讨论】:

    • 谢谢,这绝对有帮助。它使用与我基本相同的方法来完成修剪 wav 文件。我可能已经解决了我的代码中的主要问题,但我不知道为什么。在原始帖子中查看我的编辑。
    【解决方案2】:

    我的更新中的问题是 startTime 的演员阵容有效地向下舍入到最接近的秒。下面的代码有效,但我仍然不确定为什么我原来的铸造方法不起作用。

    public void TrimToSelection(double startTime, double endTime){
        InputStream wavStream = null; // InputStream to stream the wav to trim
        File trimmedSample = null;  // File to contain the trimmed down sample
        File sampleFile = new File(samplePath); // File pointer to the current wav sample
    
        // If the sample file exists, try to trim it
        if (sampleFile.isFile()){
            trimmedSample = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC), "trimmedSample.wav");
            if (trimmedSample.isFile()) trimmedSample.delete();
    
            // Trim the sample down and write it to file
            try {
                wavStream = new BufferedInputStream(new FileInputStream(sampleFile));
                // Javazoom WaveFile class is used to write the wav
                WaveFile waveFile = new WaveFile();
                waveFile.OpenForWrite(trimmedSample.getAbsolutePath(), (int)audioFormat.getSampleRate(), (short)audioFormat.getSampleSizeInBits(), (short)audioFormat.getChannels());
                // The number of bytes of wav data to trim off the beginning
                long startOffset = (long)(startTime * audioFormat.getSampleRate()) * audioFormat.getSampleSizeInBits() / 4;
                // The number of bytes to copy
                long length = ((long)(endTime * audioFormat.getSampleRate()) * audioFormat.getSampleSizeInBits() / 4) - startOffset;
                wavStream.skip(44); // Skip the header
                wavStream.skip(startOffset);
                byte[] buffer = new byte[1024];
                int i = 0;
                while (i < length){
                    if (length - i >= buffer.length) {
                        wavStream.read(buffer);
                    }
                    else { // Write the remaining number of bytes
                        buffer = new byte[(int)length - i];
                        wavStream.read(buffer);
                    }
                    short[] shorts = new short[buffer.length / 2];
                    ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
                    waveFile.WriteData(shorts, shorts.length);
                    i += buffer.length;
                }
                waveFile.Close(); // Complete writing the wave file
                wavStream.close(); // Close the input stream
            } catch (IOException e) {e.printStackTrace();}
            finally {
                try {if (wavStream != null) wavStream.close();} catch (IOException e){}
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-25
      • 1970-01-01
      • 2017-05-14
      • 2018-11-28
      • 2017-12-24
      • 1970-01-01
      • 2017-12-25
      相关资源
      最近更新 更多