首页 > 评测 > 嵌入式系统与音频处理
[导读]Intel MSC-51也能做PC声卡?!

21ic打算携手资(tu)深(ding)直男癌晚期工程师zhanzr21,来给大家讲一讲嵌入式系统与音频处理的故事。

关于zhanzr21

曾经混迹于两岸三地,摸爬滚打在前端后端,搞过学术上过班。现在创业中,欢迎各种撩

点击链接加入群【嵌入式音频信号处理】:https://jq.qq.com/?_wv=1027&k=45wk8Ks

嵌入式音频专用资料代码分享:https://pan.baidu.com/s/1dFh5pWd

apple2_speaker2_copy.jpg

在IBM PC流行之前的时代,一般的个人电脑都没有声卡.某些主机,比如NES,Atari之类的注重于游戏应用的,都有专门设计的声音设备.比如NES主机在CPU(定制的6502)中专门设计了一个APU的外设来播放声音.说起来这个APU还是5通道呢:两路方波,一路三角波,一路噪音,一路采样. 注意这个5通道不是现在说的5声道这种概念,而是5通道信号进行叠加实现类声卡的功能.关于NES的音频硬件软件的内容将在今后的连载中介绍,这里还是回到PC音频硬件上来.

说声卡之前先讲一讲PC扬声器(实际上现代嵌入式系统中这个称作蜂鸣器更合适,但是所有文献都称作Speaker,这里也随俗.有这个设备的主板有焊接蜂鸣器的,也有焊接扬声器的,只是起的作用跟嵌入式系统中的无源蜂鸣器类似.).作为音频设备,扬声器早于真正意义上的声卡出现在PC上.因此声卡与扬声器是分开的两个设备,扬声器是直接焊接在主板南桥的定时器(8253/8254兼容定时器)引脚上面. 有一定年龄的读者可能还记得那种老电脑出了故障的时候,滴滴滴滴的报警声. 有经验的老司机们还可以通过扬声器不同响声模式来判断电脑故障的原因.比如: 短短短-内存没有插好, 短长短-硬盘没有插好, 长-风扇散热不够等等.

[因为这个扬声器只能输出高和低的方波,本质上就不是用来播放PCM的.但是本系列文章介绍过一种D类放大器,可以通过PWM+滤波器实现一种简单DAC. 事实上确实有人做过这样的实验. 只是考虑到现代电脑上扬声器已经与声卡合并了, 本文就不进行这个方向的阐叙了.]

时过境迁, 大多数电脑上早就没有专门的扬声器了. 现在的操作系统中一般把扬声器的调用转到声卡上执行, 当然用户可以设置是否使能这种转向.

扬声器的声音转移到声卡上播放.jpg

图 扬声器的声音转移到声卡上播放

Windows操作系统API中还遗留着这个扬声器的控制接口. WinXP与Vista中曾经去除这个API,但是Win7又恢复了. 这个调用的函数就是:

BOOL WINAPI Beep(

_In_ DWORD dwFreq,

_In_ DWORD dwDuration

);

我想, 这个函数的命名也是没有出乎任何人的意料吧.

第一个参数为频率,范围为:37Hz到32767Hz. 那么这个范围怎么来的呢.先说37Hz,这是由于早期PC运行的主频而来的. 当年所有的PC兼容机给板子上的定时器8254提供的频率为: 1.19318 MHz(14.31818 MHz除以12). 这个频率除以65536(8254为16位定时器, 65536是最大的分频系数)得到18.2Hz的最小分辨率, 而方波是50%占空比, 需要两次翻转输出口,所以驱动扬声器最低频率为36.4Hz, 取整得37Hz. 其实如果真正做到bug级别兼容的PC主机, 所谓的37Hz扬声器声音就是36.4Hz. 只是后来主板上增加了更精准的定时器, 37Hz也能精确的实现. 那么32767怎么来的, 这个简单一些, 因为早期的操作系统大多是16位的, 16位有符号整数的最大值是32767. 因为人耳的频率响应范围是20Hz-20KHz,这两个极限也不怎么影响这个API的目的.下面做个实验,听一听实际的扬声器的嘀嘀声.

#!/bin/python

