使用soundcard在Python中操作声卡

卓晴 2021-10-27 03:26:57
Python 使用 操作 作声 soundcard

简 介: 利用Python中的soundcard软件包可以对声卡的MIC,SPEAKER进行操作。基于此,配合可编程信号源DG1062可以获得声卡的详细的幅频特性。

关键词 声卡soundcarddg1062幅频特性

 

§01 作声卡


之前通过实验( 测试计算机声卡双通道录音的频率特性 )初步测试了计算机声卡录制声音所对应的频率范围,并在 双声道录制的混动波形信号 记录了 混沌电路产生的混沌物理信号 。实验中使用了录音软件Audacity进行录制。为了方便后期实验,需要测试直接在Python语言中操作声卡。

一、soundcard 软件包

在python中提供对于声卡操作的软件包包括:

上面两个软件都可以正常安装。由于只在 SoundCard 0.4.1 中给出了示例程序,所以下面仅对SoundCard软件包进行测试。

1、读取音频设备信息

(1) 测试程序

from headm import *
import soundcard as sc
speakers = sc.all_speakers()
printf(speakers)
default_speaker = sc.default_speaker()
printf(default_speaker)
mics = sc.all_microphones()
printf(mics)
default_mic = sc.default_microphone()
printf(default_mic)

(2) 读取结果

[<Speaker 扬声器 (VIA High Definition Audio) (2 channels)>, <Speaker DELL U2410-1 (NVIDIA High Definition Audio) (2 channels)>, <Speaker SPDIF Interface (TX0) (VIA High Definition Audio) (2 channels)>, <Speaker SPDIF Interface (TX1) (VIA High Definition Audio) (2 channels)>]
<Speaker 扬声器 (VIA High Definition Audio) (2 channels)>
[<Microphone Analog (USB Capture AIO Analog) (2 channels)>, <Microphone 立体声混音 (VIA High Definition Audio) (2 channels)>, <Microphone Digital (USB Capture AIO) (2 channels)>, <Microphone 麦克风 (3- USB Audio Device) (1 channels)>, <Microphone 数字音频接口 (USB3. 0 capture) (1 channels)>, <Microphone 线路输入 (VIA High Definition Audio) (2 channels)>]
<Microphone 麦克风 (3- USB Audio Device) (1 channels)>

2、获取特定输入

利用 get_microphone() 获得对应的mic输入。

one_mic = sc.get_microphone('线路输入')
printf(one_mic)

上述代码输出:

<Microphone 线路输入 (VIA High Definition Audio) (2 channels)>

二、录音与回复

1、录音

下面给出了录音的函数:

data = default_mic.record(samplerate=48000, numframes=48000)

2、回放函数

下面给出了回放函数:

default_speaker.play(data/numpy.max(data), samplerate=48000)

3、录音和回复

下面的代码测试了利用 “线路输入”进行录音,然后通过缺省喇叭进行回放。

with one_mic.recorder(samplerate=48000) as mic,\
default_speaker.player(samplerate=48000) as sp:
for _ in range(10):
data = mic.record(numframes=10240)
sp.play(data)

修改回复的samplerate参数,可以改变回复是声音的频率。

三、显示录制信号波形

1、采集正弦波

from headm import *
import soundcard as sc
default_mic = sc.default_microphone()
one_mic = sc.get_microphone('线路输入')
data = one_mic.record(samplerate=48000, numframes=1024)
plt.plot(data)
plt.xlabel("Samples")
plt.ylabel("Values")
plt.grid(True)
plt.tight_layout()
plt.show()

▲ 图1.3.1 显示采集到的正弦波波形

▲ 图1.3.1 显示采集到的正弦波波形

▲ 图1.3.2 显示采集到的正弦波波形

▲ 图1.3.2 显示采集到的正弦波波形

从上面可以看到在数据的起始部分显示了一些数据为0的采集数据。这可能是声卡在被初始化的时候对应的起始数据为0。下面通过对声卡先进行初始化,采集 一段之后,再采集,就可以避免这种情况。

from headm import *
import soundcard as sc
default_mic = sc.default_microphone()
one_mic = sc.get_microphone('线路输入')
with one_mic.recorder(samplerate=48000) as mic:
mic.record(numframes=1000)
data = mic.record(numframes=1024)
plt.plot(data)
plt.xlabel("Samples")
plt.ylabel("Values")
plt.grid(True)
plt.tight_layout()
plt.show()

