SDK iOS Lecture de tonalités avec le cadre Audio Toolbox

Bienvenue au septième volet de notre série sur la manière de concevoir et de construire une version des années 1980 de l’iOS? Phone? app. Dans ce tutoriel, je vais montrer comment jouer la tonalité audio appropriée pour chaque numéro sur le clavier du téléphone..

Aperçu final de l'application

Voici un aperçu de ce que nous allons construire au cours de cette série:

Avant que tu commences?

Il s'agit d'une série en plusieurs parties conçue pour enseigner les sujets de SDK iOS intermédiaires. Le contenu deviendra de plus en plus complexe au fur et à mesure que la série avance. Si, à un moment quelconque, vous vous perdez à suivre cette série, vous devrez peut-être prendre du recul et vous frayer un chemin dans notre série Learn Objective-C ou dans notre série Début pour le développement du SDK iOS..

Dans le dernier tutoriel de cette série, j'ai montré comment initier un appel iPhone après avoir composé un numéro sur le clavier et comment formater l'affichage du numéro lorsqu'un utilisateur tapait un chiffre. Dans ce didacticiel, nous allons ajouter les tonalités promises à chacun des boutons 0 à 9..

Présentation audio iOS

Le SDK iOS est livré avec plusieurs frameworks qui fournissent diverses méthodes pour lire des clips audio et même générer de l'audio à la volée. Pommes Guide de programmation multimédia décrit le but de chaque infrastructure audio disponible comme suit:

  • Utilisez le Cadre de lecteur multimédia lire des chansons, des livres audio ou des podcasts audio à partir de la bibliothèque iPod d'un utilisateur?
  • Utilisez le Cadre AV Foundation jouer et enregistrer de l'audio à l'aide d'une simple interface Objective-C?
  • Utilisez le Boîte à outils audio cadre permettant de lire de l'audio avec des capacités de synchronisation, d'accéder à des paquets d'audio entrants, d'analyser des flux audio, de convertir des formats audio et d'enregistrer de l'audio avec accès à des paquets individuels?
  • Utilisez le Cadre d'unité audio connecter et utiliser des plug-ins de traitement audio?
  • Utilisez le Cadre OpenAL pour fournir une lecture audio positionnelle dans les jeux et autres applications. iOS supporte OpenAL 1.1?

-Guide de programmation multimédia: Utiliser l'audio

Toute une série de didacticiels peut être dédiée à chacun des cadres de la liste ci-dessus, mais il suffit de préciser que, pour ce didacticiel, nous utiliserons le cadre Audio Toolbox en raison d'une offre unique: les services sonores système. Les services audio système sont une interface de niveau C conçue pour la lecture d'effets sonores d'interface utilisateur courts et d'autres petits clips audio d'une durée de 30 secondes ou moins..

Le processus de lecture d’un clip audio avec System Sound Services s’effectue en trois étapes:

  1. Enregistrer un clip audio avec les services son du système pour la lecture dans un avenir (pas si éloigné)
  2. Recevoir un ID de son système (SSID) identifiant de manière unique le clip audio enregistré avec le serveur de son du système.
  3. Appelez le serveur de son du système avec le SSID approprié pour commencer la lecture..

Le reste de ce didacticiel implémentera ce processus pour reproduire des tonalités DTMF préenregistrées pour les chiffres du clavier, entre 0 et 9..

Pourquoi utilisons-nous des tonalités préenregistrées au lieu de générer la fréquence appropriée à la volée? Essentiellement pour gagner du temps et pour rendre ce tutoriel plus accessible en évitant les mathématiques impliquées dans les fonctions sinusoïdales et la génération de fréquences. Si vous préférez emprunter cette voie, les articles suivants vous seront probablement utiles:

  • Signalisation multifréquence à deux tonalités
  • Clavier tactile
  • Onde sinusoïdale
  • Forums iPhone Dev SDK: générer un bip

Voulez-vous vraiment savoir comment générer du son à la volée? Si cet article reçoit au moins 10 commentaires demandant un tutoriel sur la création audio à partir de rien avant le 1er mai 2011, je réaliserai une série avancée de SDK iOS sur ce sujet. Aucune promesse que cela impliquera spécifiquement les tonalités DTMF, mais ce sera certainement quelque chose de génial.

Avec les connaissances théoriques de côté, passons au code et réalisons cette fonctionnalité!

Étape 1: Importer le cadre AudioToolbox

