2017-03-14 1 views
0

J'essaie de développer un compteur SPL pour un projet uni dans iOS, j'ai suivi un tutoriel en ligne sur la façon d'obtenir l'entrée audio et afficher le niveau d'entrée, mais cette tutoriel montre l'entrée comme une intensité de couleur variable et aussi à la valeur RMS, pas le pic. J'ai trouvé deux messages précédents à ce sujet mais ils ne sont pas assez informatifs pour aider, et étant un débutant à empiler débordement, je suis incapable de demander un soutien supplémentaire sur les réponses fournies.Afficher le niveau SPL en valeur numérique plutôt que de varier l'intensité des couleurs

Previous Post 1

Previous Post 2

Le tutoriel de projet, j'ai suivi est en cours d'exécution en Objective-C plutôt que Swift est une vieille collection vidéo, mais il ne (presque) ce que je dois à si Je n'ai pas essayé de changer rapidement, jusqu'à ce que je comprenne ce que je fais et pourquoi je le fais.

Voici le code entier pour l'enregistrement et le suivi de niveau d'entrée:

//Lynda.Com Tutorial Project 


#import "ViewController.h" 

@import AudioToolbox; 
@import AVFoundation; 

#define kOutputBus 0 
#define kInputBus 1 

@interface ViewController() 

@property (nonatomic,weak) IBOutlet UIView *indicatorView; 

@end 

@implementation ViewController 

static AudioComponentInstance audioUnit; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    [self setupAudio]; 
} 

- (void) setupAudio { 
    AudioComponentDescription desc; 

    desc.componentType = kAudioUnitType_Output; 
    desc.componentSubType = kAudioUnitSubType_RemoteIO; 
    desc.componentManufacturer = kAudioUnitManufacturer_Apple; 
    desc.componentFlags = 0; 
    desc.componentFlagsMask = 0; 

    AudioComponent comp = AudioComponentFindNext(NULL, &desc); 

    OSStatus status = AudioComponentInstanceNew(comp, &audioUnit); 
    if (status != noErr) { 
     NSAssert(status == noErr,@"Error"); 
    } 

    AudioStreamBasicDescription audioFormat; 

    audioFormat.mSampleRate = 44100.00; 
    audioFormat.mFormatID = kAudioFormatLinearPCM; 
    audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 
    audioFormat.mFramesPerPacket = 1; 
    audioFormat.mChannelsPerFrame = 1; 
    audioFormat.mBitsPerChannel = 16; 
    audioFormat.mBytesPerFrame = audioFormat.mChannelsPerFrame * sizeof(SInt16); 
    audioFormat.mBytesPerPacket = audioFormat.mFramesPerPacket * audioFormat.mBytesPerFrame; 

    UInt32 flag = 1; 
    status = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag)); 
    if (status != noErr) { 
     NSAssert(status == noErr,@"Error"); 
    } 

    flag = 0; 
    status = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof(flag)); 
    if (status != noErr) { 
     NSAssert(status == noErr,@"Error"); 
    } 

    status = AudioUnitSetProperty(audioUnit , kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &audioFormat, sizeof(audioFormat)); 
    if (status != noErr) { 
     NSAssert(status == noErr,@"Error"); 
    } 

    AURenderCallbackStruct callbackStruct; 
    callbackStruct.inputProc = recordingCallback; 
    callbackStruct.inputProcRefCon = (__bridge void*)self; 

    status = AudioUnitSetProperty(audioUnit , kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, kInputBus, &callbackStruct, sizeof(callbackStruct)); 
    if (status != noErr) { 
     NSAssert(status == noErr,@"Error"); 
    } 

    status = AudioUnitInitialize(audioUnit); 
    if (status != noErr) { 
     NSAssert(status == noErr,@"Error"); 
    } 

} 

