python信号处理函数 python数字信号处理( 五 )


上面的程序可以保存在一个文件中(比如test.py) 。我们使用如下方法运行:
$python test.py
以便让进程运行 。当程序运行到signal.pause()的时候,进程暂停并等待信号 。此时,通过按下CTRL+Z向该进程发送SIGTSTP信号 。我们可以看到,进程执行了myHandle()函数, 随后返回主程序,继续执行 。(当然,也可以用$ps查询process ID, 再使用$kill来发出信号 。)
(进程并不一定要使用signal.pause()暂停以等待信号,它也可以在进行工作中接受信号 , 比如将上面的signal.pause()改为一个需要长时间工作的循环 。)
我们可以根据自己的需要更改myHandler()中的操作,以针对不同的信号实现个性化的处理 。
定时发出SIGALRM信号
一个有用的函数是signal.alarm(),它被用于在一定时间之后,向进程自身发送SIGALRM信号:
import signal
# Define signal handler function
def myHandler(signum, frame):
print("Now, it's the time")
exit()
# register signal.SIGALRM's handler
signal.signal(signal.SIGALRM, myHandler)
signal.alarm(5)
while True:
print('not yet')
我们这里用了一个无限循环以便让进程持续运行 。在signal.alarm()执行5秒之后,进程将向自己发出SIGALRM信号,随后,信号处理函数myHandler开始执行 。
发送信号
signal包的核心是设置信号处理函数 。除了signal.alarm()向自身发送信号之外,并没有其他发送信号的功能 。但在os包中,有类似于linux的kill命令的函数,分别为
os.kill(pid, sid)
os.killpg(pgid, sid)
分别向进程和进程组(见Linux进程关系)发送信号 。sid为信号所对应的整数或者singal.SIG* 。
实际上signal, pause,kill和alarm都是Linux应用编程中常见的C库函数,在这里,我们只不过是用Python语言来实现了一下 。实际上,Python 的解释器是使用C语言来编写的,所以有此相似性也并不意外 。此外,在Python 3.4中 , signal包被增强,信号阻塞等功能被加入到该包中 。我们暂时不深入到该包中 。
总结
signal.SIG*
signal.signal()
signal.pause()
signal.alarm()
Python 简单的扩音,音频去噪,静音剪切数字信号是通过对连续的模拟信号采样得到的离散的函数 。它可以简单看作一个以时间为下标的数组 。比如,x[n],n为整数 。比如下图是一个正弦信号(n=0,1, ..., 9):
对于任何的音频文件,实际上都是用这种存储方式,比如,下面是对应英文单词“skip”的一段信号(只不过由于点太多,笔者把点用直线连接了起来):
衡量数字信号的 能量(强度) ,只要简单的求振幅平方和即可:
我们知道,声音可以看作是不同频率的正弦信号叠加 。那么给定一个声音信号(如上图),怎么能够知道这个信号在不同频率区段上的强度呢?答案是使用离散傅里叶变换 。对信号x[n], n=0, ..., N-1,通常记它的离散傅里叶变换为X[n],它是一个复值函数 。
比如 , 对上述英文单词“skip”对应的信号做离散傅里叶变换 , 得到它在频域中的图像是:
可以看到能量主要集中在中低音部分(约16000Hz以下) 。
在频域上,也可以计算信号的强度,因为根据Plancherel定理,有:
对于一般的语音信号,长度都至少在1秒以上 , 有时候我们需要把其中比如25毫秒的一小部分单独拿出来研究 。将一个信号依次取小段的操作 , 就称作分帧 。技术上,音频分帧是通过给信号加一系列的 窗函数 实现的 。
我们把一种特殊的函数w[n],称作窗函数,如果对所有的n,有0=w[n]=1,且只有有限个n使得w[n]0 。比如去噪要用到的汉宁窗,三角窗 。

推荐阅读