利用Python进行录音和音频分析

pyaudio简介

Python有个很强大的处理音频的库pyqudio, 使用pyaudio库可以进行录音,播放,生成wav文件等等。更多介绍可以查阅官方文档

pyaudio安装

各平安安装方法 windows平台下直接使用pip安装即可:pip install pyqudio

录音

import wave
import pyaudio

# 定义数据流块
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
# 录音时间
RECORD_SECONDS = 5
# 要写入的文件名
WAVE_OUTPUT_FILENAME = "output.wav"
# 创建PyAudio对象
p = pyaudio.PyAudio()

# 打开数据流
stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

print("* recording")

# 开始录音
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)

print("* done recording")

# 停止数据流
stream.stop_stream()
stream.close()

# 关闭PyAudio
p.terminate()

# 写入录音文件
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()

这里设置的录音时间是5秒,运行后结果如下:

recording

音频分析

import wave
import numpy
from pyaudio import PyAudio
import matplotlib.pyplot as plt

# 只读方式打开WAV文件
wf = wave.open('./output.wav', 'rb')
# 创建PyAudio对象
p = PyAudio()
stream = p.open(format = p.get_format_from_width(wf.getsampwidth()),
    channels = wf.getnchannels(),
    rate = wf.getframerate(),
    output = True)
nframes = wf.getnframes()
framerate = wf.getframerate()

# 读取完整的帧数据到str_data中,这是一个string类型的数据
str_data = wf.readframes(nframes)
wf.close()

# 将波形数据转换成数组
wave_data = numpy.fromstring(str_data, dtype=numpy.short)
# 将wave_data数组改为2列,行数自动匹配
wave_data.shape = -1,2
# 将数组转置
wave_data = wave_data.T

def time_plt():
    # time也是一个数组,与wave_data[0]或wave_data[1]配对形成系列点坐标
    time = numpy.arange(0, nframes)*(1.0/framerate)
    # 绘制波形图
    plt.subplot(211)
    plt.plot(time, wave_data[0], c='r')
    plt.subplot(212)
    plt.plot(time, wave_data[1], c='g')
    plt.xlabel('time (seconds)')
    plt.show()

def freq():
    # 采样点数,修改采样点数和起始位置进行不同位置和长度的音频波形分析
    N = 44100
    start = 0  # 开始采样位置
    df = framerate/(N-1)  # 分辨率
    freq = [df*n for n in range(0, N)]  # N个元素
    wave_data2 = wave_data[0][start:start+N]
    c = numpy.fft.fft(wave_data2)*2/N
    # 常规显示采样频率一半的频谱
    d = int(len(c)/2)
    # 仅显示频率在4000以下的频谱
    while freq[d] > 4000:
        d -= 10
    plt.plot(freq[:d-1], abs(c[:d-1]), 'r')
    plt.show()

def main():
    time_plt()
    freq()

if __name__ == '__main__':
    main()

代码中的注释比较详细,这里我录了等间隔按顺序念的 “1,2,3,4”。

先读取刚刚录制的wav文件,频谱分析中利用numpy包进行FFT(快速傅里叶变换)处理,最后利用matplotlib库进行绘图,依次绘制了波形图和频谱图。

波形图如下:

频谱图如下:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术总结

YYImage框架瞧一瞧

建议查看原文:https://www.jianshu.com/p/83edaeeb5851(不定时更新)

16230
来自专栏小灰灰

zxing二维码生成服务之深度定制

二维码生成服务之深度定制 之前写了一篇二维码服务定制的博文,现在则在之前的基础上,再进一步,花样的实现深度定制的需求,我们的目标是二维码上的一切都是可以由用户...

54960
来自专栏葬爱家族

Android高级动画(3)

上一篇文章我们讲了Android中的矢量动画,虽然文中展示的Demo并不多,但是相信大家还是体会到了矢量动画的强大。这里再做一个温故总结:

18910
来自专栏GIS讲堂

唐宋文学诗人分布展示

本文的数据是从搜韵获取而来的,地址为http://sou-yun.com/poetlife.html,为方便大家使用,将数据保存到了百度云盘,下载信息为:链接:...

13030
来自专栏非典型技术宅

Quartz2D进行渲染1. 渲染模式2. even-odd rule:奇偶填充规则3. nonzero winding number rule:非零绕数规则4. 其他会用到的渲染模式5. 混合模式

14430
来自专栏技术博客

Win8中缩放视图(SemanticZoom控件)

    SemanticZoom控件可以让用户缩放具有相同内容的两个不同视图。其中有一个是主视图。另外一个视图可以让用户进行快速导航。例如,当用户查看地址簿时,...

8210
来自专栏cs

python爬虫练手,爬取名言,实现英语词典

她们的Html为,通过beautiful库的html.parser解析,通过id,class选择器,提取我们需要的东西。

10750
来自专栏偏前端工程师的驿站

CSS魔法堂:你真的理解z-index吗?

一、前言                                 假如只是开发简单的弹窗效果,懂得通过z-index来调整元素间的层叠关系就够了。但要将...

20750
来自专栏nimomeng的自我进阶

抓住iOS的未来 - 30天学习编写30个Swift小程序

=======================================================

50120
来自专栏AndroidTv

属性动画 ValueAnimator 运行原理全解析

好,废话不多说,之前我们已经分析过 View 动画 Animation 运行原理解析,那么这次就来学习下属性动画的运行原理。

44780

扫码关注云+社区

领取腾讯云代金券