2015-04-21 1 views
1

J'essaie de faire quelque chose de vraiment simple, mais j'ai seulement fait des progrès dans les débuts. Je veux seulement obtenir des données audio d'un microphone dans un fichier, pour le moment. Je ferai plus de traitement des données dans le bloc une fois que je franchirai cet obstacle. Je suis fatigué de certains des idéosyncracies que je trouve avec AVAudioEngine, et je me demande si je devrais revenir à AudioUnits qui est probablement un peu mieux débogué (bien que plus complexe). Tout d'abord, il semble que l'AudioEngine ne peut pas être démarré tant que le InputNode n'est pas instancié, et vous ne pouvez pas utiliser son outputFormatForBus pour obtenir son format (la fréquence d'échantillonnage est nulle); vous devez utiliser inputFormatForBus.Comment installer un tap sur le noeud d'entrée par défaut de AudioEngine et écrire dans le fichier

Maintenant que je l'ai travail et je reçois des appels sur le bloc avec ce qui semble être des données valides, je ne peux pas écrire dans le fichier sans elle générer une exception, avec l'erreur:

« erreur écriture des données du tampon dans le fichier, L'opération n'a pas pu être terminée. (Erreur com.apple.coreaudio.avfaudio 1768846202.) »

('de NISS) Cela semble indiquer qu'il ya une sorte d'erreur soit le format que je fournis ou le format que le bloc devient .

Des pensées?

_engine = [[AVAudioEngine alloc] init]; 

_outputFileURL = [NSURL URLWithString:[NSTemporaryDirectory() stringByAppendingString:@"tempOutput.caf"]]; 

AVAudioInputNode *inputNode = [_engine inputNode]; 
AVAudioFormat *format = [inputNode inputFormatForBus:1]; 
NSMutableDictionary *recordSettings = format.settings.mutableCopy; 
[recordSettings addEntriesFromDictionary:@{ 
           AVFormatIDKey : @(kAudioFormatMPEG4AAC), 
           AVEncoderAudioQualityKey : @(AVAudioQualityMedium) 
           }]; 

AVAudioFile *outputFile = [[AVAudioFile alloc] initForWriting:_outputFileURL settings:recordSettings error:&error]; 

[inputNode installTapOnBus:1 bufferSize:4096 format:format block:^(AVAudioPCMBuffer *buffer, AVAudioTime *when) { 
    NSError *error; 

    // as AVAudioPCMBuffer's are delivered this will write sequentially. The buffer's frameLength signifies how much of the buffer is to be written 
    // IMPORTANT: The buffer format MUST match the file's processing format which is why outputFormatForBus: was used when creating the AVAudioFile object above 
    NSAssert([outputFile writeFromBuffer:buffer error:&error], @"error writing buffer data to file, %@", [error localizedDescription]); 
}]; 
if (!_engine.isRunning) [self startEngine]; 

Merci.

code mis à jour en fonction du commentaire de @ mat

+0

'paramètres: [paramètres de format]'. C'est probablement le problème. Vous avez besoin de paramètres de format de fichier de sortie corrects. – matt

+0

J'essayais juste d'écrire les données en tant que PCM pour garder les choses simples (voir l'exemple UsingAVAudioEngineforPlaybackMixingandRecording d'Apple). J'ai ajouté des clés de dictionnaire pour enregistrer le fichier en MP4 AAC, mais toujours pas de chance. – mahboudz

+1

Ok, mais je vous suggère toujours de ne pas baser les paramètres du fichier de sortie sur le format de noeud d'entrée _at all_. Essayez de trouver un groupe de paramètres complètement indépendants qui fonctionne. C'est ce que j'ai dû faire la première fois que j'ai écrit un robinet. – matt

Répondre

2

Voici comment je suis arrivé dans ce, au cas où quelqu'un d'autre va dans le même problème. @matt commenté correctement que je devrais créer des paramètres indépendants, et ne pas utiliser le format qui a été associé à l'inputNode.

commonFormat = [[AVAudioFormat alloc] initWithCommonFormat:AVAudioPCMFormatFloat32 sampleRate:44100 channels:2 interleaved:NO]; 

engine = [[AVAudioEngine alloc] init]; 
AVAudioInputNode *inputNode = engine.inputNode; 

NSError *error; 
AVAudioFile *outputFile = [[AVAudioFile alloc] initForWriting:_outputFileURL settings:commonFormat.settings error:&error]; 

[inputNode installTapOnBus:0 bufferSize:4096 format:commonFormat block:^(AVAudioPCMBuffer *buffer, AVAudioTime *when) { 
    NSError *error; 

    NSAssert([outputFile writeFromBuffer:buffer error:&error], @"error writing buffer data to file, %@", [error localizedDescription]); 
}];