Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

附录:NumPy的应用—音频数据

一个音频文件是一个一维数组的样本。 每个样本都是一个数字,代表一小块音频信号。 CD的音频每秒可能有44,100个样本,每个样本是-32767到32768之间的整数。 这意味着如果您有一个10秒的CD的WAVE文件,您可以将它装入一个长度为441,000(也就是10 * 44,100)的NumPy数组中。 如果想提取音频的第一秒,只需将该文件加载到一个NumPy数组audio 中,并使用 audio[:44100]即可获取到。

下面是一个音频文件的一个切片:

numpy-audio

利用正弦波频率生成中央C到H音调

正弦波频率是指正弦波的周期性振荡中,每秒钟完成的周期数,通常以赫兹(Hz)为单位表示。具体来说,正弦波的频率表示了它在单位时间内震荡的次数,也可以理解为它的音调高低。例如,440赫兹的正弦波代表在一秒钟内完成440个周期的振荡,通常被称为A4音调,是音乐中的一个常用音调。

以下是中央C到H音调的频率对照表,以及它们对应的频率(赫兹):

音调频率(赫兹)
中央C261.63
D293.66
E329.63
F349.23
G392.00
A440.00
B493.88
H523.25

这些频率是基于国际标准音高记谱法。在这个表格中,中央C的频率为261.63赫兹,依次向上升,每个音调的频率都比前一个音调高一个半音。在音乐理论中,半音是音乐中的基本单位,它表示两个音调之间的最小音高间隔。在半音的音乐系统中,每个半音的频率比前一个半音的频率高约6%,这是因为音高是按对数比例增加的。换句话说,每个半音的频率是前一个半音频率的1.059463094倍。

from scipy.io import wavfile
import numpy as np

def wav_gen(freq, duration, sampling_rate):
    """
    生成示例音频数据(这里假设使用正弦波作为示例音频)
    音频文件的参数:
    freq - 正弦波频率(Hz)
    sampling_rate - 采样率,表示每秒采集的样本数
    duration - 音频时长,单位为秒
    """
    t = np.linspace(0, duration, int(sampling_rate * duration))
    audio_data = np.sin(2 * np.pi * freq * t)
    audio_data_int = np.int16(audio_data * 32767)   # 将音频数据转换为整数型
    return audio_data_int
sampling_rate = 44100
audio = np.array([])
for i in range(0, 16):
    freq = 261.63*1.059463094**(i*2)
    print('frequency: %.2f' %freq)
    audio_data_int = wav_gen(freq = freq,
                            duration=0.5,
                            sampling_rate=44100)
    audio = np.concatenate((audio, audio_data_int))
audio = np.int16(audio)
print('audio array:', audio)
wavfile.write('audio.wav', sampling_rate, audio)      # 保存音频文件
frequency: 261.63
frequency: 293.67
frequency: 329.63
frequency: 370.00
frequency: 415.31
frequency: 466.17
frequency: 523.26
frequency: 587.34
frequency: 659.27
frequency: 740.00
frequency: 830.62
frequency: 932.34
frequency: 1046.52
frequency: 1174.68
frequency: 1318.53
frequency: 1480.00
audio array: [     0   1221   2440 ... -13153  -6580    284]
def play_music(file_path):
    import pygame
    pygame.init()                         # 初始化pygame
    pygame.mixer.music.load(file_path)    # 加载音乐文件
    pygame.mixer.music.play()             # 播放音乐
    print('start play: %s' %file_path)
    while pygame.mixer.music.get_busy():  # 等待音乐播放结束
        pygame.time.Clock().tick(10)
    print('end!')
play_music('audio.wav')
pygame 2.5.2 (SDL 2.28.3, Python 3.11.5)
Hello from the pygame community. https://www.pygame.org/contribute.html
start play: audio.wav
end!

参考:

A Visual Intro to NumPy and Data Representation, https://jalammar.github.io/visual-numpy/