Bonjour,

Tout d'abord, désolé si ce topic a déjà été traité sur ce forum (et si tel est le cas, pouvez vous m'indiquer où ? :p).

Je souhaite développer une appli pour OSX qui (dans un premier temps) :
- Identifie le périphérique d'entrée audio par défaut (microphone intégré sur mon mac book) ;
- Lance une capture audio ;
- Ecrit la valeur des échantillons capturés en temps réel dans la console

Mon but est de faire du DSP en temps réel sur ces échantillons, mais une fois que je peux lire les échantillons et les afficher dans la console, je sais faire .

Après quelques jours à lire de la doc Apple et à zoner sur des forums, je bricole le code (de base) ci-dessous pour "tester si ça marche" avant d'aller plus loin. (J'ai quelques années de programmation derrière moi en C, Java, C++, mais mon expérience en programmation pour OSX est à peu près nulle :p et j'aimerais bien éviter de passer plus de temps à me battre avec l'HAL qu'à jouer avec mes petits échantillons fraichement capturés ).

Bon, j'arrête un peu de raconter ma vie. Voici mon code - je vous fais grâce de la gestion des erreurs - et ce que je crois comprendre (merci de me corriger là où je me trompe parce que si j'avais vraiment compris, je ne serais pas là :p) :

- Fonction principale :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
int main(int argc, const char * argv[])
{

    @autoreleasepool {
        //  Get input device
        AudioDeviceID inDevice= GetDefaultInputDevice();
        NSLog(@"Input device id = %u", inDevice);  //  Qui vaut 42, est-ce normal ?

        //  register the IOProc
        AudioDeviceIOProcID theIOProcID = NULL;
        
        //  Create an IO procedure.
        OSStatus theError = AudioDeviceCreateIOProcID(inDevice, MyIOProc, nil, &theIOProcID);

        // ensure theIOProcID != NULL
        if(theIOProcID == NULL) {
        
        //  start IO
        theError = AudioDeviceStart(inDevice, theIOProcID);
        
        //  keep on capturing for 1s
        sleep(1);
        
        //  stop IO
        theError = AudioDeviceStop(inDevice, theIOProcID);
        
        //  unregister the IOProc
        theError = AudioDeviceDestroyIOProcID(inDevice, theIOProcID);
    }
    return 0;
}
- Récupérer le périphérique audio d'entrée par défaut :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//  Get the default input device
AudioDeviceID GetDefaultInputDevice()
{
    //  Declarations
    AudioDeviceID theAnswer = 0;
    UInt32 theSize = sizeof(AudioDeviceID);
    
    //  Describe the device I want to fetch
    AudioObjectPropertyAddress theAddress = {
        kAudioHardwarePropertyDefaultInputDevice,
        kAudioObjectPropertyScopeGlobal,
        kAudioObjectPropertyElementMaster
    };
    
    //  Get it.
    OSStatus theError = AudioObjectGetPropertyData(kAudioObjectSystemObject,
                                                   &theAddress,
                                                   0,
                                                   NULL,
                                                   &theSize,
                                                   &theAnswer);
    return theAnswer;
}
- Pour chaque échantillon capturé, lire sa valeur et la logger dans la console :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
OSStatus MyIOProc(AudioDeviceID           inDevice,
                  const AudioTimeStamp*   inNow,
                  const AudioBufferList*  inInputData,
                  const AudioTimeStamp*   inInputTime,
                  AudioBufferList*        outOutputData,
                  const AudioTimeStamp*   inOutputTime,
                  void*                   inClientData)
{
    OSStatus error = noErr;
    
    //  Log sample in dbg console
    fprintf(stderr, "value = %f", NewGetVolumeScalar(inDevice, TRUE, 0));

    return error;
}
- Lire l'échantillon capturé (le volume dans mon cas ^^) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Float32 NewGetVolumeScalar(AudioDeviceID inDevice, bool inIsInput, UInt32 inChannel)
{
    //  Declarations
    Float32 theAnswer = 0;
    UInt32 theSize = sizeof(Float32);

    //  Not really necessary in this case since I always want the first one.
    AudioObjectPropertyScope theScope = inIsInput ? kAudioDevicePropertyScopeInput:kAudioDevicePropertyScopeOutput;

    //  Describe what I want to read (volume value for current sample).
    AudioObjectPropertyAddress theAddress = {
        kAudioHardwareServiceDeviceProperty_VirtualMasterVolume,
        theScope,
        inChannel
    };
    
    //  Check if this it exists for the pointed device.
    if(!AudioHardwareServiceHasProperty(inDevice, &theAddress)) {
        fprintf(stderr, "Audio object doesn't have such a property data \n");

    }
    
    //  Read the sample value
    OSStatus theError = AudioObjectGetPropertyData(inDevice,
                                                   &theAddress,
                                                   0,
                                                   NULL,
                                                   &theSize,
                                                   &theAnswer);

    return theAnswer;
}

Mon problème c'est qu'apparemment, ça ne marche pas :
Pendant la seconde que dure la capture, la console m'affiche en boucle la même valeur : "value = 0.916667".

Quelqu'un a-t-il une idée de ce qui foire ? Je ne suis pas un expert de l'API Mac et résoudre ce problème (qui doit être simple) risque de me prendre plusieurs semaines si je dois le faire seul :p.

Merci et encore désolé si ce topic a été traité ailleurs (auquel cas je serais suffisamment puni en ayant tapé ce pavé pour rien ).