Nous devrons commencer par importer la structure Audio Toolbox dans notre application afin de rendre les services son du système disponibles pour notre code. Pour ce faire, sélectionnez le projet "PhoneAppSkin" dans la sous-fenêtre Navigateur de projet de Xcode, puis sélectionnez "PhoneAppSkin" sous "CIBLES", puis sélectionnez l'onglet "Générer des phases". Après cela, votre écran devrait ressembler à ceci:

Ensuite, cliquez sur le menu déroulant "Lier le binaire avec les bibliothèques", puis cliquez sur le symbole "+" pour ajouter un nouveau cadre à la phase de liaison de notre projet..

Enfin, recherchez le cadre "AudioToolbox" dans la fenêtre contextuelle, puis cliquez sur "Ajouter"..

Ensuite, ouvrez le PhoneViewController.h fichier et ajoutez la ligne nécessaire pour réellement importer le framework Audio Toolbox dans votre classe:

 #importation  #importation 

Les fonctions de la Boîte à outils Audio devraient maintenant être accessibles à votre classe.!

Étape 2: Importer les fichiers WAV Touch Tone

Téléchargez et ouvrez le code source attaché à ce message Mobiletuts + et trouvez le dossier intitulé "Audio". Faites glisser tout ce dossier dans le dossier "Ressources" du navigateur de projet Xcode, en veillant à cocher l'option "Copier" lorsque vous y êtes invité. Vous devriez vous retrouver avec un écran qui ressemble à ceci:

Étape 3: Créer un tableau pour les références SSID

Dans PhoneViewController.h, ajoutez la déclaration de tableau de style C suivante:

 @interface PhoneViewController: UIViewController SystemSoundID toneSSIDs [10]; 

Ligne 13 déclare un tableau de type C SystemSoundID avec une capacité maximale de 10.

Le stockage des ID de son système dans cette matrice nous permettra de référencer rapidement le clip audio approprié dans la numberButtonPressed: méthode plus tard.

Étape 4: Enregistrer les sons du système de tonalité

Ouvrir PhoneViewController.m et sauter au initWithCoder méthode sur ligne 17. Quand le PhoneViewController est d'abord initialisé et le initWithCoder Lorsque la méthode est appelée, nous voulons enregistrer les sons système pour chaque tonalité à utiliser sur le clavier avec le serveur de sons du système iOS. Lorsqu'un clip audio est enregistré sur le serveur de son, nous pouvons demander au serveur de lire le fichier son ultérieurement lorsque vous appuyez sur le clavier..

Pour enregistrer les tonalités tactiles 0-9, ajoutez le code suivant:

 -(id) initWithCoder: (NSCoder *) aDecoder self = [super initWithCoder: aDecoder]; if (self) phoneNumberString = [[NSString alloc]] init]; pour (int compte = 0; compte < 10; count++) NSString *toneFilename = [NSString stringWithFormat:@"DTMF_%02d", count]; NSURL *toneURLRef = [[NSBundle mainBundle] URLForResource:toneFilename withExtension:@"wav"]; SystemSoundID toneSSID = 0; AudioServicesCreateSystemSoundID( (CFURLRef) toneURLRef, &toneSSID ); toneSSIDs[count] = toneSSID;   return self; 

Sur ligne 24, une pour boucle qui va itérer 10 fois commence. Le but de ceci pour la boucle consiste à ajouter un nouvel ID de son système à la toneSSIDs tableau pour chacune des tonalités associées aux touches 0 - 9.

Sur ligne 25, une instance de NSString est instancié qui contiendra le nom de fichier de la tonalité tactile DTMF appropriée. Une note intéressante sur cette ligne est la stringWithFormat: appel de méthode et le % 02d spécificateur de format. Ce spécificateur de format convertira n'importe quel chiffre en un chiffre de 2 caractères, complété à zéro. Ainsi, par exemple, 0 devient "00", 1 devient "01", 2 devient "02", etc..

Sur ligne 27, la NSBundle class est utilisé pour générer un chemin de système de fichiers vers le nom de fichier généré à la ligne 25 avec l'extension "wav" ajoutée. NSLog cette valeur si vous souhaitez voir le chemin complet par vous-même.

Ligne 29 crée une variable pour tenir le SystemSoundID qui sera généré par le serveur de son système iOS suivant.

Comme note de côté, SystemSoundID est juste un typedef pour le type de Mac UInt32, qui est lui-même un typedef pour non signé longtemps. Par conséquent, nous aurions pu déclarer la variable sur cette ligne de type non signé longtemps, mais ce serait une mauvaise pratique car les futures versions d’iOS pourraient modifier la SystemSoundID tapez, causant la rupture du code. Néanmoins, il est bon de garder cela à l'esprit lorsque vous travaillez avec SystemSoundIDs parce que le compilateur avertit parfois de l’incompatibilité non signé longtemps les types.

