音频响度归一化 - python 实现

        在处理音频样本时,往往我们的音频样本由于录制设备,环境,人发音的音量大小的不同影响,会造成音频响度不统一,分布在一个不同的响度值域上。为了让语音模型更好的学习音频特征,就有必要对音频的响度进行归一化处理,控制在一定的响度值域。

代码实现如下:

# -*- coding: utf-8 -*-
# date:2024
# Author: DataBall
# function: 音频响度归一化

import librosa
import soundfile as sf
import pyloudnorm as pyln
import numpy as np

def get_audio_loudness(voice,sr):
    # 计算音频的响度(以分贝为单位)
    meter = pyln.Meter(sr)
    loudness = meter.integrated_loudness(voice)
    return loudness
def change_audio_loudness(voice,sr,origin_loudness,target_loudness,path_out):
    # 归一化音频到目标响度
    normalized_wav = pyln.normalize.loudness(voice,origin_loudness,target_loudness)

    # 如果归一化后的音频振幅超过1,需要进一步归一化
    if np.abs(normalized_wav).max() > 1.0:
        normalized_wav = normalized_wav / np.abs(normalized_wav).max()

    # 保存归一化后的音频
    sf.write(path_out, normalized_wav, sr)
    print("保存归一化后的音频:{}".format(path_out))

if __name__ == "__main__":
    path_audio_origin = 'audio/m_16.wav'

    y, sr = librosa.load(path_audio_origin, sr=None) # 加载音频文件,返回音频数据和采样率
    print("音频采样率:{}".format(sr))

    origin_loudness = get_audio_loudness(y,sr)
    print("原音频响度 : {:.5f}".format(origin_loudness))
    target_loudness = -20 # 目标响度

    path_audio_out = "audio/normalized_audio.wav"
    change_audio_loudness(y,sr,origin_loudness,target_loudness,path_audio_out)

    #---------------------- 读取修改后的音频的响度信息
    y2, sr2 = librosa.load(path_audio_out, sr=None)
    loudness2 = get_audio_loudness(y2,sr2)
    print("调整后音频响度 loudness: {:.5f}".format(loudness2))

对于的运行log如下:

音频采样率:16000
原音频响度 : -35.06912
保存归一化后的音频:audio/normalized_audio.wav
调整后音频响度 loudness: -20.00000

​​

助力快速掌握数据集的信息和使用方式。

数据也可如此美好!

在Java中实现音频文件的响度归一化,通常涉及到处理音频流并调整其幅度值,使其在整个音轨上保持一致的响度。这个过程通常包含以下几个步骤: 1. **加载音频文件**:使用Java的AudioInputStream或类似库(如JAVE、JFugue等)读取音频数据。 2. **获取采样率和通道数**:了解音频的采样频率和声道数,这对于后续处理非常重要。 3. **计算平均响度**:遍历音频数据,对每个样本点取对数(因为人耳对响度的变化敏感于音频强度的对数),然后求平均,得到当前的平均响度。 4. **标准化**:对于每个样本,减去平均响度,并乘以一个固定的阈值(例如,可以设置为0分贝),使得结果音频的平均响度达到预设的标准。 5. **保存或播放归一化音频**:将处理后的音频数据写回一个新的AudioInputStream,或者通过AudioSystem工具播放。 以下是一个简单的示例代码片段,但这只是一个简化的版本,实际应用中需要处理线程安全和错误处理等问题: ```java import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; public class AudioNormalization { private static final double MAX_DB_GAIN = 0; // Set target maximum dB gain public static void normalize(AudioInputStream audio) throws Exception { int sampleSizeInBytes = audio.getFormat().getSampleSizeInBits() / 8; byte[] buffer = new byte[sampleSizeInBytes]; // Get the total number of frames and their average db level int frameCount = (int) audio.framesToMillisecond(audio.getFrameLength()); float avgDb = calculateAverageDb(audio); // Normalize each frame to the desired max dB while (audio.read(buffer, 0, buffer.length) != -1) { for (byte b : buffer) { double amplitude = Float.intBitsToFloat(BitConverter.getInt(b)) * 0.0078125f; // Convert to float double normalizedAmplitude = Math.max(0, amplitude - avgDb) * AudioUtil.dbToLinear(MAX_DB_GAIN); float normByte = Float.floatToIntBits(normalizedAmplitude); buffer[BitConverter.byteOffset(normByte, 0)] = normByte; } // Write back the normalized audio audio.write(buffer, 0, buffer.length); } audio.close(); } private static float calculateAverageDb(AudioInputStream audio) throws Exception { // ... implement a method to calculate average db over the stream } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值