Utiliser un NSLevelIndicator pour un preview audio

Bonjour à  tous


 


J'ai un petit souci sous AVFoundation : je cherche à  visualiser en preview l'entrée son du micro intégré du mac. Pour cela j'ai tenté d'adapter l'exemple de projet AVRecorder mais spécifiquement pour mon projet.

Je n'y ai pas encore mis l'action d'enregistrement mais "logiquement" ça devrait marcher....mais non !! Je n'arrive pas à  avoir de valeur dans mon updateAudioLevels. 

Est ce que quelqu'un peut m'aider svp ?


Voici mon code : 



- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];


session = [[AVCaptureSession alloc]init];

[self researchDeviceForPopUp];
[b_audio selectItemAtIndex:2];


NSError *error = nil;
AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:[tabDevices objectAtIndex:1] error:&error];
if (audioInput) {
[session addInput:audioInput];


[self affectOutPut];

// Start updating the audio level meter
[self setAudioLevelTimer:[NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(updateAudioLevels:) userInfo:nil repeats:YES]];


}
else {
// Handle the failure.
}
}


-(void)affectOutPut
{
movieOutput = [[AVCaptureMovieFileOutput alloc]init];
if ([session canAddOutput:movieOutput]) {
[session addOutput:movieOutput];


}
else {
// Handle the failure.
}

movieOutput = [[AVCaptureMovieFileOutput alloc] init];
[movieOutput setDelegate:self];
[session addOutput:movieOutput];

audioPreviewOutput = [[AVCaptureAudioPreviewOutput alloc] init];
[audioPreviewOutput setVolume:0.f];
[session addOutput:audioPreviewOutput];


}

- (void)updateAudioLevels:(NSTimer *)timer
{
NSInteger channelCount = 0;
float decibels = 0.f;



// Sum all of the average power levels and divide by the number of channels

for (AVCaptureConnection *connection in [[self movieOutput] connections]) {
for (AVCaptureAudioChannel *audioChannel in [connection audioChannels]) {

decibels += [audioChannel averagePowerLevel];
channelCount += 1;
}
}

decibels /= channelCount;

float val = pow(10.f, 0.05f * decibels) * 20.0f;
NSLog(@val = %.2f décibel = %.2f chanelcount = %ld,val,decibels,channelCount);


[level setFloatValue:val]; //level est un NSLevelIndicator
}