Lignes 31 - 34 sont un appel de fonction de style c à AudioServicesCreateSystemSoundID, qui prend un CFURL (URL Core Foundation) du chemin de fichier audio pour générer un ID son système et une référence SystemSoundID qui seront utilisés pour stocker le SSID après sa création. Remarquez comment le caractère et commercial (c'est-à-dire '&') apparaît avant le toneSSID variable sur la ligne 33? Ceci est un opérateur de préfixe unaire qui convertit le toneSSID paramètre dans l'adresse mémoire de la variable au lieu de la valeur stockée en mémoire pour cette variable. Ceci est fait pour que le AudioServicesCreateSystemSoundID fonction peut stocker le numéro de SSID généré directement dans le toneSSID adresse de mémoire, permettant à l'appelant de fonction (c'est-à-dire notre méthode) d'accéder au SSID généré sans renvoyer le SSID de la fonction.

Cela semble un peu déroutant? Ce sera probablement le cas, sauf si vous avez déjà de l'expérience en programmation dans un langage tel que C, C ++ ou Go. Etant donné qu'Objective-C est un sur-ensemble strict du langage C, le SDK iOS repose parfois sur des bibliothèques écrites en C procédural. Si la syntaxe C n'a pas de sens, ne vous inquiétez pas trop pour le moment, mais relever le défi de compléter votre connaissance du SDK iOS avec les bases du langage C à l'avenir!

Sur ligne 35, l'index du toneSSIDs tableau de style c désigné par le courant compter la valeur est attribuée à la valeur créée par le AudioServicesCreateSystemSoundID une fonction. Cette valeur SSID sera référencée ultérieurement pour reproduire la tonalité appropriée lorsque l'utilisateur tapera sur les numéros du clavier..

Étape 5: Jouer des tonalités sur le robinet

le numberButtonPressed: méthode est appelée chaque fois que la touchUpInside événement se déclenche pour les boutons 0 - 9. En raison des indices 0-9 du toneSSIDs array contient maintenant la tonalité correspondante pour chaque bouton, les trois lignes de code suivantes suffisent pour reproduire la tonalité appropriée:

 -(IBAction) numberButtonPressed: (UIButton *). PressedButton int toneIndex = [presséButton.titleLabel.text intValue]; SystemSoundID toneSSID = toneSSIDs [toneIndex]; AudioServicesPlaySystemSound (toneSSID); self.phoneNumberString = [self.phoneNumberString stringByAppendingString :unkButton.titleLabel.text]; [auto displayPhoneNumber]; 

Ligne 96 convertit la valeur de texte de la presse UIButton titre d'un entier d'une chaîne.

Avec le chiffre du clavier obtenu, ligne 97 récupère un SystemSoundID du toneSSIDs tableau.

Sur ligne 98, la AudioServicesPlaySystemSound la fonction est appelée avec le SSID qui vient d’être récupéré pour commencer la lecture par tonalité.

C'est tout! Allez-y et enregistrer et construire le projet maintenant, et vous devriez trouver que les numéros de clavier ont des effets sonores!

Étape 6: Rendre le jeu vif

Il y a un petit problème avec la solution actuelle. Avez-vous remarqué le délai entre le toucher du bouton et la tonalité générée? Dans la partie 6 de cette série, les boutons du clavier ont été configurés pour déclencher la touchUpInside action. Cette action se déclenche lorsque l'utilisateur retire son doigt du bouton. Cependant, la tonalité doit être émise dès que l'utilisateur appuie sur le bouton, pas après avoir retiré son doigt. Pour résoudre ce problème, ouvrez PhoneView.xib, retirer le touchUpInside IBAction références pour tous les boutons, puis lier chaque bouton atterrissage action à la numberButtonPressed: méthode.

Si vous avez besoin d’aide pour savoir comment procéder, reportez-vous à la partie 6, étape 1 de cette série..

Emballer

Ce tutoriel a été une visite éclair du framework Audio Toolbox et des services System Sound. Si vous avez des questions, n'hésitez pas à les laisser dans les commentaires ci-dessous et je ferai de mon mieux pour vous répondre. Bien sûr, il n'y a pas assez d'heures dans la journée pour que je vérifie tous les messages précédents chaque jour, de sorte que les mois passent, vous aurez peut-être plus de chance de me contacter via Twitter: @markhammonds.