#Example source code for 21ic

#Default runs in Python 3.5 Environment

#Author: zhanzr21

#Description: This Example plays different beep using the windows API(Beep). So it will only run on Windows(After Version 7) Machine

#

import winsound

import time

for freq in range(37,32767, 100):

winsound.Beep(freq, 500)

time.sleep(0.5)

根据作者的实践,100Hz以下的声音很难感觉到, 15KHz之后也几乎听不到, 反倒是25KHz之后到32KHz慢慢的有点听得见. 这并非作者有特异功能, 而是属于一般的音频硬件的滤波器的副作用, 25KHz到32KHz这个范围的音频在通过滤波器时产生了一些低频的剩余能量.

事实上除了Beep这个函数,还有一个Windows API也是产生简单声音. 只是这个函数优先通过声卡来播放, 如果没有声卡就播放给扬声器. 这个调用叫做:

BOOL WINAPI MessageBeep(

_In_ UINT uType

);

相比于上面说的Beep函数, 这个函数仅能播放系统默认的几种声音.下面是实验代码:

#!/bin/python

#Example source code for 21ic

#Default runs in Python 3.5 Environment

#Author: zhanzr21

#Description: This Example plays different beeps using the windows API(MessageBeep). So it will only run on Windows(After Version 7) Machine

#

import winsound

import time

winsound.MessageBeep(winsound.MB_OK)

time.sleep(0.4)

winsound.MessageBeep(winsound.MB_ICONASTERISK)

time.sleep(0.4)

winsound.MessageBeep(winsound.MB_ICONEXCLAMATION)

time.sleep(0.4)

winsound.MessageBeep(winsound.MB_ICONHAND)

time.sleep(0.4)

winsound.MessageBeep(winsound.MB_ICONQUESTION)

time.sleep(0.4)

winsound.MessageBeep(-1)

time.sleep(0.4)

说完了扬声器就轮到该说真正的声卡了.真正的声卡出现之前还有几个过渡产品.比如这个使用PC的并口连一个8位的DAC, 效果比起扬声器来是很大的进步了.

dss_dac-2_copy.jpg

图 并口接DAC的Speech Thing

硬件上到了总线时代, 才陆续有声卡这一类的扩展音频硬件(不需CPU来做实际的音频控制)出现.

early_pc_soundcard.jpg

图 Adlib出产的早期类声卡(AdLib公司是早期类声卡的先驱者)

注意到那个蓝色的器件吗,那是个电位器, 用来调整音量的. 早期音频硬件不是标配的时候,操作系统是没有调整音量的软件接口的, 要调整音量请把手伸到机箱后面找旋钮.

从技术的角度来看其实这个也不能算声卡,只能算类声卡, 因为输出的声音还是多通道的方波之类信号合成的. 这种卡有很多种, 复杂度也有很大的差别. 技术角度来讲, 更类似今天所说的MIDI合成器. 集成了很多效果(鼓声,钢琴,手风琴等乐器).

真正和现代计算机的声卡相提并论的产品为Creative公司的Sound Blaster系列. 在这个系列的1.0版本上使用了一个DSP(其实是个单片机), 可以播放22.05KHz, 8bit单声道的PCM, 采样方面支持单声道的13bit(与后面要讲的A-law格式兼容).

sb15-3.jpg

图 早期声卡Sound Blaster 1.5

下图是该公司向客户送测的一个样品.

killer_card-3_copy.jpg

图 Sound Blaster的样品版本(据知情人介绍, 上面那个遮住的DIP40片子正是Intel MCS-8051)

从SoundBlaster 16系列开始, 声卡开始跟我们今天使用的声卡差别只是在参数, 标准与集成度上了.

KL_Creative_Labs_Soundblaster_16_CT2230_copy.jpg

图 SoundBlaster 16 现代声卡的始祖鸟

 

现代电脑上的声卡一般就集成到主板上, 除非有专业工作室级别的需求. 关于声卡的话题,后面的章节如果有篇幅的话还会讲到. 包括如何利用声卡制作信号发生器, 示波器等等主题.

本文系21ic原创,未经许可禁止转载!

网友评论

立 即 购 买 查看产品细节
更多相似方案