Enregistrement, modification et lecture audio sur iOS

EDIT: À la fin, j'ai utilisé exactement comme je l'ai expliqué ci-dessous, AVRecorder pour save le discours et openAL pour le décalage de hauteur et la lecture. Cela a fonctionné assez bien.

J'ai une question concernant l'logging, la modification et la lecture audio. J'ai déjà posé une question similaire ( save, modifier la hauteur et lire l'audio en time réel sur iOS ) mais j'ai maintenant plus d'informations et je pourrais faire avec quelques conseils supplémentaires s'il vous plaît.

Donc d'abord c'est ce que j'essaie de faire (sur un fil séparé du fil principal):

  1. surveiller le micro de l'iphone
  2. vérifier le son supérieur à un certain volume
  3. si au-dessus du seuil, démarrer l'logging, par ex.
  4. continuer à save jusqu'à ce que le volume passe en dessous du seuil, par exemple si la personne cesse de parler
  5. modifier la hauteur du son enregistré.
  6. son de lecture

Je pensais utiliser l'AVRecorder pour surveiller et save le son, bon tutoriel ici: http://mobileorchard.com/tutorial-detecting-when-a-user-blows-into-the-mic/

et je pensais utiliser openAL pour modifier la hauteur de l'audio enregistré.

Donc, ma question est, est-ce que ma pensée est correcte dans la list des points ci-dessus, ai-je manqué quelque chose ou y a-t-il un moyen meilleur / plus facile de le faire. Puis-je éviter de mélanger des bibliothèques audio et d'utiliser AVFoundation pour modifier la hauteur de ton?

Vous pouvez soit utiliser AVRecorder ou quelque chose de plus bas comme l'unité audio IO en time réel.

Le concept de «volume» est assez vague. Vous voudrez peut-être examiner la différence entre calculer les valeurs de crête et de RMS et comprendre comment intégrer une valeur RMS sur une période donnée (disons 300 ms, ce qui est utilisé par un VU-mètre).

Fondamentalement, vous additionnez tous les carrés des valeurs. Vous devez prendre la racine carrée et convertir en dBFS avec 10 * log10f (sqrt (sum / num_samples)), mais vous pouvez le faire sans le sqrt en une seule fois avec 20 * log10f (sum / num_samples).

Vous devrez faire beaucoup de réglages des time d'intégration et des seuils pour que le comportement se fasse comme vous le souhaitez.

Pour le pitch shifting, je pense que OpenAL avec le truc, la technique derrière elle s'appelle l'interpolation à bande limitée – https://ccrma.stanford.edu/~jos/resample/Theory_Ideal_Bandlimited_Interpolation.html

Cet exemple montre un calcul rms en moyenne courante. Le tampon circulaire conserve un historique des carrés et élimine le besoin de sumr les carrés à chaque opération. Je ne l'ai pas exécuté donc le traiter comme pseudo code;)

Exemple:

class VUMeter { protected: // samples per second float _sampleRate; // the integration time in seconds (vu meter is 300ms) float _integrationTime; // these maintain a circular buffer which contains // the 'squares' of the audio samples int _integrationBufferLength; float *_integrationBuffer; float *_integrationBufferEnd; float *_cursor; // this is a sort of accumulator to make a running // average more efficient float _sum; public: VUMeter() : _sampleRate(48000.0f) , _integrationTime(0.3f) , _sum(0.) { // create a buffer of values to be integrated // eg 300ms @ 48khz is 14400 samples _integrationBufferLength = (int) (_integrationTime * _sampleRate); _integrationBuffer = new float[_integrationBufferLength + 1]; bzero(_integrationBuffer, _integrationBufferLength); // set the pointers for our ciruclar buffer _integrationBufferEnd = _integrationBuffer + _integrationBufferLength; _cursor = _integrationBuffer; } ~VUMeter() { delete _integrationBuffer; } float getRms(float *audio, int samples) { // process the samples // this part accumulates the 'squares' for (int i = 0; i < samples; ++i) { // get the input sample float s = audio[i]; // remove the oldest value from the sum _sum -= *_cursor; // calculate the square and write it into the buffer double square = s * s; *_cursor = square; // add it to the sum _sum += square; // increment the buffer cursor and wrap ++_cursor; if (_cursor == _integrationBufferEnd) _cursor = _integrationBuffer; } // now calculate the 'root mean' value in db return 20 * log10f(_sum / _integrationBufferLength); } }; 

Le rééchantillonnage OpenAL modifie inversement la hauteur et la durée. par exemple, un son rééchantillonné à une hauteur plus élevée jouera pendant un laps de time plus court et donc plus rapidement.