▲ 图1.3.3 显示采集到的1kHz的声音波形

▲ 图1.3.3 显示采集到的1kHz的声音波形

 

§02 卡带宽


测试计算机声卡双通道录音的频率特性 对于声卡的带宽进行了初步测试。下面通过Python来对声卡采集到的数据进行处理,便可以获得多点不同频率下的声卡采集到的信号的幅度,进而可以更加精确获得声卡的带宽。

一、测量方法

利用 DG1062可编程信号源 产生不同频率下的信号,送到声卡进行采集。通过读取声卡采集到的信号,计算出它对应的幅值(通过对最大值,最小值进行检测)进而计算采集到的信号的幅值。

通过测量一组不同频率下的声卡获得信号的幅值,绘制出声卡的幅频特性。

二、测量结果

1、测量低频截止频率

(1) 测量代码

from headm import *
import soundcard as sc
from tsmodule.tsvisa import *
dg1062open(103)
dg1062freq(1,2000)
one_mic = sc.get_microphone('线路输入')
pltgif = PlotGIF()
with one_mic.recorder(samplerate=48000) as mic:
mic.record(numframes=100000)
fdim = linspace(1, 10, 50)
ddim = []
for f in fdim:
dg1062freq(1,f)
data = mic.record(numframes=48000)
damp = max(list(data[:,0])) - min(list(data[:,0]))
ddim.append(damp)
printff(f, damp)
plt.clf()
plt.plot(data[:,0])
plt.xlabel("Sample")
plt.ylabel("Values")
plt.grid(True)
plt.tight_layout()
plt.draw()
plt.pause(.1)
pltgif.append(plt)
plt.clf()
pltgif.save()
tspsave('datal', f=fdim, d=ddim)
plt.plot(fdim, ddim)
plt.xlabel("Frequency(Hz)")
plt.ylabel("Amplitude")
plt.grid(True)
plt.tight_layout()
plt.show()

(2) 测量过程波形

▲ 图2.1.1 不同频率对应的波形

▲ 图2.1.1 不同频率对应的波形

(3) 测量结果

▲ 图2.1.2 不同频率对应的信号的幅值

▲ 图2.1.2 不同频率对应的信号的幅值

可以看到在上面测量过程中,采集到的数据出现较大的问题,主要是出现数据的丢失。

2、测量高频截止频率

测量频率范围:
起始频率:10kHz
截止频率:50kHz
采集步数:50

(1) 采集到不同频率波形

下面是测量过程中采集到的不同频率的波形:

▲ 图2.1.3 测量过程不同波形

▲ 图2.1.3 测量过程不同波形

(2) 幅频特性

下面是不同频率下声卡采集到的信号波形的幅值。

▲ 图2.1.4 不同频率下采集到的信号的幅值

▲ 图2.1.4 不同频率下采集到的信号的幅值

通过上述采集到的声卡的幅频特性,可以看到它的高频截止频率硬给了25kHz。

三、设置不同采用频率

1、提高采样频率

设置高频采样频率为96kHz,重复上面测量高频截止频率过程。

▲ 图2.3.1 采集过程不同频率对应的采集波形

▲ 图2.3.1 采集过程不同频率对应的采集波形

在96kHz下, 对应的声卡的幅频特性如下:

▲ 图2.3.2 测量在采样频率96kHz下对应的信号的幅度

▲ 图2.3.2 测量在采样频率96kHz下对应的信号的幅度

可以看到提高采样频率并没有实质提高声卡的高频截止频率。

2、降低采样频率

降低采样频率,设置声卡的采样频率为 24kHz。重新测试声卡的高频截止频率。

▲ 图2.3.3 采集到不同频率的信号波形

▲ 图2.3.3 采集到不同频率的信号波形

▲ 图2.3.4 声卡在采样频率为24kHz下的幅频特性

▲ 图2.3.4 声卡在采样频率为24kHz下的幅频特性

从上面可以看到在24kHz 采样频率下,声卡的截止频率大约在12kHz。这说明在声卡前面已经有了抗混叠滤波器了。

下面是重新测量扫频范围在 10 ~ 20kHz下,采样频率在24kHz下对应的声卡的幅频特性。

▲ 图2.3.5 声卡在采样频率24kHz下的幅频特性

▲ 图2.3.5 声卡在采样频率24kHz下的幅频特性

下面是设置采样频率为12kHz 下,声卡的高频部分的幅频特性。

