⚠申明: 未经许可,禁止以任何形式转载,若要引用,请标注链接地址。 全文共计3077字,阅读大概需要3分钟
🌈更多学习内容, 欢迎👏关注👀【文末】我的个人微信公众号:不懂开发的程序猿
个人网站:https://jerry-jy.co/❗❗❗知识付费,🈲止白嫖,有需要请后台私信或【文末】个人微信公众号联系我
语音识别之演奏小星星-理解音阶与频率
- 演奏小星星-理解音阶与频率
- 一、任务需求
- 二、任务目标
- 1、掌握音名与频率
- 2、掌握国际标准音和八度
- 3、学习使用librosa计算不同音高对应的频率
- 三、任务环境
- 1、jupyter开发环境
- 2、python3.6
- 3、tensorflow2.4
- 四、任务实施过程
- 1、音名与频率
- 2、八度
- 3、生成音阶
- 4、演奏小星星
- 五、任务小结
- 说明
演奏小星星-理解音阶与频率
一、任务需求
国际标准音是为了方便了音乐理论研究、乐器制作和文化交流而在国际上统一的音高标准。
音名标记C、D、E、F、G、A、B
乐音体系中的各音级,其高度都有一定的标准。音的标准高度,1939年在伦敦的国际会议上决定国际通用的标准(第一国际标准)是440Hz,波长78cm的a音,即以小字一组的a为“标准音”。
国际上有了统一的音高标准,它方便了音乐理论研究、乐器制作和文化交流。机械波约261.6Hz,波长1.3m的c音在乐音体系中叫中央c,它位于基本音级首位。
要求:利用librosa学习音节与频率相关概念及实现
二、任务目标
1、掌握音名与频率
2、掌握国际标准音和八度
3、学习使用librosa计算不同音高对应的频率
三、任务环境
1、jupyter开发环境
2、python3.6
3、tensorflow2.4
四、任务实施过程
1、音名与频率
以国际标准音 A-la-440HZ为准:
字母体系 | 唱各体系 | 频率 |
---|---|---|
C | do | 261.6HZ |
D | re | 293.6HZ |
E | mi | 329.6HZ |
F | fa | 349.2HZ |
G | sol | 392HZ |
A | la | 440HZ |
B | si | 493.8HZ |
八度音的频率关系: 每相邻的两个半音,高音频率是低音频率的“2的1/12次方倍”。 例如国际标准音A的频率是440HZ(因此也被成文A440),那么比它高半音的bB。频率就是: 440 × 2 1 / 12 = 466.13 H Z 440\times2^{1/12}=466.13HZ 440×21/12=466.13HZ。所以,以此类推,一个八度的12个音,连乘下来结果正好得2。通俗一点儿说,高音1的频率是比它低一个八度的那个1的频率的两倍。
为了验证上述表格的频率结论,我们做个实验如下:
# 指定基准频率
base_sound_hz = 440
# 生成音名
pitch_names = ['C','D','E','F','G','A','B']
# 生成音高顺序
pitch_loc = dict(zip(pitch_names,range(len(pitch_names))))
pitch_loc
{‘C’: 0, ‘D’: 1, ‘E’: 2, ‘F’: 3, ‘G’: 4, ‘A’: 5, ‘B’: 6}
2、八度
根据标准音理论,一个全音与全音之间相差 2 2 / 12 2^{2/12} 22/12,一个八度与八度之间正好相差 2 12 / 12 = 2 2^{12/12}=2 212/12=2倍,即一个八度的do,相比下一个八度的do,在频率上刚好相差两倍。
因此音名A为标准音,频率440,下一个全音B的频率应当为:
B = 440*2**(2/12);B
493.8833012561241
根据这个理论,我们可以确定各个音名对应的频率,需要注意的是,音名E和F之间只相差半音,即 2 1 / 12 2^{1/12} 21/12倍,一个八度之内的其他音高之间则是相差一个全音,即 2 2 / 12 2^{2/12} 22/12。自定义函数如下:
def get_pitch_hz(pitch_name):pitch_name = pitch_name.upper()if pitch_loc.get(pitch_name) is not None:if pitch_loc.get(pitch_name)>2:coef_exp = (pitch_loc.get(pitch_name)*2-10)/12else:coef_exp = (pitch_loc.get(pitch_name)*2-9)/12return 440*2**coef_expelse:raise ValueError('没有查询到这个音名!')get_pitch_hz('c')
261.6255653005986
3、生成音阶
有了这个函数,我们就可以尝试生成音乐了。首先生成一个简单的C调do
notation = '1'
pitch_name = pitch_names[int(notation[0])-1]
pitch_name
‘C’
# 使用自定义函数,将音名转换为频率
pitch_hz = get_pitch_hz(pitch_name)
pitch_hz
261.6255653005986
import librosa
# 生成纯音信号do
pitch_sound = librosa.tone(pitch_hz, duration=0.5)
import IPython.display as ipd
ipd.Audio(pitch_sound,rate=22050)
4、演奏小星星
接下来把生成声音的步骤,封装在一个自定义函数
def get_notation_sound(notation):pitch_name = pitch_names[int(notation[0])-1]pitch_hz = get_pitch_hz(pitch_name)pitch_sound = librosa.tone(pitch_hz, duration=0.5)return pitch_sound
ipd.Audio(get_notation_sound('2'),rate=22050)
有了这个函数,我们就可以尝试根据乐谱生成音乐了。例如,我们可以根据下面的小星星乐谱生成音乐。
# 定义小行星简谱
notations = '115566554433221155443322554433221155665544332211'
这里需要注意的是,简谱中的增时线,我们简单的使用增时线前一个音符做为替换。
import numpy as np
# 根据简谱生成音乐
def get_music(notations,rate=22050):tmp_sound = np.array([])for notation in notations:notation_sound = get_notation_sound(notation)notation_sound = np.pad(notation_sound,1000)tmp_sound = np.append(tmp_sound,notation_sound)return tmp_sound
ipd.Audio(get_music(notations),rate=22050)
再尝试一下2倍速播放(本质就是对采样率的调整,单位时间内采样率翻倍,就相当于加速1倍)
ipd.Audio(get_music(notations),rate=44100)
五、任务小结
本实验我们学习了音名、频率、国际标准音和八度等相关概念。
学习使用librosa生成音高对应频率的音频。
根据本实验能发现这样一个现象:人类对频率的认知,并不是线性的,而是指数变化的。这就是为什么很多情况下,我们需要对声音频率做对数变换,其中一个目的,就是为了符合人类的听觉认知。
–end–
说明
本实验(项目)/论文若有需要,请后台私信或【文末】个人微信公众号联系我