1

したがって、基本的には、iPhone のマイクが拾っている現在の dB レベルを、主に客観的な C コードで監視したいだけです。Google で調べたところ、AudioQueues を使用して「ハードコア」な C プログラミングを行う必要があるようです。私は C コーディングが得意ではないので、以下のコードは最低限の C コーディングを使用して、温かく親しみのある Objective-C の世界に送り返すことができる結果を得ようとする私の試みです。問題は、 AudioQueue を作成できないように見えることです。返される「ステータス」は「不明なエラー」である -50 です。

基本的に、viewDidLoad で Audio キューを設定し、その上に ac コールバックを宣言します。コールバック内から現在の dB 値を取得して、それを目的の c ランドに送り返しますが、AudioQueue が呼び出されないため、コールバックは呼び出されません。適切に作成されていますが、その理由はわかりません。私が間違っていることを確認できる人、またはこのオーディオ関連の目的の C ラッパーの方向を教えてくれる人。乾杯。

@interface ViewController ()
{
    AudioQueueRef mQueue;
}

- (void)receivedSoundOfPower:(Float32)power;

@end

@implementation ViewController


void MyInputBufferHandler(  void *                              inUserData,
                                      AudioQueueRef                     inAQ,
                                      AudioQueueBufferRef                   inBuffer,
                                      const AudioTimeStamp *                inStartTime,
                                      UInt32                                inNumPackets,
                                      const AudioStreamPacketDescription*   inPacketDesc)
{
    ViewController *self = (__bridge id)inUserData;

    AudioQueueLevelMeterState meters[1];
    UInt32 dlen = sizeof(meters);
    OSStatus status = AudioQueueGetProperty(inAQ,kAudioQueueProperty_CurrentLevelMeterDB,meters,&dlen);
    if (status == 0)
    {
        Float32 peakPower = meters[0].mPeakPower;
        [self receivedSoundOfPower:peakPower];
    }
}

- (void)receivedSoundOfPower:(Float32)power
{
    NSLog(@"%f", power);
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    OSStatus status =AudioQueueNewInput(kAudioStreamAnyRate,
                                MyInputBufferHandler,
                                (__bridge void *)(self),
                                NULL,
                                NULL,
                                0,
                                &(mQueue));

    NSLog(@"%ld", status);

    // Turn on level metering (iOS 2.0 and later)
    UInt32 on = 1;
    AudioQueueSetProperty(mQueue,kAudioQueueProperty_EnableLevelMetering,&on,sizeof(on));

    // Do any additional setup after loading the view, typically from a nib.
}
4

1 に答える 1

6

DB 値を取得するためだけに Audio Queues を使用する必要はありません。次のようなことができます。

- (void)setup {
    // record audio to /dev/null
    NSURL *url = [NSURL fileURLWithPath:@"/dev/null"];

    // some settings
    NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:
                              [NSNumber numberWithFloat: 44100.0],                 AVSampleRateKey,
                              [NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey,
                              [NSNumber numberWithInt: 2],                         AVNumberOfChannelsKey,
                              [NSNumber numberWithInt: AVAudioQualityMax],         AVEncoderAudioQualityKey,
                              nil];

    // create a AVAudioRecorder
    NSError *error;
    recorder = [[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error];

    if (recorder) {
        [recorder prepareToRecord];
        recorder.meteringEnabled = YES;
        [recorder record];
        levelTimer = [NSTimer scheduledTimerWithTimeInterval:0.01f target:self selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES];
    }
}

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

    // here is the DB!
    float peakDecebels =  [recorder peakPowerForChannel:1];
            float avaeragePower = [recorder averagePowerForChannel:1];
}

また、オーディオ データにアクセスする場合は、このライブラリが最適です: http://alexbw.github.com/novocaine/

于 2012-10-14T13:14:51.243 に答える