▲ 图2.3.6 声卡在采样频率12kHz下的幅频特性

▲ 图2.3.6 声卡在采样频率12kHz下的幅频特性

通过上面测试结果可以看到,声卡的采样频率越低,对应的高频截止频率也越低。对应的截止频率(对应增益降低到原来的一半,-6dB)对应的频带宽度等于采样频率的一半。这证明了声卡中存在着前置的可编程的抗混叠滤波器。

3、测量低频截止频率

设置声卡的采样频率为1200Hz,重新测量声卡的低频采样频率。

▲ 图2.3.7 不同频率下采集到的波形

▲ 图2.3.7 不同频率下采集到的波形

▲ 图2.3.8 采样频率为1200Hz,低频下的幅频特性

▲ 图2.3.8 采样频率为1200Hz,低频下的幅频特性

对比之前的结果来看,在低频阶段,声卡采集到的声音的波形依然存在着较大的损失。

4、测量中频段幅频特性

测量1000 ~ 2000Hz中声卡的幅频特性。设置采样频率为24000Hz。

▲ 图2.3.9 不同频率采集到的波形

▲ 图2.3.9 不同频率采集到的波形

▲ 图2.3.10 采样频率为24000Hz下的声卡的幅频特性

▲ 图2.3.10 采样频率为24000Hz下的声卡的幅频特性

from headm import *
import soundcard as sc
from tsmodule.tsvisa import *
dg1062open(103)
dg1062freq(1,2000)
one_mic = sc.get_microphone('线路输入')
pltgif = PlotGIF()
with one_mic.recorder(samplerate=24000) as mic:
mic.record(numframes=100000)
fdim = linspace(1000, 2000, 50)
ddim = []
for f in fdim:
dg1062freq(1,f)
data = mic.record(numframes=1024)
damp = max(list(data[:,0])) - min(list(data[:,0]))
ddim.append(damp)
printff(f, damp)
plt.clf()
plt.plot(data[:,0])
plt.xlabel("Sample")
plt.ylabel("Values")
plt.grid(True)
plt.tight_layout()
plt.draw()
plt.pause(.1)
pltgif.append(plt)
plt.clf()
pltgif.save()
tspsave('datal', f=fdim, d=ddim)
plt.plot(fdim, ddim)
plt.xlabel("Frequency(Hz)")
plt.ylabel("Amplitude")
plt.grid(True)
plt.tight_layout()
plt.show()

 

验总结 ※


试了python中soundcard软件包对于计算机声卡的操作,利用线路输入可以获取外部模拟信号的波形,并通过speaker进行播放。

通过程序,控制信号源DG1062,利用soundcard采集到信号波形,可以逐点获得声卡的幅频特性。声卡的高频截止频率最大为25kHz左右,不再随着采样频率的提高而提高。如果声卡的采样频率低于48000Hz,声卡中具有前端的抗混叠滤波器,抗混叠滤波器的截止频率等于采样频率的一半。

对于声卡的低频以及中频的幅频特性的测量,显示了采集过程中数据的不稳定性,这也实测测量结果出现了较大的抖动。

具体为什么使用soundcard中的 record 指令所获得数据出现截断过程,具体原因还不可而知。


■ 相关文献链接:

● 相关图表链接:

#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY -- by Dr. ZhuoQing 2021-10-20
#
# Note:
#============================================================
from headm import *
import soundcard as sc
from tsmodule.tsvisa import *
dg1062open(103)
dg1062freq(1,2000)
one_mic = sc.get_microphone('线路输入')
pltgif = PlotGIF()
with one_mic.recorder(samplerate=24000) as mic:
mic.record(numframes=100000)
fdim = linspace(1000, 2000, 50)
ddim = []
for f in fdim:
dg1062freq(1,f)
data = mic.record(numframes=1024)
damp = max(list(data[:,0])) - min(list(data[:,0]))
ddim.append(damp)
printff(f, damp)
plt.clf()
plt.plot(data[:,0])
plt.xlabel("Sample")
plt.ylabel("Values")
plt.grid(True)
plt.tight_layout()
plt.draw()
plt.pause(.1)
pltgif.append(plt)
plt.clf()
pltgif.save()
tspsave('datal', f=fdim, d=ddim)
plt.plot(fdim, ddim)
plt.xlabel("Frequency(Hz)")
plt.ylabel("Amplitude")
plt.grid(True)
plt.tight_layout()
plt.show()
# data = mic.record(numframes=1024)
# plt.plot(data)
# plt.xlabel("Samples")
# plt.ylabel("Values")
# plt.grid(True)
# plt.tight_layout()
# plt.show()
#------------------------------------------------------------
# END OF FILE : TEST1.PY
#============================================================
版权声明
本文为[卓晴]所创,转载请带上原文链接,感谢
https://zhuoqing.blog.csdn.net/article/details/120875107

  1. python求带我脱离苦海,哎_
  2. Python 数据分析里面轴的问题
  3. python初学者,请问使用openpyxl库读取文件后出现图片中的报错要怎么解决?
  4. 大学毕业论文写有关python
  5. 授人以鱼吧友友python编写程序自动计算个人总分平均分各科最高最低平均分
  6. python怎么将四行代码换成一行啊
  7. 用Python如何编写啊 真不会啊?
  8. 这个布尔变化怎么做啊(Python
  9. PYTHON求集合交集需要用户手动输入集合名
  10. Python运行哈姆雷特词频统计时出错(如图),是哪方面的问题?
  11. 【Python表白代码合集】”我还是很喜欢你,像风走了八千里,不问归期”!!
  12. python实现学生信息管理系统(含代码)
  13. wxpython中如何按键停止死循环?
  14. python 类的问题?不懂这种方法的作用?不是继承那是什么作用?
  15. Python 题目不会写 求帮助!
  16. Python,turtle制图,要求使用for,while编写
  17. Python题目不会 求帮助! 谢谢您!
  18. Python题目不会!求帮助!
  19. Python这个看不太懂,,大神们帮个忙
  20. 安装拓展库pandas失败怎么解决
  21. python将字符串转成特定列表格式
  22. Python做一个保护手机号编程
  23. 用Spyder运行Python爬虫时仅输出“runfile(xx), wdir=xx”
  24. 使用Python对一组数据进行分段拟合,如何处理断点处的左右倒数相等
  25. Python输出符合条件的文件的路径名
  26. Python中pandas怎么实现分组去重统计和求和
  27. python xpath 爬虫,请帮帮我吧!
  28. python 用泰勒公式近似计算sinx的值 求解代码中哪里出现了错误
  29. Python语法2
  30. python如何将输出的各行数字对齐
  31. 使用 Python 进行数据可视化之Matplotlib
  32. python新鲜题 老公们 救救孩子
  33. 如何用python解答 要如何着手
  34. 请问Python正则表达式如何在多个文本中匹配出关键字
  35. Python 三天打鱼两天晒网问题
  36. mac安装python3
  37. 請問python要怎麼印数字倒等腰三角形
  38. 【算法学习】807. 保持城市天际线(java / c / c++ / python / go / rust)
  39. 【算法学习】237. 删除链表中的节点(java / c / c++ / python / go)
  40. 【算法学习】1512. 好数对的数目(java / c / c++ / python / go / rust)
  41. 【算法学习】1672. 最富有客户的资产总量(java / c / c++ / python / go / rust)
  42. 【算法学习】771. 宝石与石头(java / c / c++ / python / go / rust)
  43. 【算法学习】02.03. 删除中间节点(java / c / c++ / python / go)
  44. 【算法学习】1769. 移动所有球到每个盒子所需的最小操作数(java / c / c++ / python / go / rust)
  45. 【算法学习】1486. 数组异或操作(java / c / c++ / python / go / rust)
  46. 【算法学习】剑指 Offer 64. 求1+2+…+n(java / c / c++ / python / go / rust)
  47. 【算法学习】LCP 44. 开幕式焰火(java / c / c++ / python / go / rust)
  48. 【算法学习】剑指 Offer 58 - II. 左旋转字符串(java / c / c++ / python / go / rust)
  49. python的学校疑问难题求解
  50. 大学python题 作业题 基础题
  51. Python字典的知识,输出的样例为,最高分:89
  52. python写入文件失败且程序提前中止
  53. 用Python写一个学生字典,帮帮忙
  54. Python,能不能帮帮忙,真的不会
  55. [python] yield 和 readline() 的使用问题
  56. python安装找不到问题救救孩子
  57. python中循环结构完成数字游戏
  58. 如何用python实现多列vlookup(excle操作)
  59. python语言deLong‘s test:通过统计学的角度来比较两个ROC曲线、检验两个ROC曲线的差异是否具有统计显著性
  60. 安装LPC55S69 MicroPython模块是遇到的CDC Interface驱动问题