static OSStatus recordingCallback(

            void *inRefCon, 
            AudioUnitRenderActionFlags *ioActionFlags, 
            const AudioTimeStamp *inTimeStamp, 
            UInt32 inBusNumber, 
            UInt32 inNumberFrames, 
            AudioBufferList *ioData 

          ) { 

    AudioBuffer buffer; 

    buffer.mNumberChannels = 1; 
    buffer.mDataByteSize = inNumberFrames * sizeof(SInt16); 
    buffer.mData = malloc(buffer.mDataByteSize); 

    AudioBufferList bufferList; 
    bufferList.mNumberBuffers = 1; 
    bufferList.mBuffers[0] = buffer; 

    OSStatus status = AudioUnitRender(audioUnit , ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &bufferList); 
    if (status != noErr) { 
     printf("Error\n"); 
     return -1; 
    } 

    SInt16 *frameBuffer = buffer.mData; 

    double totalAmplitude = 0; 

    for (int i = 0; i < inNumberFrames; i++) { 
     //printf("%i\n",frameBuffer[i]); 
     totalAmplitude += frameBuffer[i] * frameBuffer[i]; 
    } 

    totalAmplitude /= inNumberFrames; 

    totalAmplitude = sqrt(totalAmplitude); 

    float alphaFloat = totalAmplitude/(float)SHRT_MAX * 2; 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     ViewController *viewController = (__bridge ViewController*)inRefCon; 
     viewController.indicatorView.backgroundColor = [UIColor colorWithRed:1.0 green:0 blue:0 alpha:alphaFloat]; 
    }); 

    return noErr; 
} 

- (IBAction)recordButtonPressed:(id)sender { 
    NSError *error; 
    [[AVAudioSession sharedInstance] setActive:YES error:&error]; 
    if (error != nil) { 
     NSAssert(error == nil, @"Error"); 
    } 
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:&error]; 
    if (error != nil) { 
     NSAssert(error == nil, @"Error"); 
    } 

    [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) { 
     if (granted) { 
      OSStatus status = AudioOutputUnitStart(audioUnit); 
      if (status != noErr) { 
       NSAssert(status == noErr,@"Error"); 
      } 
     } else { 
      NSAssert(NO, @"Error"); 
     } 
    }]; 
} 

- (IBAction)stopButtonPressed:(id)sender { 
    OSStatus status = AudioOutputUnitStop(audioUnit); 
    if (status != noErr) { 
     NSAssert(status == noErr,@"Error"); 
    } 
    NSError *error; 
    [[AVAudioSession sharedInstance] setActive:NO error:&error]; 
    if (error != nil) { 
     NSAssert(error == nil, @"Error"); 
    } 
    self.indicatorView.backgroundColor = [UIColor clearColor]; 
} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

- (void) dealloc { 
    OSStatus status = AudioComponentInstanceDispose(audioUnit); 
    if (status != noErr) { 
     NSAssert(status == noErr,@"Error"); 
    } 
} 

@end 

Ce que je besoin d'aide pour la compréhension est, comme je crois en ce morceau de code ici:

dispatch_async(dispatch_get_main_queue(), ^{ 
    ViewController *viewController = (__bridge ViewController*)inRefCon; 
    viewController.indicatorView.backgroundColor = [UIColor colorWithRed:1.0 green:0 blue:0 alpha:alphaFloat]; 

C'est On dit à UIView d'afficher des intensités variables de rouge, ce que je veux, c'est changer cela en un nombre variable. La valeur RMS en dBSPL n'est pas un problème, il est affiché comme valeur changeante en permanence à la place de la boîte rouge dans l'application en cours d'exécution que je pourrais vraiment faire avec de l'aide, toute aide est incroyablement appréciée dans avance!

Merci,

Chris

Répondre

0

La valeur que vous souhaitez afficher est dans la alphaFloat variable. Vous devez ajouter une propriété UILabel à votre ViewController, vous pouvez l'appeler dBSPLView. Puis, en ce lieu où viewController.indicatorView.backgroundColor est changé, vous feriez quelque chose comme ceci:

viewController.dBSPLView.text = [NSString stringWithFormat:@"%f", alphaFloat]; 
+0

Cela a fait l'affaire, je vous remercie beaucoup! – ChrisBearBaker