torchaudio音频基础知识学习

torchaudio音频基础知识学习


贴出本文学习的主要来源: pytorch官网torchaudio的学习文档

需要使用的工具函数

import torchaudio
import torch
import matplotlib.pyplot as plt
import librosa


# 绘制波形图
def plot_waveform(waveform, sample_rate):
    waveform = waveform.numpy()
    num_channels, num_frames = waveform.shape
    time_axis = torch.arange(0, num_frames) / sample_rate

    figure, axes = plt.subplots(num_channels, 1)
    if num_channels == 1:
        axes = [axes]
    for c in range(num_channels):
        axes[c].plot(time_axis, waveform[c], linewidth=1)
        axes[c].grid(True)
        if num_channels > 1:
            axes[c].set_ylabel(f"Channel {c + 1}")
    figure.suptitle("waveform")
    plt.show()


# 绘制频频谱图
def plot_specgram(waveform, sample_rate, title="Spectrogram"):
    waveform = waveform.numpy()
    num_channels, num_frames = waveform.shape

    figure, axes = plt.subplots(num_channels, 1)
    if num_channels == 1:
        axes = [axes]
    for c in range(num_channels):
        axes[c].specgram(waveform[c], Fs=sample_rate)
        if num_channels > 1:
            axes[c].set_ylabel(f"Channel {c + 1}")
    figure.suptitle(title)
    plt.show()

# 绘制梅尔频谱图
def plot_spectrogram(specgram, title=None, ylabel="freq_bin"):
    fig, axs = plt.subplots(1, 1)
    axs.set_title(title or "Spectrogram(db)")
    axs.set_ylabel(ylabel)
    axs.set_xlabel("frame")
    im = axs.imshow(librosa.power_to_db(specgram), origin="lower", aspect="auto")
    fig.colorbar(im, ax=axs)
    plt.show()

前置知识

  • sample_rate: 采样率

    从原始音频中一秒钟采样的次数,可以得到sample_rate个采样点,每个采样点就是一个数值。原始的音频可以用波形图表示,包含了音量(振幅)、音频(频率)等各种信息,这里的采样就是直接将波形图上的值(可以简单理解为正弦、余弦图上的函数值)量化成数值。因为波形图是连续的,我们没法做到全部采样,只能离散的采样一些值,单位时间采样的值越多,采样率越高,保存的信息就越多,音频质量就越好。

  • bit_per_sample: 位深

    采样率中我们提到量化的概念,位深与此有关。常见的位深有 8bit,16bit等,以8bit为例,我们可以将波形图沿竖直方向切分成 2^8(256)份,每个采样点的取值为0-255 .

  • num_channels: 声道数

    单声道,双声道,从多个声源采样。声源数量不同,立体音乐就有多个声道,效果更好。

  • encoding : 采样使用的编码格式

    了解的有限。。大概有“PCM_S”、“MP3”、“PCM_U”、“ULAW”、“GSM”等音频编码格式。

  • frames: 音频帧

    简单来讲,就是一组采样点的集合。 语音信号是一个非稳态的、时变的信号。但在短时间范围内可以认为语音信号是稳态的、时不变的,这个短时间一般取 10-30ms。进行语音信号处理时,为减少语音信号整体的非稳态、时变的影响,从而对语音信号进行分段处理,其中每一段称为一帧,帧长一般取 25ms。为了使帧与帧之间平滑过渡,保持其连续性,分帧一般采用交叠分段的方法,保证相邻两帧相互重叠一部分,末尾不足部分用零填充。相邻两帧的起始位置的时间差称为帧移,我们一般在使用中帧移取值为 10ms。

    采样率为16kHz的音频,假设帧长为25ms,一帧就有16000*0.025=400个采样点。(一秒音频有16k个采样点)。从音频开始处,划分帧,但是帧与帧之间会有重叠。

    但是在torchaudio中num_frames似乎表示的一段一音频中采样点的数量,而非帧的数量???刚开始的时候把我看迷糊了

音频的表示形式

waveform波形图

我们称原始的音频信号为波形, 绘制waveform代码如下:

from torchaudio.utils import download_asset

# 使用download_asset从网上下载音频文件保存到本地,返回本地文件路径
SAMPLE_WAV = download_asset("tutorial-assets/Lab41-SRI-VOiCES-src-sp0307-ch127535-sg0042.wav")
print(SAMPLE_WAV)

# 本地的音频文件路径
audio_file_path = SAMPLE_WAV
metadata = torchaudio.info(SAMPLE_WAV)
print(metadata)
# load中可以传入音频文件的路径(path-like)或者原始的音频文件数据(file-like)
# waveform是一个tensor数据,size:(channels,num_frames),官方写的是num_frames,我理解的是采样点的个数num_samples
waveform, sample_rate = torchaudio.load(SAMPLE_WAV)
plot_waveform(waveform,sample_rate)

image-20221118235239790


spectrogram 语谱图/时频图

在介绍spectrogram之前,这里先简单介绍一下时域和频域,频谱图

基于MATLAB的语音信号频谱分析及滤波-云社区-华为云

频谱图:简单理解为频率分布图,复杂的信号主要在于信号中包含了不同频率成分的信号。在时域信号上使用傅里叶变换(FT)就能得到信号的频域表示

横坐标为各种不同的频率,纵坐标为振幅值

