linux自动读取麦克风,检测用户向麦克吹气

uid-20622737-id-1912870.html

如果几年前你告诉我人们可以通过晃动手机或向麦克吹气使手机有所动作,我一定会大笑不止。但现在这已经是事实了。

检查晃动动作是很直接的,所有这些在3.0“motion event”(动作事件)中都有介绍。

检测向麦克吹气困难一点。本教程将建立一个简单的单视图程序,它将在用户向麦克吹气时向控制台写入记录信息。

源代码/Github

可从GitHub获得。 你可以克隆软件仓库或直接下载。

概述

检测向麦克吹气的工作可分为两部分:(1) 获取麦克输入 (2) “听”吹气的声音。

我们将使用3.0中新的AVAudioRecorder类来捕获麦克输入。使用AVAudioRecorder可以让我们使用Objective-C,而不需像其他方法一样使用C。

向麦克吹气的噪声/声音是由低频声音组成的。我们将使用 来降低来自麦克的高频声音;当滤波信号的电平等级突然增大时,我们就知道有人向麦克吹气了。

创建项目

启动Xcode创建一个View-Based iPhone程序,叫MicBlow:

使用Xcode菜单File > New Project… 创建一个新项目

从 iPhone OS > Application 选择View-based Applications然后按Choose…

将项目命名为MicBlow,按Save

添加AVFoundation Framework

为使用AVAudioRecorder类,我们需要向项目添加AVFoundation framework:

在项目Groups & Files面板上展开Targets

按Control-点击或右击MicBlow

选择Add > Existing Frameworks…

按下Linked Libraries左下角的+按钮

选择AVFoundation.framework并按下Add

AVFoundation.framework出现在Linked Libraries下。关闭窗口

然后,我们在view controller接口中引入AVFoundation头文件并设置AVAudioRecorder实例变量:

展开项目Groups & Files面板下的MicBlow

展开Classes文件夹

选择MicBlowViewController.h进行编辑

更新文件。修改见如下2,3,7行:

#import

#import

#import

@interface MicBlowViewController : UIViewController

{

AVAudioRecorder *recorder;

}

@end

引入CoreAudioTypes头文件实际上是下一步需要的工作。我们还需要在设置AVAudioRecorder定义更多的常量。

获取麦克输入

我们在ViewDidLoad进行设置并开始“听“取麦克:

解除样本ViewDidLoad方法注释

更新如下。见4-18行:

- (void)viewDidLoad

{

[super viewDidLoad];

NSURL *url = [NSURL fileURLWithPath:@"/dev/null"];

NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:

[NSNumber numberWithFloat: 44100.0], AVSampleRateKey,

[NSNumber numberWithInt: kAudioFormatAppleLossless],

AVFormatIDKey, [NSNumber numberWithInt: 1], AVNumberOfChannelsKey,

[NSNumber numberWithInt: AVAudioQualityMax], AVEncoderAudioQualityKey, nil];

NSError *error;

recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];

if (recorder) {

[recorder prepareToRecord];

recorder.meteringEnabled = YES;

[recorder record];

} else

NSLog([error description]);

}

AVAudioRecorder的主要功能就像前名字暗示的那样进行音频录制。其第二个功能是提供音频电平等级信息。所以,这里我们只是将音频输入指向/dev/null位 – 我没有找到任何文档支持我的观点,但一致意见是就像在任何Unix下一样,/dev/null将打开音频计量表。

注意: 如果你准备采用上述代码,记住在设置meteringEnabled属性或音频计量开始工作前,要调用prepareToRecord (或者record)。

记住在dealloc中释放recorder。 见第三行:

- (void)dealloc

{

[recorder release];

[super dealloc];

}

音频采样

我们将使用定时器每秒30次检查一次音频电平等级。NSTimer实例变量以及其回调函数在MicBlowViewController.h中定义。修改见7,10行:

#import

#import

#import

@interface MicBlowViewController : UIViewController {

AVAudioRecorder *recorder;

NSTimer *levelTimer;

}

- (void)levelTimerCallback:(NSTimer *)timer;

@end

更新.m文件中ViewDidLoad启用定时器。修改见16,17行:

- (void)viewDidLoad {

[super viewDidLoad];

NSURL *url = [NSURL fileURLWithPath:@"/dev/null"];

NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:

[NSNumber numberWithFloat: 44100.0],AVSampleRateKey,

[NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey,[NSNumber numberWithInt: 1],

AVNumberOfChannelsKey,[NSNumber numberWithInt: AVAudioQualityMax],

AVEncoderAudioQualityKey, nil];

NSError *error;

recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];

