WAV文件改变采样率(java版)

相关知识,仅供参考: 

一、WAV文件介绍

WAV是一种无损音频文件格式,它包含了音频数据和元数据。在WAV文件中,音频数据以采样率、位深和声道数等信息存储。我们需要读取这些信息并对音频数据进行相应处理。

1.1 WAV 文件结构


RIFF Header:
----------------------------------
Chunk ID(4字节):通常为“RIFF”,标识这是一个RIFF文件。
Chunk Size(4字节):RIFF chunk的大小,不包括Chunk ID和Chunk Size本身。
Format(4字节):通常为“WAVE”,标识这是WAVE文件。

Format Chunk(fmt chunk):
---------------------------------
Subchunk1 ID(4字节):通常为“fmt ”,标识格式子块。
Subchunk1 Size(4字节):此子块的大小。对于PCM格式,通常为16。
Audio Format(2字节):音频格式标识符。对于PCM格式,值为1。
Number of Channels(2字节):声道数,通常为1(单声道)或2(立体声)。
Sample Rate(4字节):采样率,比如44100 Hz。
Byte Rate(4字节):每秒的字节数,计算公式为 Sample Rate * Number of Channels * Bits per Sample / 8。
Block Align(2字节):每个采样帧的字节数,计算公式为 Number of Channels * Bits per Sample / 8。
Bits per Sample(2字节):每个样本的位深度,比如16位。

Data Chunk:
------------------------------
Subchunk2 ID(4字节):通常为“data”,标识数据子块。
Subchunk2 Size(4字节):音频数据的大小。
Data:实际的音频数据。

1.2采样率介绍

采样频率(Sampling Frequency),也称为采样速度或采样率,是指每秒钟从连续信号中提取并组成离散信号的采样数量,用赫兹(Hz)来表示。简单来说,采样频率描述了计算机每秒钟采集多少个声音样本。这一参数对声音文件的音质和音调有直接影响,并且是衡量声卡和声音文件质量的重要标准。

采样频率的倒数叫做采样周期或采样时间,表示的是两个连续采样之间的时间间隔。例如,如果采样频率为 44.1 kHz(即每秒钟采集 44,100 个样本),那么采样周期就是约 22.7 微秒。较高的采样频率通常意味着更高的音频质量,因为它可以捕捉到更细致的声音细节。

1.3采样率与播放速度

采样率(采样频率)会影响音频的播放速度和音质,当采样率发生变化时,音频的播放速度和音高都会受到影响,具体来说:

  1. 播放速度:采样率越高,每秒钟采集的样本越多,相同长度的音频文件在高采样率下会播放得更快。例如,如果你以 44.1 kHz 的采样率播放一个原本是 8 kHz 采样率的音频文件,音频将会比正常速度播放得更快,因为高采样率会导致每秒播放的样本数增多,从而加快播放速度。所以在TTS时候,看服务传输的音频流是多少赫兹的然后再去添加头部元数据信息。

  2. 音高:采样率的变化也会影响音高,如果你将一个低采样率的音频提升到高采样率播放,会使得音频的音高变高,这类似于音频被“加速”了。

1.4采样率转换

由于音频文件的采样率不一定统一,当播放或处理不同采样率的音频时,需要进行采样率转换(Sample Rate Conversion),这种转换的过程包括以下几个步骤:

  1. 重采样:将音频数据从原始采样率转换到目标采样率。重采样的过程涉及到插值和降采样,以确保音频的质量在转换过程中尽可能保持一致。

  2. 时间伸缩:在转换过程中,可能需要对音频进行时间伸缩,以调整播放速度和音高。

  3. 滤波器:在重采样时,通常会使用滤波器来防止混叠效应(Aliasing)并平滑音频信号。

采样率转换可以在音频处理软件或音频播放器中自动完成,但在某些专业的音频处理应用中,用户可能需要手动设置和调整采样率,以获得最佳的音质和播放效果。

二、JSSRC 处理库

实际业务中并不是所有音频的采样率都是统一的,特别是做智能语音,再做ASR过程中,如果音频采样率配置错误,会导致音频识别错误,造成严重的业务灾难。这时候我们需要改变wav音频文件的采样率,以满足特定的需求。现在给大家介绍一个开源的java 音频处理库JSSRC。

