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 :
- 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
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; }
- 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
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; }
- 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 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; }
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).
Partager