java - 如何在Java中将播放音频保存为WAV格式

标签 java audio wav javasound

我正在使用waywardgeek开发的Sonic算法来加快和减慢音频文件的速度。一切正常。但是我需要的是将播放音频保存到wav文件中。我尝试使用ByteArrayInputStreamTargetDataLink保存。但是我做不到。因此,有人可以帮助我将播放音频保存到wav文件吗?而且,我还是Java Audio的新手。

这是代码,

Main.java

import java.io.File;
import java.io.IOException;

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

public class Main {

    private static void runSonic(
            AudioInputStream audioStream,
            SourceDataLine line,
            float speed,
            float pitch,
            float rate,
            float volume,
            boolean emulateChordPitch,
            int quality,
            int sampleRate,
            int numChannels) throws IOException {
        Sonic sonic = new Sonic(sampleRate, numChannels);
        int bufferSize = line.getBufferSize();
        byte inBuffer[] = new byte[bufferSize];
        byte outBuffer[] = new byte[bufferSize];
        int numRead, numWritten;

        sonic.setSpeed(speed);
        sonic.setPitch(pitch);
        sonic.setRate(rate);
        sonic.setVolume(volume);
        sonic.setChordPitch(emulateChordPitch);
        sonic.setQuality(quality);
        do {
            numRead = audioStream.read(inBuffer, 0, bufferSize);
            if (numRead <= 0) {
                sonic.flushStream();
            } else {
                sonic.writeBytesToStream(inBuffer, numRead);
            }
            do {
                numWritten = sonic.readBytesFromStream(outBuffer, bufferSize);
                if (numWritten > 0) {
                    line.write(outBuffer, 0, numWritten);
                }
            } while (numWritten > 0);
        } while (numRead > 0);
    }

    public static void main(String[] argv) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
        float speed = 1.0f;
        float pitch = 1.0f;
        float rate = 1.5f;
        float volume = 1.0f;
        boolean emulateChordPitch = false;
        int quality = 0;

        AudioInputStream stream = AudioSystem.getAudioInputStream(new File("C:\\audio1.wav"));
        AudioFormat format = stream.getFormat();
        int sampleRate = (int) format.getSampleRate();
        int numChannels = format.getChannels();
        SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class, format,
                ((int) stream.getFrameLength() * format.getFrameSize()));
        SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
        line.open(stream.getFormat());
        line.start();
        runSonic(stream, line, speed, pitch, rate, volume, emulateChordPitch, quality,
                sampleRate, numChannels);
        line.drain();
        line.stop();
    }
}

我尝试使用以下代码,并将其保存到wav文件,但是在播放时具有单字音频。还有TargetDataLink,什么都行不通。
byteArrayOutputStream = new ByteArrayInputStream(outBuffer);
audioStreams = new AudioInputStream(byteArrayOutputStream, line.getFormat(), bufferSize);
AudioSystem.write(audioStreams, AudioFileFormat.Type.WAVE, new File("C:\\audio2.wav"));

Sonic.java

由于允许的字符数有限,因此无法在此处发布完整的代码。代码是here

PS:该代码由Bill Cox开发。谢谢Bill Cox提供的出色代码。

最佳答案

我已经尝试过,现在我想出了一个使用ByteArrayInputStreamByteArrayOutputStream的解决方案。首先,我使用outBufferByteArrayOutputStream SourceDataLine一起写line.write()。然后将其转换为byteArray并使用AudioInputStream保存。 java2s中的这个tutorial帮助我做到了。它正在工作,但我不知道这是否是最佳解决方案。因此,欢迎提出任何建议。谢谢。

import java.io.File;
import java.io.IOException;

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

public class Main {

    private static void runSonic(
            AudioInputStream audioStream,
            SourceDataLine line,
            float speed,
            float pitch,
            float rate,
            float volume,
            boolean emulateChordPitch,
            int quality,
            int sampleRate,
            int numChannels) throws IOException {
        Sonic sonic = new Sonic(sampleRate, numChannels);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        int bufferSize = line.getBufferSize();
        byte inBuffer[] = new byte[bufferSize];
        byte outBuffer[] = new byte[bufferSize];
        int numRead, numWritten;

        sonic.setSpeed(speed);
        sonic.setPitch(pitch);
        sonic.setRate(rate);
        sonic.setVolume(volume);
        sonic.setChordPitch(emulateChordPitch);
        sonic.setQuality(quality);
        do {
            numRead = audioStream.read(inBuffer, 0, bufferSize);
            if (numRead <= 0) {
                sonic.flushStream();
            } else {
                sonic.writeBytesToStream(inBuffer, numRead);
            }
            do {
                numWritten = sonic.readBytesFromStream(outBuffer, bufferSize);
                if (numWritten > 0) {
                    line.write(outBuffer, 0, numWritten);
                    byteArrayOutputStream.write(outBuffer, 0, numWritten);
                }
            } while (numWritten > 0);
        } while (numRead > 0);
        byte audioBytes[] = byteArrayOutputStream.toByteArray();
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(audioBytes);
        AudioFormat format = line.getFormat();

        AudioInputStream audioInputStream = new AudioInputStream(byteArrayInputStream, format, audioBytes.length / format.getFrameSize());
        AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, new File("C:\\audio2.wav"));

    }

    public static void main(String[] argv) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
        float speed = 1.0f;
        float pitch = 1.0f;
        float rate = 1.5f;
        float volume = 1.0f;
        boolean emulateChordPitch = false;
        int quality = 0;

        AudioInputStream stream = AudioSystem.getAudioInputStream(new File("C:\\audio1.wav"));
        AudioFormat format = stream.getFormat();
        int sampleRate = (int) format.getSampleRate();
        int numChannels = format.getChannels();
        SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class, format,
                ((int) stream.getFrameLength() * format.getFrameSize()));
        SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
        line.open(stream.getFormat());
        line.start();
        runSonic(stream, line, speed, pitch, rate, volume, emulateChordPitch, quality,
                sampleRate, numChannels);
        line.drain();
        line.stop();
    }
}

关于java - 如何在Java中将播放音频保存为WAV格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56513351/

相关文章:

java 。全局JLabels

java - 所有功能文件均未执行

java - 如何只在for循环中的所有条件都为真时才返回true?

java - 我想知道java中一行的含义

Android Studio - SoundPool - 手指从ImageView拿开后停止声音

java - AudioSystem.write(input, AudioFileFormat.Type.WAVE, file) 生成损坏的 WAVE 文件。 RIFF 长度无效

android - 在 Android 上将 mp3 转换为 wav

android - 有没有办法将播放/暂停放在同一个按钮中?

c# - 如何检查两个.wav文件是否包含相同的声音数据?

python - wave.Error : unknown format: 3 arises when trying to convert a wav file into text in Python