使用 Cocos2D 检测 iPhone 麦克风中的打击

发布于 2024-11-18 15:25:01 字数 2236 浏览 5 评论 0原文

我正在使用 Cocos2D 和系统粒子,我希望我用英语正确地写了这篇文章。 我在使用 iPhone 麦克风以某种方式识别声音时遇到问题。

我的应用程序中有不同的部分,在其中一个部分中,我使用麦克风来检测是否有人向麦克风“吹气”。这部分一开始工作正常,但如果您转到应用程序播放声音的其他部分,然后返回该区域并尝试吹气,则它将不起作用。

我调试了代码,即使我不在这个场景中,levelTimeCallback 也始终有效。我真的不知道发生了什么事。我已经使用

[[SimpleAudioEngine shareEngine] stopBackgroundMusic];

停止了所有声音有人知道我做错了什么吗?顺便说一句,在模拟器中工作得很好,但在 iPhone 中却不行。

录音机在 onEnter 方法中设置

-(void) onEnter {
     [super onEnter];
     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];
          NSLog(@"I'm in the recorder");

       } else

              NSLog(@"recorder error");

}

这是“检查”声音时的 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;  

if (lowPassResults > 0.55)
{   
    NSLog(@"Mic blow detected");

    self.emitter = [[CCParticleExplosion alloc] initWithTotalParticles:5];
    [self addChild: emitter z:1];           
    emitter.texture = [[CCTextureCache sharedTextureCache] addImage: @"hoja.png"];      
    emitter.autoRemoveOnFinish = YES;

}
NSLog(@"Inside levelTimerCallback");}

I'm using Cocos2D and the system particles and I hope I wrote this correctly in English.
I'm having problems to recognize sounds with the iPhone mic in certain way.

I have different sections in my application, in one of them I use the mic to detect if someone is "blowing air" into the mic. This part works fine at the beginning, but if you go to other section of the app that plays sound and later you return to this area and try to blow air, it won't work.

I debuged the code, and the levelTimeCallback is always working even if I'm not in this scene. I don't really know what's happening. I've stopped all sounds using

[[SimpleAudioEngine sharedEngine] stopBackgroundMusic];

Anyone knows what I'm doing wrong? BTW works perfectly in simulator, but not in iPhone.

The recorder is set in the onEnter method

-(void) onEnter {
     [super onEnter];
     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];
          NSLog(@"I'm in the recorder");

       } else

              NSLog(@"recorder error");

}

This is the levelTimerCallback method were the sound is "checked"

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

if (lowPassResults > 0.55)
{   
    NSLog(@"Mic blow detected");

    self.emitter = [[CCParticleExplosion alloc] initWithTotalParticles:5];
    [self addChild: emitter z:1];           
    emitter.texture = [[CCTextureCache sharedTextureCache] addImage: @"hoja.png"];      
    emitter.autoRemoveOnFinish = YES;

}
NSLog(@"Inside levelTimerCallback");}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伴随着你 2024-11-25 15:25:01

同样的问题。
有两种方法可以解决这个问题。

1:使用AVAudioPlayer播放音乐或音效。

2:将#import "CDAudioManager.h"添加到AppDelegate.m并添加

 [CDAudioManager initAsynchronously:kAMM_PlayAndRecord];

- (void) applicationDidFinishLaunching:(UIApplication*)application`

来源

Same problem.
There are 2 ways to solved this.

1: Use AVAudioPlayer to play music or sound effect.

2: Add #import "CDAudioManager.h"to AppDelegate.m and Add

 [CDAudioManager initAsynchronously:kAMM_PlayAndRecord];

to

- (void) applicationDidFinishLaunching:(UIApplication*)application`

source

情话墙 2024-11-25 15:25:01

最后,在阅读了音频会话食谱和不同类型的相关帖子后,我找到了解决方案。只需将此代码块放入 init 方法中即可:

    UInt32 sessionCategory = kAudioSessionCategory_PlayAndRecord;
    UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
    AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
    AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
    AudioSessionSetActive(true);

Finally, after reading the Audio Session cookbook and different kind of post related I found the solution. Jus put this code block in the init method:

    UInt32 sessionCategory = kAudioSessionCategory_PlayAndRecord;
    UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
    AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
    AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
    AudioSessionSetActive(true);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文