if (recorder) {

[recorder prepareToRecord];

recorder.meteringEnabled = YES;

[recorder record];

levelTimer = [NSTimer scheduledTimerWithTimeInterval: 0.03 target: self

selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES];

} else

NSLog([error description]);

}

现在,我们只是直接进行音频采样而未使用滤波。在.m文件中添加levelTimerCallback:

- (void)levelTimerCallback:(NSTimer *)timer {

[recorder updateMeters];

NSLog(@"Average input: %f Peak input: %f",

[recorder averagePowerForChannel:0], [recorder peakPowerForChannel:0]);

}

发送updateMeters消息来刷新平均和峰值功率。此计数是以对数刻度计量的,-160表示完全安静,0表示最大输入值。

不要忘记在dealloc中释放定时器。修改见第三行:

- (void)dealloc

{

[levelTimer release];

[recorder release];

[super dealloc];

}

”聆听“吹气声

正如概述中提到的那样,我们要使用低通滤波来消除高频声音对电平带来的影响。该算法建立了一系列将过去的每个采样输入合成而得到的结果。我们需要一个实例变量来保存此结果。更新.h文件。修改见第八行:

#import

#import

#import

@interface MicBlowViewController : UIViewController {

AVAudioRecorder *recorder;

NSTimer *levelTimer;

double lowPassResults;

}

替换levelTimerCallback:方法来实现此算法:

- (void)levelTimerCallback:(NSTimer *)timer {

[recorder updateMeters];

const double ALPHA = 0.05;

double peakPowerForChannel = (10, (0.05 * [recorder peakPowerForChannel:0]));

lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults;

NSLog(@"Average input: %f Peak input: %f Low pass results: %f",

[recorder averagePowerForChannel:0],

[recorder peakPowerForChannel:0], lowPassResults);

}

我们在每次定时器回调时重新计算一次lowPassResults变量。为方便,我们将其转换为0-1,0代表完全安静,1代表最大音量。

但低通滤波值超过一定门槛范围时,我们就可以判断有人向麦克吹了气。门槛范围值的设定是一种技巧。它设定太小,则太容易被触发,如果设定太高,则必须长时间用尽力气吹气才会有效果。在我们的程序中,我将其设为0.95。我们要改变一下log的条件,见第6,7行:

- (void)listenForBlow:(NSTimer *)timer {

[recorder updateMeters];

const double ALPHA = 0.05;

double peakPowerForChannel = (10, (0.05 * [recorder peakPowerForChannel:0]));

lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults;

if (lowPassResults > 0.95)

NSLog(@"Mic blow detected");

}

好了!你可以检测是否有人吹了麦克了。

鸣谢及说明

此方法在大部分情况下工作良好,但并非任何情况都正确。我是在飞行中写的这篇文章,飞机的引擎声经常触发我的算法。类似地,在一个噪声很大的房间内足够多的低频声也会触发我的算法。

算法节选自。上面帖子使用的是库来进行音频电平检测。SCListener比AVAudioRecorder更早出现;它是用来隐藏C语言细节的获取音频电平代码。而无疑AVAudioRecorder更容易使用。

最后,此方法确实可以在模拟器中正常工作。但你要找到Mac上的麦克。出乎我的意料,第一代Macbook上的麦克处于摄像头左方的小孔中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用Python读取麦克风,你可以按照以下步骤进行操作: 1. 首先,引入`pyaudio`库并创建一个`PyAudio`对象来控制音频流。使用以下代码打开麦克风: ```python import pyaudio p = pyaudio.PyAudio() stream = p.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True, frames_per_buffer=1024) ``` 这将创建一个音频流对象,允许你从麦克风读取音频数据。请注意,这里的示例设置了麦克风的一些参数(格式、通道、采样率和缓冲区大小),你可以根据自己的需求进行调整。 2. 如果你的环境中没有安装`pyaudio`库,你需要先安装它。你可以通过在终端中运行`pip install pyaudio`来安装。 3. 当你读取到音频数据后,你可以对其进行进一步的处理。例如,你可以使用FFT(快速傅里叶变换)来分析音频信号的频谱。你可以使用`numpy`和`scipy`库来进行FFT计算。你可以参考一些教程和代码示例来学习如何使用FFT进行音频分析。 4. 最后,在使用完麦克风后,记得关闭输入流和释放相关资源。你可以使用以下代码关闭输入流和终止`PyAudio`对象: ```python stream.close() p.terminate() ``` 这将关闭麦克风输入流并释放相关的资源。 总结一下,使用Python读取麦克风的基本步骤是:创建一个`PyAudio`对象,打开麦克风的音频流,读取音频数据,进行进一步处理(如FFT分析),最后关闭输入流和释放资源。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值