首页 文章

识别录制声音中的音符 - 第2部分 - Python

提问于
浏览
1

这是这个问题的延续here .

This is the code I used in order to get the samples:

spf = wave.open(speech,'r')
sound_info = spf.readframes(-1)
sound_info = fromstring(sound_info, 'Int16')

length of sound_info is 194560 ,这是 4.4 times the sample rate of 44100 . 声音文件的长度是 2.2 seconds ,所以sound_info的长度应该是它的两倍吗?

此外,我似乎只能在 why FFTs are used in order to produce the frequency spectrum 找到足够的信息 .

我想将声音分开并分析多个分数秒的频谱,而不是整个声音文件 .


非常感谢帮助 . :)


This is the basic sound_info graph

plot(sound_info)

This is the FFT graph

freq = [abs(x.real) for x in fft(sound_info)]
plot(freq)

2 回答

  • 1

    如果你的wav文件有两个通道,那么 sound_info 的长度将是2 采样率持续时间(秒) . 信道数据候补,因此,如果您已slurpped所有值到1维阵列, data ,然后与一个信道相关联的值将是 data[::2] ,而另一个将是 data[1::2] .


    粗略地说,平滑函数可以表示为正弦和余弦波的总和(具有各种幅度和频率) .

    FFT(快速傅里叶变换)将函数与那些正弦和余弦波的系数(幅度)联系起来 . 也就是说,一方面功能与另一方面系数序列之间存在一对一的映射 .

    如果声音样本主要由一个音符组成,则其FFT将具有一个非常大的系数(绝对值),而其他系数将非常小 . 该系数对应于具有特定频率的特定正弦波 . 那就是音符的频率 .

  • 0

    不要重新发明轮子:)

    查看http://librosa.github.io,尤其是关于短时傅立叶变换(STFT)的部分,或者在您的情况下,更像是恒定Q变换(CQT) .

    但首先要做的是:让我们假设我们有一个来自音频文件的立体声信号(2个声道) . 现在,我们通过创建平均通道(将两个通道相加并除以2)丢弃在音频文件的两个通道中编码的空间信息 . 我们现在有一个单声道(1声道)信号 . 由于我们有数字信号,因此每个时间点都称为样本 .

    现在开始有趣的部分,我们通过取连续样本(512或2的倍数是标准值)将信号切割成小块(称为帧) . 通过对这些帧中的每一帧进行离散傅里叶变换(DFT),我们得到称为谱图的时频表示 . 任何进一步的概念(重叠等)都可以在每本DSP书籍或本实验课程的资源中阅读:https://www.audiolabs-erlangen.de/content/05-fau/professor/00-mueller/02-teaching/2016s_apl/LabCourse_STFT.pdf

    注意,DFT的频率轴是线性间隔的 . 在西方音乐系统中,八度音程被分成12个半音,其中心频率以对数方式间隔开 . 查看上面关于如何从线性STFT接收对数间隔频率轴的分箱策略的脚本 . 但是,这种方法非常基础,还有很多其他可能更好的方法 .

    现在回到你的笔记识别问题 . 第一:这是一个非常艰难的 . :)如上所述,乐器演奏的真实声音包含泛音 . 此外,如果您有兴趣转录完整乐队演奏的音符,您会受到其他音乐家的干扰等 .

    谈论你可以尝试的方法:现在很多人使用非负矩阵fatorization(NMF或类似的LDPCA)或神经网络来完成这项任务 . 例如,NMF包含在scikit-learn中 . 要开始,我会推荐NMF . 仅使用单声道声音,即一次播放一个乐器 . 使用简单的衰减泛音结构初始化模板,看看会发生什么 .

相关问题