噪音检测说明文档

1. 系统功能设计与分析

(1)噪声分贝检测功能模块
为了实现用户对周围声音进行分贝实时监测的功能,用户通过点击开
始按钮开始进行监测,和当前检测到的噪声的大小。用户上传的噪声信息会关联到分享模块中,获取用户的手机坐标位置是为了在地图上定位,以便绘制噪声地图,这样的得到的噪声地图,有时间、声音大小、更真实、形象,也更符合大众的生活化需求。在噪声检测页面,为了考虑用户的视觉多元化需求,设计了以波浪线的表达方式动态显示噪声的变化,同时为了直观精确,在旁边又加入了数字表达的方式,满足了多年龄层人群的不同需求,不仅有动画效果的趣味性,而且有数字显示保证准确性。主界面效果图如下所示。

Simulator Screen Shot 2017年6月9日 上午9.06.56.png

(2)噪声频率监测模块:这个模块主要是为用户提供一些有关噪声频率信息,是用户能够更全面了解身边的声音信息。


Simulator Screen Shot 2017年6月9日 上午9.08.57.png

2. 实现思路及核心代码

(1)噪声分贝模块
声音采集使用系统的AVFoundation框架,首先在工程引入该框架。该框架中的AVAudioSession单利类负责大部分音频的处理。其中噪声检测模块主要使用AVAudioRecorder创建一个录音机获取噪音输入。在使用前必须进行音频会话的初始化:

-(void)setAudioSession{
    AVAudioSession *audioSession=[AVAudioSession sharedInstance];
    //设置为播放和录音状态,以便可以在录制完之后播放录音
    [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
    [audioSession setActive:YES error:nil];
}

进行录音文件的设置:

- (NSDictionary *)getAudioSetting {
    NSMutableDictionary *dicM = [NSMutableDictionary dictionary];
    // 设置录音格式为lpcm
    [dicM setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey];
    // 设置录音采样率,8000是电话采样率,对于一般录音已经够了
    [dicM setObject:@(8000) forKey:AVSampleRateKey];
    // 声道
    [dicM setObject:@(2) forKey:AVNumberOfChannelsKey];
    // 每个采样点位数
    [dicM setObject:@(8) forKey:AVLinearPCMBitDepthKey];
    // 是否使用浮点数采样
    [dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey];
    // 录音品质
    [dicM setObject:@(AVAudioQualityHigh) forKey:AVSampleRateConverterAudioQualityKey];
    return dicM;
}

因为要实时的检测当前环境的噪音分贝值,所以需要开启定时器:

-(NSTimer *)timer {  \\使用延迟加载的方式
    if (!_timer) {
        _timer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(audioPowerChange) userInfo:nil repeats:YES];
    }
    return _timer;
}

接下来进行声音分贝的计算,power 为均值,powerMax为峰值,注意每次计算之前要调用updateMeters进行更新测量值, 获取到分贝值后使用setGaugeValue 进行UI表盘的刻度显示。

-(void)audioPowerChange{
    [self.audioRecorder updateMeters];//更新测量值
    float power = [self.audioRecorder averagePowerForChannel:0];
    float powerMax = [self.audioRecorder peakPowerForChannel:0];
    NSLog(@"power = %f, powerMax = %f",power, powerMax);
    CGFloat progress = (1.0 / 160.0) * (power + 160.0);
    power = power + 160  - 50;
    int dB = 0;
    if (power < 0.f) {
        dB = 0;
    } else if (power < 40.f) {
        dB = (int)(power * 0.875);
    } else if (power < 100.f) {
        dB = (int)(power - 15);
    } else if (power < 110.f) {
        dB = (int)(power * 2.5 - 165);
    } else {
        dB = 110;
    }
    NSLog(@"progress = %f, dB = %d", progress, dB);
    self.test.retLabel.text = [NSString stringWithFormat:@"%d db", dB];
    [self.test setGaugeValue:dB animation:YES];
}

(2)频率监测模块
该模块使用控制器HZViewController完成。该控制器含有四个成员。
其中EZAudioPlot继承自UIView,该类负责实时显示当前的频率图谱的绘制,EZMicrophone负责采集音频,EZAudioFFTRolling负责生意相关的傅立叶计算。因为EZAudioPlot相关类基于AVFoundation框架,所以在使用前必须设置AVAudioSession:

AVAudioSession *session = [AVAudioSession sharedInstance];
    NSError *error;
    [session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];

HZViewController控制器必须实现代理EZMicrophoneDelegate

#pragma mark - EZMicrophoneDelegate
//------------------------------------------------------------------------------

-(void)    microphone:(EZMicrophone *)microphone
     hasAudioReceived:(float **)buffer
       withBufferSize:(UInt32)bufferSize
 withNumberOfChannels:(UInt32)numberOfChannels
{
    //
    // Calculate the FFT, will trigger EZAudioFFTDelegate
    //
    [self.fft computeFFTWithBuffer:buffer[0] withBufferSize:bufferSize];
    
    __weak typeof (self) weakSelf = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        [weakSelf.audioPlotTime updateBuffer:buffer[0]
                              withBufferSize:bufferSize];
    });
}

//------------------------------------------------------------------------------
#pragma mark - EZAudioFFTDelegate
//------------------------------------------------------------------------------

- (void)        fft:(EZAudioFFT *)fft
 updatedWithFFTData:(float *)fftData
         bufferSize:(vDSP_Length)bufferSize
{
    float maxFrequency = [fft maxFrequency];
    NSString *noteName = [EZAudioUtilities noteNameStringForFrequency:maxFrequency
                                                        includeOctave:YES];
    NSLog(@"---->%@", noteName);
    __weak typeof (self) weakSelf = self;
    dispatch_async(dispatch_get_main_queue(), ^{
//        weakSelf.maxFrequencyLabel.text = [NSString stringWithFormat:@"Highest Note: %@,\nFrequency: %.2f", noteName, maxFrequency];
        weakSelf.coorView.heighNoteLabel.text = noteName;
        weakSelf.coorView.hzValueLabel.text = [NSString stringWithFormat:@"%.2f", maxFrequency];
        [weakSelf.audioPlotFreq updateBuffer:fftData withBufferSize:(UInt32)bufferSize];
    });
}

WHCoordinateView类继承自UIView,该类负责x,y坐标系的绘制。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,540评论 25 708
  • 不同图像灰度不同,边界处一般会有明显的边缘,利用此特征可以分割图像。需要说明的是:边缘和物体间的边界并不等同,边缘...
    大川无敌阅读 13,968评论 0 29
  • 林肯说“一滴蜂蜜比一加仑胆汁能捕到更多的苍蝇”正如太阳和风的故事: 太阳和风在争论谁更强更有力。风说他能比太阳更快...
    Joyce小熊阅读 813评论 0 0
  • D83 今天下午看到一个朋友发的朋友圈,给我笑了半天,虽然我也不能清楚地说出笑点在哪,哈哈。 首先他发的这个图片里...
    当额咧阅读 225评论 0 0
  • 漫天繁星中的一颗,虽然明亮却容易被人遗忘;宇宙中的光源,独一无二,点亮自己,照亮别人,受世人敬仰。——小筑 前几天...
    贤雅小筑阅读 308评论 0 2