波形实质上是将各个频率的波形叠加在了一起(波形是由各频率不同幅值和相位的简单正弦波复合叠加得到的。)表示的是一个静态的时间点上各频率正弦波的幅值大小的分布状况。下面的图非常典型,可以加深理解。

img

关于时域、频域、时频域的更多分析,可以参考下面这篇博客:https://blog.csdn.net/Robin_Pi/article/details/109204672

关于语谱图更加详细的信息可以参考这篇博客,个人认为非常清晰了。
https://blog.csdn.net/chumingqian/article/details/123019808

下面进入正题,spectrogram是使用短时傅里叶变换得到信号的频谱图。ps:百度百科的介绍是这样的,按我的理解频谱图应该就是频域图,只包含频域信息??这个百度百科的介绍我有点迷惑。

刚入门语音处理,好多基础知识都快把我搞迷糊了,继续坚持😭😭

anyway,大家更多的称spectrogram 为语谱图/时频图/声谱图,语谱图是声音数据通过STFT(短时傅立叶变换)转换得到的。短时很好理解,就是将一段语音信号分成多帧,每一帧包含了一小段时间的语音信号,帧变成了分析处理的基本单元。

语谱图上横轴为时间,纵轴为频率,用颜色表示幅度,可以得到信号的时频分布。经常还对幅度进行相应的转换,得到功率表示(amplitude squared振幅的平方),或者db表示【 10 * log10(S / ref)】。

image-20221118235447264

torchaudio中绘制spectrogram 语谱图的代码:

# waveform和sample_rate见上文绘制波形图
plot_specgram(waveform,sample_rate) #详细见工具函数

melSpectrogram 梅尔频谱

声谱图对频率范围维持了原始的audio的频率范围,但这个对人耳来说不是好事,人对声音的敏感区域和敏感度有自己的特点。频率的单位是赫兹(Hz),人耳能听到的频率范围是20-20000Hz,但人耳对Hz这种标度单位并不是线性感知关系,所以我们把频率转换到了mel scale尺度下,人的感知在mel scale下就是线性关系。

人耳对低频信号的区别更加敏感,而对高频信号的区别不是那么敏感。在低频段上的两个频度和高频上的两个频度,人们会更容易区分前者。也就是说,频域上相等距离的两对频度,对于人耳来说他们的距离不一定相等。

那么,能不能调整频域的刻度,使得这个新的刻度上相等距离的两对频度,对于人耳来说也相等呢?答案是可以的,这就是梅尔刻度。

在语谱的基础上,我们可以得到梅尔频谱,简单的来讲,梅尔频谱就是将原来的语谱图上的频率刻度转换成梅尔刻度,这是通过梅尔滤波器组(mel-scale filter banks)转换得到的。其实经过这种转换之后,在频度这一维度上,维度是降低了,例如:原来一段语音信号的语谱图中纵坐标(频度Hz)有513个刻度,经过转换之后,变成了mel freq刻度,只有128个刻度。

因此用来表示这段语音信号的数据量减少了,因此在模型训练中使用的话可以大幅减少cost。例如:语谱图中的数据表示(513,359),513是频度(Hz)刻度,359是num_frames(语音信号分成的帧数),变成梅尔频谱后,数据表示为(128,359),数据量约为原来的1/4。

但是!!

既然降维了,那么原本数据的信息必然损失了一部分,但因为梅尔刻度是针对人耳设计的,因此梅尔频谱很大程度上保留了人耳理解原本语音所需的信息,这就是梅尔频谱的精髓所在。

梅尔频谱图

绘制出的梅尔频谱图,横坐标表示帧数(与语谱图似乎有些不对应,语谱图貌似表示的是时间,但是其实语谱图也是分成了多帧,但是相当于做了一个简单的变换,当前帧数/总帧数 音频时长,即可转换成时间),纵坐标表示梅尔刻度下的频度,颜色表示幅度(幅度做一定的变化,平方可以转成功率/能量,在取对数运算转成db)。所以并不总是,一定表示的是 时间-频度-幅度 的三维信息,也可以是时间-频度-功率* 图等等。

image-20221119000247938

torchaudio中绘制梅尔频谱图的代码如下:

import torchaudio.transforms as T

n_fft = 1024
win_length = None
hop_length = 512
n_mels = 128
mel_spectrogram = T.MelSpectrogram(
    sample_rate=sample_rate,
    n_fft=n_fft,
    win_length=win_length,
    hop_length=hop_length,
    center=True,
    pad_mode="reflect",
    power=2.0,
    norm="slaney",
    onesided=True,
    n_mels=n_mels,
    mel_scale="htk",
)
melspec = mel_spectrogram(waveform)
plot_spectrogram(melspec[0], title="MelSpectrogram - torchaudio", ylabel="mel freq")

总结

这篇文章是我在入坑深度学习、语音合成(TTS)的基础知识的学习记录,其实期间遇到了不少令人费解的知识点,看了一些博客与文档,算是大致掌握了一些基础的知识,但其实比较细致的东西没有深究,但总体来说,对语音数据的表示有了更加深刻的了解,希望之后能够继续坚持下去。

ps:本文只介绍了语音信号的几种表示形式,波形、语谱、梅尔频谱三种比较常见的表达方式,但其实像MFCC也比较常见,但并没有介绍,这里给出pytorch官网的一张图片,给一个概览,各种语音信号表示形式以及它们之间的转换。

https://download.pytorch.org/torchaudio/tutorial-assets/torchaudio_feature_extractions.png

  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值