Проблема с микрофоном Android - PullRequest
1 голос
/ 02 августа 2010

Можно ли обнаружить (в режиме реального времени), если кто-то дует в микрофон? Спасибо

Ответы [ 2 ]

2 голосов
/ 07 июля 2011

Да, это так,

Вы можете использовать класс AudioRecord и проанализировать форму сигнала, которая возвращается.

РЕДАКТИРОВАТЬ: Только что провёл небольшое исследование - одно предупреждение.Оказывается, Android не очень хорошо справляется с обработкой звука в реальном времени.Вы увидите задержку в 100 мс.Если это нормально для вашего проекта (возможно, так оно и есть), это здорово, но просто о чем стоит знать.

0 голосов
/ 21 ноября 2013

Добавление платформы AVFoundation Framework

Чтобы использовать класс AVAudioRecorder в SDK, нам нужно добавить в проект инфраструктуру AVFoundation:

Далее мы импортируем заголовки AVFoundation в файл интерфейса контроллера представления и настроим переменную экземпляра AVAudioRecorder:

Разверните ветку проекта MicBlow на панели «Группы и файлы» проекта. Разверните папку Classes Отредактируйте MicBlowViewController.h, выбрав его Обновите файл:

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreAudio/CoreAudioTypes.h>

@interface MicBlowViewController : UIViewController {
AVAudioRecorder *recorder;
}

Принимая вход от микрофона Раскомментируйте шаблонный метод ViewDidLoad Обновите его следующим образом.

- (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]);

}

Выбор уровня звука Мы будем использовать таймер для проверки уровня звука примерно 30 раз в секунду. Добавьте переменную экземпляра NSTimer и метод обратного вызова к нему в MicBlowViewController.h.

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreAudio/CoreAudioTypes.h>

@interface MicBlowViewController : UIViewController {
AVAudioRecorder *recorder;
NSTimer *levelTimer;
  }

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

  @end

Обновите ViewDidLoad файла .m, чтобы включить таймер. - (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]);

}

Сейчас мы просто сэмплируем уровень входного аудиосигнала напрямую / без фильтрации. Добавьте реализацию levelTimerCallback: в файл .m:

  - (void)levelTimerCallback:(NSTimer *)timer {
[recorder updateMeters];
NSLog(@"Average input: %f Peak input: %f", [recorder averagePowerForChannel:0],     [recorder peakPowerForChannel:0]);

}

При отправке сообщения updateMeters обновляются измерители средней и пиковой мощности. Измеритель использует логарифмическую шкалу, где -160 - полная тишина, а ноль - максимальный ввод.

Не забудьте отпустить таймер в dealloc. Изменения выделены жирным шрифтом:

- (void)dealloc {
[levelTimer release];
[recorder release];
[super dealloc];
 }

Прослушивание дующего звука Как уже упоминалось в обзоре, мы будем использовать фильтр низких частот, чтобы уменьшить вклад звуков высоких частот в уровень. Алгоритм создает текущий набор результатов, включающий входные данные прошлых выборок; нам понадобится переменная экземпляра для хранения результатов. Обновите .h файл.

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreAudio/CoreAudioTypes.h>

@interface MicBlowViewController : UIViewController {
AVAudioRecorder *recorder;
NSTimer *levelTimer;
double lowPassResults;
}

Реализуйте алгоритм, заменив levelTimerCallback: метод на:

- (void)levelTimerCallback:(NSTimer *)timer {
[recorder updateMeters];

const double ALPHA = 0.05;
double peakPowerForChannel = pow(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);
 }

Для моего приложения нужно 0,95. Мы заменим строку журнала на простое условие:

 - (void)listenForBlow:(NSTimer *)timer {
[recorder updateMeters];

const double ALPHA = 0.05;
double peakPowerForChannel = pow(10, (0.05 * [recorder peakPowerForChannel:0]));
lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * lowPassResults;

if (lowPassResults > 0.95)
    NSLog(@"Mic blow detected");
}

Это пример .

и тема .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...