工具
Kaldi,虽然非常高效,表现也好,但是忒难用,不灵活,总得改C++代码;
PyKaldi,虽然用上了机器学习界宠儿Python,但本质上跟Kaldi还是一回事嘛;
PyTorch-Kaldi,虽然灵活了一些,声学模型也易于修改,但是,跟前面一样,它也还是Kaldi呀;
ESPNET,虽然是基于Python和PyTorch的,但是只支持端到端语音识别,太不全面了;
- 声音四大要素:音高、强弱、长短、音色
- 音高:就是振动的频率不同导致的区别。
- 强弱:就是振动的振幅不同导致的区别。
- 长短:就是振动持续时间的不同导致的区别。
- 音色:音色的区别是由于各种振动,其总能量在泛音各音级上能量分配不同而造成的。
音高
- 中央区的A音符发出的频率为440Hz(表示成”A=440Hz”,或是”A440”),通常被当作“标准音高”。
- 人类对音高的感受与基频成对数性的:对人耳而言,”A220”到”A440”之间的差距跟”A440”到A880”之间相同。
- 广为使用的MIDI标准,将基频f对应成一数字p
基频(基音,fundamental tone)
- 基本频率(或简称基频,fundamental frequency)声音分解为很多正玄波 傅立叶从数学上证明了,任何的一种非正弦的振动,都可以分解为若干个不同频率的正弦波的叠加。),频率最低的波就是基音,其他频率高的为泛音。频率越高分配到的能量越少。
- 而波的频率,从某种程度上来说,正对应了参与振动的弦的长度。假设频率是基音的3倍,那参与振动的弦的长度就是原弦的1/3,呈倒数关系。
- 除了正弦波本身是不存在泛音的,任何其他的振动(或音),都存在无穷多个泛音——我们实际在音乐演奏中无法听到那么多泛音,正是由于频率越高,分配到的能量越少,因此无法实际使用的原因。
- F(ω)= A1f(ω) + A2f(2ω) + A3f(3ω) + A4f(4ω) + A5f(5ω) + A6f(6ω)……
- 这里,f(n ω)代表各种正弦波。而之前的数字,则代表这个正弦波的频率,是原先那个音频率的几倍。而A1 A2…..则代表这个频率的正弦波的振幅,或者说强弱。
- F(ω)就是小提琴拉出的那个音,那A1f(ω)就是基音,这个频率ω,就是基频。
- 基音是区别音高的主要成分,泛音则决定乐器或人声的音色。
泛音(overtones) == 谐波 (Harmonics)
- 泛音(Overtone)在声学和音乐中,指一个声音中除了基频外其他频率的音。
- 频率都是某一频率的倍数,这一频率就称作基频,也就决定了这个音的音高。
- 频率为2f的音称为第一泛音,频率为3f的音称为第二泛音。
- 泛音越充分的声音越饱满。
- 低频泛音越充分的声音听起来越“厚实”,越“有力”。
- 高频泛音越充分的声音穿透力越强,声音听起来越“亮”,越“尖”。
- 高低频都有并且合理分布的声音,就是比较完美的声音。
- 上半部分为声谱图(Spectrogram),下半部分为频谱图(Spectrum)
- 先看上图:横坐标是时间,纵坐标是频率值,同一时间的纵线上存在着数个波,重合而成最终的波。颜色越亮则表示波的振幅越大。混乱的背景都是伴奏,我们只观察人声线。
- 再看下图:下图反映了上图的某个时间点(上图中的黄线)的频率分布。横坐标为频率,纵坐标为振幅。这个图更有利于直观的观察泛音的成分和强弱。
- 所以一个人唱了个C5,那他的基频就大概是500,第一泛音是1000,第二泛音是1500,画到声谱图上的结果就是从下到上每隔500画一个点,根据振幅有颜色的区别。随着时间的推移,声谱图会不断向右延伸,这样我们就得到了一段时间内频率分布图。比如一个C5的线在声谱图上水平延续了5秒,那表示该歌手唱了C5五秒。声谱图上类似“波”的东西是颤音,也就是歌手演唱中不断改变音高,所以自然会不断改变纵坐标。
- 图上的水平线含义:水平线表示一个歌手在某个音高上持续了一段时间。越亮的线表示振幅越大,听感上当然就音量大了。直线就是一个长直音,考察长直音主要看稳定度,整个线越直则这个长音越稳定。如果大抖就是破音,如果小抖就是不稳。如果歪了,那就是音准没把握好。
- 波浪线就是颤音。波浪越大则颤音越大。看颤音也是看稳定度,如果颤的不稳就是气息出现问题,控制不好。
- 看泛音主要看三点:丰富与否;分布情况;泛音的音量。对比泛音主要是看与基频的对比。因为音频文件的音量是可以调整的,单纯的看泛音大小没多大意义,以基频为参照才比较有实际意义。(低频的共鸣情况取决于元音的类型,每一个元音都有自己的特定的共鸣特性。一般来说,基频被共鸣强化的情况比较少)
- 此例中第一泛音巨大(看多了就知道,一般都是第一泛音最大),在3000左右的三个泛音也很强。
- 另一种观察方法就是和伴奏比,人声线越明显则人声越强,越能穿透伴奏。
- 这首歌有如此大的高频泛音
- 要知道,这可是清唱,中音区!唱高音的时候鼓足了气,有很大的共鸣很正常,但唱低缓的主歌,竟然也能爆出这么大的泛音!只能说宝哥太逆天。
- 泛音太少,音色暗很多,上面那个比较清亮。
分音 Partials 如何看音准?
- 很明显这个高频差的很远。高频放大了差值
- 基频/第一泛音(基频的二倍)/第二泛音(基频的三倍)
清音和浊音
- 清音——发音时声带不振动;浊音——发音时声带要振动。
- 发浊音时音像是靠口腔前位置发出,听起来吐字重而实,给人以清亮的感觉;发清音时音像是靠口腔后位置发出,听起来吐字轻而虚,有含隐的感觉。
音频合成
- 什么是midi格式?
- 音乐数字接口(Music Instrument Digital Interface,简称MIDI)是一个工业标准的电子通信协议,为电子乐器等演奏设备(如合成器)定义各种音符或弹奏码,容许电子乐器、电脑、手机或其它的舞台演出配备彼此连接,调整和同步,得以即时交换演奏数据。
- MIDI不发送声音,只发送像是音调和音乐强度的数据,音量,颤音和相位[1]等参数的控制信号,还有设置节奏的时钟信号。
- what is WaveNet?
- A Generative Model for Raw Audio
- speech synthesis and text to speech
- based model :concatenative TTS and newly :parametric TTS
- wavenet 模仿原始的波形因此可以可以很好的模拟任何音乐。
- 音频处理和基础就是运用RNN和CNN来处理。
音频基础
- 采样率:从连续的数据中提取数据分析,其实就是离散化的过程。采样率尽可能的高。
- 频域:
- 音频信号分成了三个不同的纯信号,频域中可以表示唯一的值。
- MFC(梅尔频率系数)区别于时域频域的音频表示方法。
节拍跟踪
- 音响闪光灯同步。
- 基于节拍的音乐分类、推荐
- 音频性能分析
- 数字DJ的音频编辑
Madmom
- madmom 是一个音频信号处理库,主要用于音乐信号提取(MIR)
pyAudioAnalysis
- audioAnalysis.py: 主要实现了对命令行语句的执行
audioFeatureExtraction.py: 实现了音频特征抽取的全部功能。包括:一共21个短期时长的特征及计算。此外,为了抽取音频特征的统计特性,也实现了一个中期时长窗口的特征计算。
audioTrainTest.py: 实现了音频分类的过程。可以使用SVM和KNN分类器进行模型训练。此外还提供了方法的封装和常用的训练、评估、特征标准化等工具
audioSegmentation.py: 实现了音频切割的功能,比如固定大小的分割、演讲者数字化等
audioBasicIO.py: 主要提供了一些对音频文件的基础IO操作,如文件读取、格式转换
audioVisualization.py: 提供了一系列功能,来把结果生成友好的和有代表性的图表$ pip install pyAudioAnalysis
音频特征提取工具liborsa
pip install librosa
ffmpeg is very stronger.
librosa.beat:用于检测速度和节拍
librosa.core:用于从磁盘加载音频和计算各种频谱图
librosa.decompose:实现矩阵分解进行谐波和冲击源分离通用频谱图分解
librosa.display:音频特征的显示
librosa.effects:时域音频处理,音高变换和时间拉伸,时域包装器。
librosa.feature:特征提取和操作:色度图,伪常数Q(对数频率)变换,Mel频谱图,MFCC和调谐估计
librosa.filters:滤波器生成色度。伪CQT、CQT等
librosa.onset:其实检测和起始强度计算。
librosa.segment:用于结构分段的函数
librosa.swquence:顺序建模功能
librosa.util:辅助工具(规范化。填充、居中)音频特征提取工具包librosa
- 应用方向
“`
目前MIR的商业应用主要包括: - 推荐系统
目前音乐推荐的应用很多,但很少是基于MIR技术实现的,现在主流技术是通过人工标记或者用户的评论以及收听历史等简介数据进行分类判断,进而实现推荐,但事实上不同音乐本身的相似性是很多的 - 轨道分离及乐器识别
实现音乐的轨道分离,以及从音乐中识别出是何种乐器在演奏 - 自动录音
根据音乐自动转换成MIDI文件或者乐谱 - 音乐分类
根据音乐的产地、艺术家身份、音乐节奏等特征,借助机器学习方法进行5. 音乐分类 - 自动生成音乐
利用数据库训练模式,让机器自主创造音乐
librosa 核心代码
3.1 音频信号提取
load(path[,sr,mono,offset,duration,…]):读取音频文件为时间序列的数据
to_mono(y):转化为单声道
resample(y,orig_sr,target_sr[,res_type,…]):重新采样
get_duration([y,sr,S,n_fft,hop_length,…]):计算音频文件的时长
autocorrelate(y[, max_size, axis]):自动边界识别
zero_crossings(y[, threshold, …]):找到0交叉点
tone(frequency[, sr, length, duration, phi]):返回一个纯音信号
3.2 光谱表示
stft(y[, n_fft, hop_length, win_length, …]):短时傅里叶变换
istft(stft_matrix[, hop_length, win_length, …]):反傅里叶变换
ifgram(y[, sr, n_fft, hop_length, …]):计算瞬时采样频率
3.3 幅度范围
amplitude_to_db(S[, ref, amin, top_db]):转化为db单位的幅值
db_to_amplitude(S_db[, ref]):db单位的响度图转化为幅值光谱图
power_to_db(S[, ref, amin, top_db]):能量光谱图转化为响度db单位的图
db_to_power(S_db[, ref]):响度的光谱图转化为db的响度图
perceptual_weighting(S, frequencies, **kwargs):感知加权的能量光谱图
3.4 时间和频率转化
frames_to_samples(frames[, hop_length, n_fft]):帧指数转化为音频采样指数
frames_to_time(frames[, sr, hop_length, n_fft]):帧到时间的转化
samples_to_frames(samples[, hop_length, n_fft]):采样指数到短时傅里叶变换帧
samples_to_time(samples[, sr]):帧数到时间的转化
time_to_frames(times[, sr, hop_length, n_fft]):时间到傅里叶真数的转化
time_to_samples(times[, sr]):时间到采样数的转化
hz_to_note(frequencies, kwargs):频率到音符的转化
hz_to_midi(frequencies):根据频率得到midi的音符数
midi_to_hz(notes):midi的音符得到频率
midi_to_note(midi[, octave, cents]):将midi数字转化为音符符号
note_to_midi(note[, round_midi]):音符符号转化为midi数字格式
hz_to_mel(frequencies[, htk]):频率转化为梅尔谱
hz_to_octs(frequencies[, A440]):频率转化为八度音符
mel_to_hz(mels[, htk]):梅尔谱到频率转化
octs_to_hz(octs[, A440]):八度音符到频率转化
fft_frequencies([sr, n_fft]):
mel_frequencies([n_mels, fmin, fmax, htk]):梅尔谱到频率的转化
tempo_frequencies(n_bins[, hop_length, sr]):每分钟的节拍转化为矩阵
samples_like(X[, hop_length, n_fft, axis]):特征矩阵转为数组(采样数)
3.5 音高和曲调
estimate_tuning([y, sr, S, n_fft, …]):估计输入音频的曲调
pitch_tuning(frequencies[, resolution, …]):根据音高估计曲调
3.6 节奏和曲速
beat_track([y, sr, onset_envelope, …]):估计节奏
tempo([y, sr, onset_envelope, hop_length, …]):估计曲速
3.7 显示
specshow(data[, x_coords, y_coords, x_axis, …]):显示光谱图
waveplot(y[, sr, max_points, x_axis, …]):振幅包络的波形图
cmap(data[, robust, cmap_seq, cmap_bool, …]):从给定数据中获取默认色彩映射
3.8 光谱特征
3.9 节奏特征
tempogram([y,sr,onset_envelope,…]) 计算临时图:起始强度包络的局部自相关。
3.10 光谱图分解
demo示例
# -*- coding:utf-8 -*-
# /usr/bin/python
# Beat tracking example
#from __future__ import print_function
import librosa
# 1. Get the file path to the included audio example
filename = librosa.util.example_audio_file()
# 2. Load the audio as a waveform `y`
# Store the sampling rate as `sr`
filename = "../datasets/test.wav"
y, sr = librosa.load(filename)
print("y",y,"\nsr",sr)
# 3. Run the default beat tracker
tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr)
print("tempo",tempo, "\nbeat_frames",beat_frames)
print('Estimated tempo: {:.2f} beats per minute'.format(tempo))
# 4. Convert the frame indices of beat events into timestamps
beat_times = librosa.frames_to_time(beat_frames, sr=sr)