Réponses

  • Bon ... mon problème semble être complexe puisque aucune réponse !!!!


  • Salut,


     


    Tu as trouvé la solution à  ton problème ? qu'est-ce que cela donne en debug ligne par ligne. Où est-ce que cela coince ?


     


    seb


  • Non toujours pas


     


    en fait, rien ne passe dans updateAudioLevels


  • tu peux filer ton code complet stp


  • Merci iLandes pour ton aide


     


    Voici mon projet


     


  • Salut j'ai jeté un coup d'oeil à  ton projet. Il fonctionne correctement. Je suis réparti de la démo fourni par Apple : AVRecorder puis j'ai fait le tri dans ton projet...


     


    Pour le .h



    #import <Cocoa/Cocoa.h>
    #import <AVFoundation/AVFoundation.h>

    @interface Document : NSDocument
    {
    IBOutlet NSLevelIndicator *level;

    NSArray *tabDevices;

    AVCaptureSession *session;
    AVCaptureDeviceInput *audioDeviceInput;
    AVCaptureAudioPreviewOutput *audioPreviewOutput;

    NSArray *observers;
    }


    #pragma mark Device Selection
    @property (retain) NSArray *audioDevices;
    @property (assign) AVCaptureDevice *selectedAudioDevice;

    #pragma mark - Recording
    @property (retain) AVCaptureSession *session;

    #pragma mark - Preview
    @property (assign) IBOutlet NSLevelIndicator *audioLevelMeter;

    @end

    pour le .m



    #import "Document.h"

    @interface Document ()

    // Properties for internal use
    @property (retain) AVCaptureDeviceInput *audioDeviceInput;
    @property (retain) AVCaptureAudioPreviewOutput *audioPreviewOutput;
    @property (retain) AVCaptureMovieFileOutput *movieFileOutput;
    @property (assign) NSTimer *audioLevelTimer;
    @property (retain) NSArray *observers;

    // Methods for internal use
    - (void)refreshDevices;

    @end


    @implementation Document

    @synthesize audioDeviceInput;
    @synthesize audioDevices;
    @synthesize session;
    @synthesize audioLevelMeter;
    @synthesize audioPreviewOutput;
    @synthesize movieFileOutput;
    @synthesize audioLevelTimer;
    @synthesize observers;

    - (id)init
    {
    self = [super init];
    if (self) {
    // Create a capture session
    session = [[AVCaptureSession alloc]init];


    // Capture Notification Observers
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    id runtimeErrorObserver = [notificationCenter addObserverForName:AVCaptureSessionRuntimeErrorNotification
    object:session
    queue:[NSOperationQueue mainQueue]
    usingBlock:^(NSNotification *note) {
    dispatch_async(dispatch_get_main_queue(), ^(void) {
    [self presentError:[[note userInfo] objectForKey:AVCaptureSessionErrorKey]];
    });
    }];
    id didStartRunningObserver = [notificationCenter addObserverForName:AVCaptureSessionDidStartRunningNotification
    object:session
    queue:[NSOperationQueue mainQueue]
    usingBlock:^(NSNotification *note) {
    NSLog(@did start running);
    }];
    id didStopRunningObserver = [notificationCenter addObserverForName:AVCaptureSessionDidStopRunningNotification
    object:session
    queue:[NSOperationQueue mainQueue]
    usingBlock:^(NSNotification *note) {
    NSLog(@did stop running);
    }];
    observers = [[NSArray alloc] initWithObjects:runtimeErrorObserver, didStartRunningObserver, didStopRunningObserver, nil];



    audioPreviewOutput = [[AVCaptureAudioPreviewOutput alloc] init];

    // Attach outputs to session
    movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
    [session addOutput:movieFileOutput];

    audioPreviewOutput = [[AVCaptureAudioPreviewOutput alloc] init];
    [audioPreviewOutput setVolume:0.f];
    [session addOutput:audioPreviewOutput];

    // Select devices if any exist
    [self setSelectedAudioDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]];

    // Initial refresh of device list
    [self refreshDevices];


    }
    return self;
    }

    - (NSString *)windowNibName
    {
    return @Document;
    }

    - (void)windowControllerDidLoadNib:(NSWindowController *)aController
    {
    [super windowControllerDidLoadNib:aController];

    // Start the session
    [[self session] startRunning];

    // Start updating the audio level meter
    [self setAudioLevelTimer:[NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(updateAudioLevels:) userInfo:nil repeats:YES]];

    }

    - (void)windowWillClose:(NSNotification *)notification
    {
    // Invalidate the level meter timer here to avoid a retain cycle
    [[self audioLevelTimer] invalidate];

    // Stop the session
    [[self session] stopRunning];


    // Remove Observers
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    for (id observer in [self observers])
    [notificationCenter removeObserver:observer];
    }

    #pragma mark - Getters & Setters

    - (AVCaptureDevice *)selectedAudioDevice
    {
    return [audioDeviceInput device];
    }

    - (void)setSelectedAudioDevice:(AVCaptureDevice *)selectedAudioDevice
    {
    [[self session] beginConfiguration];

    if ([self audioDeviceInput]) {
    // Remove the old device input from the session
    [session removeInput:[self audioDeviceInput]];
    [self setAudioDeviceInput:nil];
    }

    if (selectedAudioDevice) {
    NSError *error = nil;

    // Create a device input for the device and add it to the session
    AVCaptureDeviceInput *newAudioDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:selectedAudioDevice error:&error];
    if (newAudioDeviceInput == nil) {
    dispatch_async(dispatch_get_main_queue(), ^(void) {
    [self presentError:error];
    });
    } else {
    if (![selectedAudioDevice supportsAVCaptureSessionPreset:[session sessionPreset]])
    [[self session] setSessionPreset:AVCaptureSessionPresetHigh];

    [[self session] addInput:newAudioDeviceInput];
    [self setAudioDeviceInput:newAudioDeviceInput];
    }
    }

    [[self session] commitConfiguration];
    }


    #pragma mark - Audio Preview

    - (float)previewVolume
    {
    return [[self audioPreviewOutput] volume];
    }

    - (void)setPreviewVolume:(float)newPreviewVolume
    {
    [[self audioPreviewOutput] setVolume:newPreviewVolume];
    }

    - (void)updateAudioLevels:(NSTimer *)timer
    {
    NSInteger channelCount = 0;
    float decibels = 0.f;

    // Sum all of the average power levels and divide by the number of channels
    for (AVCaptureConnection *connection in [[self movieFileOutput] connections]) {
    for (AVCaptureAudioChannel *audioChannel in [connection audioChannels]) {
    decibels += [audioChannel averagePowerLevel];
    channelCount += 1;
    }
    }

    decibels /= channelCount;

    [[self audioLevelMeter] setFloatValue:(pow(10.f, 0.05f * decibels) * 20.0f)];
    }


    #pragma mark - Device selection
    - (void)refreshDevices
    {
    [self setAudioDevices:[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio]];

    [[self session] beginConfiguration];

    if (![[self audioDevices] containsObject:[self selectedAudioDevice]])
    [self setSelectedAudioDevice:nil];

    [[self session] commitConfiguration];
    }

    @end


    D'autre pourront peut-être amélioré tout cela ;-)


     


  • Bonjour iLandes


     


    Désolé pour ma réponse tardive ... vacances obligent !!!


     


    Super sympa ta correction


     


    Enormes mercis


     


    A+


  • Pour ceux que cela intéresse le projet AVRecorder limité au vue mètre ce trouve sur GitHub, les améliorations sont les bienvenues.

Connectez-vous ou Inscrivez-vous pour répondre.