2010-12-12 39 views
2

Dans l'exemple d'application aurioTouch, l'unité audio RemoteIO est configurée pour le LPCM non entrelacé à 2 canaux au format à 8,24 points fixes. C'est le format préféré sur la plate-forme iOS et je suppose que c'est ce que le matériel ADC émet. Ils ont même fait un commentaire à ce sujet (source):iOS LPCM Entrée audio non entrelacée avec 2 canaux: impossible?

// set our required format - Canonical AU format: LPCM non-interleaved 8.24 fixed point 
outFormat.SetAUCanonical(2, false); 

donc j'attendre à ce que lorsque l'application reçoit plus tard un tampon audio, il disposera des deux canaux emballés dans ses membres MDATA dans un certain ordre. Quelque chose comme ceci:

mData = [L1, L2, L3, L4, R1, R2, R3, R4]; 

Où L et R représentent les données des canaux gauche et droit d'un microphone stéréo. Seulement, il semble que ne peut pas être le cas parce que SetAUCannonical() ne définit pas assez memmory pour maintenir le canal supplémentaire:

void SetAUCanonical(UInt32 nChannels, bool interleaved) 
{ 
    mFormatID = kAudioFormatLinearPCM; 
#if CA_PREFER_FIXED_POINT 
    mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift); 
#else 
    mFormatFlags = kAudioFormatFlagsCanonical; 
#endif 
    mChannelsPerFrame = nChannels; 
    mFramesPerPacket = 1; 
    mBitsPerChannel = 8 * sizeof(AudioUnitSampleType); 
    if (interleaved) 
     mBytesPerPacket = mBytesPerFrame = nChannels * sizeof(AudioUnitSampleType); 
    else { 
     mBytesPerPacket = mBytesPerFrame = sizeof(AudioUnitSampleType); 
     mFormatFlags |= kAudioFormatFlagIsNonInterleaved; 
    } 
} 

Si « intercalées » est faux, il ne se multiplie pas le « mBytesPerPacket » et mBytesPerFrame » par le Nombre de canaux. Il n'y aura pas assez de bits dans le cadre pour stocker le canal supplémentaire.

L'exemple de code est-il légèrement trompeur lorsqu'il demande 2 canaux? Faut-il être juste demander 1 canal, puisque c'est ce que sa va revenir quand même:

outFormat.SetAUCanonical(1, false); 

Puis-je « réparer » SetAUCannonical comme cela pour rendre les choses claires ?:

mChannelsPerFrame = nChannels; 
if (!interleaved) { 
    mChannelsPerFrame = 1 
    mFormatFlags |= kAudioFormatFlagIsNonInterleaved; 
} 
mFramesPerPacket = 1; 
mBitsPerChannel = 8 * sizeof(AudioUnitSampleType); 
mBytesPerPacket = mBytesPerFrame = nChannels * sizeof(AudioUnitSampleType);  

Ou est il y a une autre raison pour laquelle vous demanderiez 2 canaux? Je ne pense même pas que le micro est un micro stéréo.

Répondre

2

L'entrée micro intégrée du micro et de l'oreillette sont toutes deux mono. Le kit de connexion de caméra a peut-être permis l'entrée audio stéréo de certains micros USB sur certains appareils iOS plus récents fonctionnant avec des versions précédentes du système d'exploitation, mais je n'ai vu aucun rapport avec la version actuelle du système d'exploitation.

De même, vérifiez si le format non-entrelacé 2 canaux (stéréo) peut renvoyer 2 tampons au rappel RemoteIO, au lieu des données concaténées dans 1 tampon.

+0

Je vais étudier ce soir. –

+0

C'était mon expérience. Je ne spécifiais rien pour l'état entrelacé. Par défaut, le simulateur voulait disposer d'un seul tampon entrelacé dans le rappel d'E/S, mais le périphérique affichait par défaut deux tampons de canal unique. –

1

Je pense que vous confondez "Interleaved" et "Non-Interleaved" et comment CoreAudio vous donne ces données dans les ABL. SetAUCanonical() fait la bonne chose. Un ABL possède un tableau de tampons variable dans lequel, dans le cas non-entrelacé, chaque tampon ne contient que les données pour un seul canal.

0

Le problème provient des noms de variables (parfois) trompeurs. Je ne l'aime pas non plus, mais voici une explication à ce qui se passe.

Lorsque mFormatFlags est NonInterleaved (of any form) alors mChannelsPerFrame spécifie le nombre de canaux et le reste des champs doit spécifier les propriétés souhaitées pour un seul canal. Vous n'aurez donc PAS besoin de multiplier par le nombre de canaux. Les valeurs appropriées seront:

mBytesPerPacket = mFramesPerPacket * sizeof(sampleSizeInBytes); // e.g. sizeof(float) 
mBytesPerFrame = sizeof(sampleSizeInBytes);