2.1. 项目介绍

JSSRC(Java-based Sample Rate Converter),正如其名,是一个旨在提供高质量音频重采样的Java实现。这个项目源于Naoki Shibata的SSRC——一个被广泛认可的C语言版本高精度音频采样率转换器。经过Naohide Sano的努力,将这一杰出的工作转化为Java语言,最终,通过一系列细微但至关重要的调整,形成了今天这样一个易于集成与使用的Java服务,让音频重采样变得前所未有的简单和高效。

github地址:https://github.com/hutm/JSSRC

2.2. 项目技术分析

JSSRC的核心在于它的高效算法移植与优化。原生基于C的SSRC因其在保持音质的同时能有效转换采样率而著称,JSSRC继承了这一优良传统,并且特别适应于Java生态系统。通过利用Java的多线程能力和内存管理特性,JSSRC不仅保证了音频转换的高保真度,还确保了在复杂应用环境中的稳定性和效率。这使得它成为跨平台应用的理想选择,无论是桌面端、Web服务还是移动开发领域。


2.3实例代码

/**
 *
 * 改变wav采样率
 *--------------------
 * @author 赵海洋
 * @date 2024-9-16
 * @des 主要应用与ASR语音识别过程中,部分wav文件采样率与模型的不匹配,导致语音识别错误调整采样 
 *率涉及到重新采样.
 *
 **/
private void simpleDownSample() {
        File BeforeSampleChangedFile = new File(BeforeSampleChangedFilePath);
        File SampleChangedFile = new File(SampleChangedFilePath);
        try {
            FileInputStream fileInputStream = new FileInputStream(BeforeSampleChangedFile);
            FileOutputStream fileOutputStream = new FileOutputStream(SampleChangedFile);
            new SSRC(fileInputStream, fileOutputStream, 8000, 44100,
                    2,
                    2,
                    1, Integer.MAX_VALUE, 0, 0, true);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
}

其中8000就是待转换的采样率,44100就是目标采样率,可以从低转到高,也可以高转低。

 2.4 纯java实现

import com.sun.media.sound.WaveFileReader;
import com.sun.media.sound.WaveFileWriter;

import javax.sound.sampled.*;
import java.io.*;

/**
 *
 * 改变wav采样率
 *--------------------
 * @author 赵海洋
 * @date 2024-9-16
 * @des 主要应用与ASR语音识别过程中,部分wav文件采样率与模型的不匹配,导致语音识别错误调整采样 
 *率涉及到重新采样,即将音频数据按新的采样率进行插值或降采样。这可能涉及复杂的信号处理算法,
 * 通常可以使用现成的库来完成。例如,TarsosDSP库是一个常用的音频处理库,可以用于实现这种功能。
 *
 * */
public class WavReSample {
   
    /**
     *
     * @param newSampleRate 新的采样率
     * @param inputFilePath 需要转化的文件
     * @param outputFilePath  输出的文件路径
     *
     * */
    public static void reSampleRate(int newSampleRate,String inputFilePath,String outputFilePath) throws IOException, UnsupportedAudioFileException {
        try (AudioInputStream inputAIS = AudioSystem.getAudioInputStream(new File(inputFilePath))) {
            AudioFormat inputFormat = inputAIS.getFormat();
            AudioFormat outputFormat = new AudioFormat(
                    AudioFormat.Encoding.PCM_SIGNED,
                    newSampleRate, // New sample rate
                    inputFormat.getSampleSizeInBits(),
                    inputFormat.getChannels(),
                    inputFormat.getFrameSize(),
                    newSampleRate, // New sample rate
                    inputFormat.isBigEndian()
            );
            try (AudioInputStream outputAIS = AudioSystem.getAudioInputStream(outputFormat, inputAIS)) {
                AudioSystem.write(outputAIS, AudioFileFormat.Type.WAVE,  new File(outputFilePath));
            }
        }
    }
    public static void main(String[] args) throws Exception {
        reSampleRate(44100,"E://out.wav","E://output2.wav");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

常生果

喜欢我,请支持我

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值