• 20 heures
  • {0} Facile|{1} Moyenne|{2} Difficile

Ce cours est visible gratuitement en ligne.

Ce cours existe en livre papier.

J'ai tout compris !

Mis à jour le 21/06/2013

Multimédia : le son

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Les devices Apple sont en mesure de jouer et d'enregistrer des sons. Vous utilisez certainement l'application iPod pour écouter vos albums préférés et l'application Dictaphone pour prendre des notes vocales. Que diriez-vous d'accéder à ces possibilités dans vos propres applications ? C'est ce que vous allez découvrir dans ce chapitre. Vous devez penser que le code à utiliser est compliqué et que vous n'avez pas (encore) le niveau nécessaire !

Je vous rappelle que vous êtes maintenant dans la quatrième partie de ce tutoriel et que vous avez appris énormément de choses dans les trois parties précédentes. Dans ce chapitre, vous allez relever un nouveau défi, et je vous assure que vous vous en sortirez honorablement !

Alors commençons sans plus attendre…

Jouer des éléments audio

Plusieurs techniques permettent de jouer des sons sur un device. La plus simple consiste à passer par les « System Sound Services » du framework AudioToolbox. Une technique, plus complexe, consiste à utiliser un AVAudioPlayer.

Je vais vous montrer comment utiliser ces deux techniques. À vous de choisir celle qui est le mieux adaptée aux applications que vous voulez réaliser.

La technique « System Sound Services »

Cette technique est particulièrement bien adaptée aux sons utilisés dans l'interface utilisateur d'une application : quand vous appuyez sur un bouton ou quand vous vous déplacez dans un contrôle par exemple.

Il y a cependant quelques restrictions.

  1. Les sons doivent avoir une durée maximale de 30 secondes.

  2. Seuls quelques codecs audio sont supportés :

  • AMR (Adaptive Multi-Rate) ;

  • iLBC (internet Low Bitrate Codec) ;

  • IMA/ADPCM (IMA-4) ;

  • Linear PCM ;

  • µLaw and aLaw.

Codec ? Qu'est-ce encore que cela ?

Codec est l'abréviation de « codeur/décodeur ». Les fichiers audio sont généralement compressés pour réduire leur taille. Le format de compression (le codec) utilisé dépend de l'application dans laquelle le fichier audio est créé. Pour qu'il puisse être joué sur une machine donnée (un Mac, un PC, un iPhone, etc.), il faut que ce dernier dispose du décodeur correspondant. Les iPhone/iPod Touch/iPad disposent des codecs cités plus haut.

Si un fichier audio utilise un codec non reconnu, il ne sera pas joué sur le device. Pour éviter ce désagrément, je vous conseille de convertir vos sons au format CAF en utilisant le programme afconvert sur votre Mac.

Cliquez sur l'icône Applications dans le Dock, ouvrez le dossier Utilitaires puis cliquez sur l'icône Terminal. Déplacez-vous dans le dossier qui contient le fichier à convertir. Supposons que vous vouliez convertir le fichier 22-new.aif en 22-new.caf ; vous taperez quelque chose comme ceci :

afconvert -f caff -d LEI16@44100 22-new.aif 22-new.caf

Ça me semble plutôt indigeste comme commande. Pourrais-je avoir quelques explications ?

Vous avez raison : la commande afconvert n'est pas très « sexy ». Mais quelle efficacité ! Elle permet de convertir à peu près tous les formats de fichiers audio en une seule ligne. Pour avoir toutes les informations nécessaires à l'utilisation de cette commande, tapez afconvert -h dans la fenêtre Terminal.

À titre d'information, sachez que le paramètre LEI16@44100 demande une conversion sur 16 bits avec un échantillonnage en 44100 Hz. Plus ces deux valeurs (16 et 44100) sont élevées, meilleur est le son obtenu. Mais aussi, plus grande est la taille du fichier. Faites quelques essais en utilisant une conversion sur 8, 16 et 24 bits en 11025, 22050 et 44100 Hz. Ce qui donne des paramètres compris entre LEI8@11025 et LEI24@44100. À vous de juger quel est le meilleur compromis entre la qualité sonore et la taille du fichier obtenu.

Voyons par la pratique comment utiliser les « System Sound Services » du framework AudioToolbox. Nous allons travailler sur un fichier audio nommé Applaudissements.caf.

Créez une nouvelle application basée sur le modèle Single View Application et donnez-lui le nom « ecouteAudio ».

Toutes les méthodes relatives aux « System Sound Services » se trouvent dans le framework AudioToolbox. La première étape va donc consister à ajouter ce framework à l'application. Pour cela, suivez les instructions visibles à la figure suivante.

  1. Cliquez sur la première icône affichée dans le volet de navigation.

  2. Sélectionnez l'onglet Build Phases dans la zone d'édition.

  3. Développez l'entrée Link Binary With Libraries.

  4. Cliquez sur l'icône +.

  5. Sélectionnez AudioToolbox.framework dans la boîte de dialogue.

  6. Cliquez sur Add pour ajouter le framework au projet.

Ajoutez le framework AudioToolbox

Pour jouer un son, vous allez placer le fichier audio correspondant dans les ressources de l'application. Cliquez du bouton droit sur la première icône du volet de navigation et sélectionnez New Group dans le menu contextuel. Donnez le nom « Resources » à ce nouveau dossier, puis glissez-déposez le fichier Applaudissements.caf du Finder dans ce dossier.

En consultant la documentation Apple sur le terme « System Sound Services Reference », vous pouvez voir qu'il vous faudra utiliser les deux méthodes suivantes :

  1. AudioServicesCreateSystemSoundID

  2. AudioServicesPlaySystemSound

Ces méthodes proviennent du framework AudioToolbox/AudioServices.h et sont déclarées dans le fichier d'en-têtes AudioServices.h.

La prochaine étape va donc consister à faire référence au framework dans le fichier d'en-têtes de l'application. Cliquez sur ViewController.h dans le volet de navigation et ajoutez l'instruction #import suivante :

#import <AudioToolbox/AudioServices.h>

Le fichier d'en-têtes doit maintenant ressembler à ceci :

#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioServices.h>
@interface ViewController : UIViewController
@end

Cliquez sur ViewController.m dans le volet de navigation et complétez la méthode viewDidLoad comme suit :

- (void)viewDidLoad
{
[super viewDidLoad];
SystemSoundID bravo;
AudioServicesCreateSystemSoundID(CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("Applaudissements"), CFSTR("caf"), NULL), &bravo);
AudioServicesPlaySystemSound(bravo);
}

Examinons les instructions contenues dans cette méthode.
La ligne 4 définit l'objet bravo de type SystemSoundID. C'est dans cet objet que sera stocké le son à jouer.

La ligne 5 appelle la méthode AudioServicesCreateSystemSoundID. Ne soyez pas effrayés par l'apparente complexité de cette méthode. Cette écriture un peu lourde vient du chaînage (entendez par là, de l'exécution consécutive) de plusieurs méthodes dans une seule instruction. Procédons par étapes, et vous verrez que cette instruction est tout à fait compréhensible.

La méthode AudioServicesCreateSystemSoundID admet deux arguments : l'adresse URL du fichier audio à jouer et l'adresse d'un objet SystemSoundID qui sera associée au son. Voici à quoi ressemble cette méthode :

AudioServicesCreateSystemSoundID(URL-fichier-audio, adresse-SystemSoundID);

Pour obtenir l'adresse URL d'un élément situé dans les ressources de l'application, nous utilisons la méthode CFBundleCopyResourceURL. Cette méthode admet quatre arguments : le nom du bundle à examiner, le nom de la ressource, l'extension de la ressource et le dossier dans lequel elle est stockée. Voici à quoi ressemble cette méthode :

CFBundleCopyResourceURL(nom-bundle,nom-ressource, extension-ressource, dossier-ressource);

Mais d'où viennent toutes ces informations ?

De la documentation Apple tout simplement ! Dans la page « System Sound Services Reference », examinez la section AudioServicesCreateSystemSoundID et vous trouverez toutes les informations nécessaires.

Le bundle de l'application est obtenu avec la méthode CFBundleGetMainBundle. Viennent ensuite le nom du fichier (CFSTR("Applaudissements")), son extension (CFSTR("caf")) et enfin le dossier du fichier (NULL).

Pourquoi ne pas avoir utilisé les chaînes Applaudissements et caf dans le deuxième et le troisième argument ? Et pourquoi le dernier argument est égal à NULL ?

Une fois encore, je vous renvoie à la documentation Apple.
Vous y apprendrez que le deuxième et le troisième argument doivent être des chaînes constantes et non de simples chaînes. De plus, pour transformer une chaîne en une chaîne constante, il faut utiliser la fonction CFSTR().

Quant au quatrième paramètre qui, rappelons-le, est censé définir le dossier dans lequel se trouve la ressource, la valeur NULL facilite l'écriture. En effet, elle indique que c'est au device de trouver dans quel dossier la ressource a été stockée. Tant que vous n'avez pas plusieurs centaines de ressources, cette technique est tout à fait possible. Alors, pourquoi s'en passer ?

La méthode CFBundleCopyResourceURL a donc retourné l'adresse URL de la ressource. Je vous rappelle que la méthode AudioServicesCreateSystemSoundID demande deux paramètres : l'adresse URL du fichier à jouer et l'adresse d'un objet SystemSoundID. Cette dernière est obtenue avec &bravo.

Nous arrivons donc à l'instruction suivante :

AudioServicesCreateSystemSoundID(CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("Applaudissements"), CFSTR("caf"), NULL), &bravo);

Je vous rassure tout de suite : le plus gros du travail a été fait. Maintenant, il suffit d'appeler la méthode AudioServicesPlaySystemSound en lui transmettant l'objet SystemSoundID pour déclencher la lecture du son :

AudioServicesPlaySystemSound(bravo);

Vous pouvez (enfin !) lancer l'application. Des applaudissements vous acclament ! Vous avez réussi à jouer votre premier son dans le simulateur. Bien entendu, cette application fonctionne sans problème sur votre device.

Le code source se trouve dans le dossier ecouteAudio.

ViewController.h
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioServices.h>
@interface ViewController : UIViewController
@end
ViewController.m
#import "ViewController.h"
@implementation ViewController
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
SystemSoundID bravo;
AudioServicesCreateSystemSoundID(CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("Applaudissements"), CFSTR("caf"), NULL), &bravo);
AudioServicesPlaySystemSound(bravo);
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
@end

La technique AVAudioPlayer

Les iPhone, iPod Touch et iPad disposent de l'application iPod, qui permet d'écouter de la musique et de visualiser des vidéos. Les techniques de programmation utilisées dans cette application sont accessibles aux développeurs Objective-C grâce (entre autres) à la classe AVAudioPlayer. Cette approche a plusieurs avantages par rapport à la précédente.

Elle permet :

  • de jouer des sons courts ou longs ;

  • de jouer des sons compressés, au format MP3 par exemple ;

  • d'utiliser plusieurs méthodes pour contrôler le son pendant qu'il est joué.

Elle repose sur :

  • l'utilisation des frameworks AVFoundation et AudioToolbox ;

  • la mise en place du delegate AVAudioPlayerDelegate ;

  • la définition d'un objet AVAudioPlayer ;

  • la mise en place de ressources dans l'application pour stocker le fichier audio à jouer ;

  • l'utilisation de méthodes sur l'objet AVAudioPlayer pour contrôler le son pendant qu'il est joué.

Commençons sans plus attendre. Définissez un nouveau projet basé sur le modèle Single View Application et donnez-lui le nom « audioPlayer ».

Insertion des frameworks dans le projet

Ajoutez les frameworks AVFoundation.framework et AudioToolbox.framework dans le projet. Comme indiqué à la figure suivante, cliquez sur la première icône affichée dans le volet de navigation (1), basculez sur l'onglet Build Phases dans le volet droit de Xcode (2), développez l'entrée Link Binary With Libraries (3), cliquez sur l'icône + (4) et ajoutez les deux frameworks dont nous avons parlé.

Ajoutez les deux frameworks
Définition de l'objet AVAudioPlayer et mise en place du delegate associé

Cliquez sur ViewController.h dans le volet de navigation et insérez-y deux instructions #import pour faire référence aux frameworks que vous avez ajoutés dans l'étape précédente :

#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>

Définissez la variable d'instance audioPlayer de classe AVAudioPlayer :

AVAudioPlayer * audioPlayer;

Cet objet va vous permettre de jouer des fichiers audio quelconques, à condition qu'ils soient compatibles avec les formats audio supportés par iOS : AAC, ALAC, HE-AAC, iLBC, IMA4, Linear PCM, MP3, µ-law ou a-law.

Pour vous tenir informés des événements relatifs à la lecture du fichier audio (position dans le son, fin du son atteint, etc.), mais également des événements externes (réception d'un appel téléphonique par exemple), l'application doit implémenter le protocole AVAudioPlayerDelegate. Pour ce faire, il vous suffit d'ajouter ce protocole dans la définition de l'interface :

@interface ViewController : UIViewController <AVAudioPlayerDelegate>
{
...
}

Si vous avez suivi mes consignes, le fichier ViewController.h doit maintenant ressembler à ceci :

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
@interface ViewController : UIViewController <AVAudioPlayerDelegate>
{
AVAudioPlayer * audioPlayer;
}
@end
Ajout du fichier audio dans les ressources

Le fichier d'en-têtes étant entièrement écrit, nous allons passer à l'étape suivante en ajoutant un fichier audio dans les ressources de l'application.

Cliquez du bouton droit sur la première icône affichée dans le volet de navigation et sélectionnez New Group dans le menu contextuel. Donnez le nom « Resources » au nouveau dossier. Ouvrez le Finder et glissez-déposez un fichier audio quelconque du Finder dans le dossier Resources. Au relâchement du bouton gauche de la souris, une boîte de dialogue est affichée. Assurez-vous que la case Copy items into destination group's folder soit cochée, puis cliquez sur Finish.

Le code de l'application

Il ne reste plus qu'à écrire le code de l'application.

Cliquez sur ViewController.m dans le volet de navigation. Cette première approche de la classe AVAudioPlayer se voulant avant tout pratique, nous allons nous contenter de jouer un son, sans chercher à le contrôler. Complétez la méthode viewDidLoad comme suit :

- (void)viewDidLoad
{
[super viewDidLoad];
AudioSessionInitialize (NULL, NULL, NULL, (__bridge void *)self);
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);
NSData *soundFileData;
soundFileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"morceau.mp3" ofType:NULL]]];
audioPlayer = [[AVAudioPlayer alloc] initWithData:soundFileData error:NULL];
if(!([audioPlayer prepareToPlay]))
NSLog(@"La méthode prepareToPlay a renvoyé la valeur FALSE");
audioPlayer.delegate = self;
[audioPlayer setVolume:1.0f];
[audioPlayer play];
}

La ligne 5 initialise le contexte audio :

AudioSessionInitialize (NULL, NULL, NULL, (__bridge void *)self);

Il n'est pas nécessaire de comprendre toutes les subtilités de cette instruction pour pouvoir l'utiliser. Sachez juste qu'elle doit toujours être appelée avant d'utiliser un objet AVAudioPlayer.

La ligne 7 définit l'entier sessionCategory et l'initialise avec la valeur :

kAudioSessionCategory_MediaPlayback;

Si vous vous reportez à la documentation Apple, vous verrez que cette constante demande au device de jouer le son dans tous les cas, y compris si le bouton muet est actif, ou encore si le device passe en mode veille.

La ligne 8 initialise la propriété kAudioSessionProperty_AudioCategory de la session audio en lui transmettant la valeur définie dans l'instruction précédente. Le fichier audio sera donc joué dans tous les cas, y compris quand le bouton muet est actif, ou encore si le device passe en mode veille :

AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);

La ligne 9 définit l'objet soundFileData de classe NSData :

NSData *soundFileData;

Cet objet est utilisé pour faire référence au fichier audio à jouer :

soundFileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"morceau.mp3" ofType:NULL]]];

Ne vous laissez pas surprendre par l'apparente complexité de cette instruction : elle se contente de chaîner trois messages. Si nous la décomposons en trois parties bien distinctes, tout sera bien plus clair.

L'objet soundFileData est initialisé (soundFileData =) avec un objet NSData ([NSData …) qui contient les données stockées à l'adresse spécifiée (dataWithContentsOfURL:). Cette URL se trouve dans le « bundle principal », c'est-à-dire dans l'application elle-même ([NSBundle mainBundle]).
Le nom du fichier est « morceau.mp3 » (pathForResource:@"morceau.mp3"). L'extension du fichier n'est pas précisée (ofType:NULL]) puisque le nom du fichier la contient déjà.

Alors, cette instruction ? Tout à fait compréhensible, n'est-ce pas ?

La ligne 13 réserve de la mémoire pour l'objet audioPlayer ([AVAudioPlayer alloc]) et l'initialise avec les données qui ont été placées dans l'objet soundFileData dans l'instruction précédente (initWithData:soundFileData) :

audioPlayer = [[AVAudioPlayer alloc] initWithData:soundFileData error:NULL];

Le son est prêt à être joué. La méthode prepareToPlay le précharge en mémoire. Si le préchargement ne s'est pas bien déroulé, la valeur FALSE est retournée. Dans ce cas, un message d'erreur est affiché dans la console :

if(!([audioPlayer prepareToPlay]))
NSLog(@"La méthode prepareToPlay a renvoyé la valeur FALSE");

L'instruction de la ligne 18 indique que les messages relatifs à l'objet audioPlayer seront traités dans ViewController.m :

audioPlayer.delegate = self;

La ligne 20 définit le volume sonore :

[audioPlayer setVolume:1.0f];

Et enfin, la ligne 22 lance la lecture du fichier audio :

[audioPlayer play];

Vous pouvez lancer l'application en cliquant sur l'icône Run. Je vous laisse savourer !

Le code de cette application se trouve dans le dossier audioPlayer.

ViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
@interface ViewController : UIViewController <AVAudioPlayerDelegate>
{
AVAudioPlayer * audioPlayer;
}
@end
ViewController.m
#import "ViewController.h"
@implementation ViewController
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
AudioSessionInitialize (NULL, NULL, NULL, (__bridge void *)self);
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);
NSData *soundFileData;
soundFileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"morceau.mp3" ofType:NULL]]];
audioPlayer = [[AVAudioPlayer alloc] initWithData:soundFileData error:NULL];
if(!([audioPlayer prepareToPlay]))
NSLog(@"La méthode prepareToPlay a renvoyé la valeur FALSE");
audioPlayer.delegate = self;
[audioPlayer setVolume:1.0f];
[audioPlayer play];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
@end

Un peu plus loin avec la technique AVAudioPlayer

Je ne sais pas pour vous, mais moi, je trouve l'application précédente un peu « tristounette ». Certes, elle joue le fichier MP3 à la perfection, mais l'écran du device reste désespérément vide. Que diriez-vous d'ajouter un arrière-plan à l'application, un contrôle de progression pour savoir où en est la lecture du fichier et un contrôle de volume pour ajuster le volume sonore comme vous l'entendez ? Tentant non ?
Eh bien, allons-y.

Commencez par dupliquer le dossier de l'application audioPlayer : cliquez sur le dossier audioPlayer, appuyez sur Command + C, puis sur Command + V et renommez-la copie audioPlayer-v2.

Ajout de nouveaux contrôles dans la vue

Cliquez sur MainStoryboard.storyboard dans le volet de navigation, puis insérez trois contrôles Label, un contrôle Slider et un contrôle Progress View dans la vue. Modifiez les dimensions par défaut de ces contrôles, la couleur d'arrière-plan et la couleur du texte des Label et disposez les contrôles dans la vue pour obtenir quelque chose ressemblant à la figure suivante.

Disposez vos contrôles comme ceci

Définissez :

  • l'outlet dureeTotale pour le premier contrôle Label (celui dans lequel est écrit « Label ») ;

  • l'outlet laPosition pour le contrôle Progress View ;

  • l'action leVolume pour le contrôle Slider.

Pour en terminer avec le fichier d'en-têtes, définissez la variable d'instance playbackTimer de type NSTimer. Cette variable sera utilisée pour mettre à jour la position de lecture dans le contrôle Progress View :

NSTimer* playbackTimer;

Si vous avez suivi mes indications, le fichier d'en-têtes devrait ressembler à ceci :

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
@interface ViewController : UIViewController <AVAudioPlayerDelegate>
{
AVAudioPlayer * audioPlayer;
NSTimer* playbackTimer;
}
@property (weak, nonatomic) IBOutlet UILabel *dureeTotale;
@property (weak, nonatomic) IBOutlet UIProgressView *laPosition;
- (IBAction)leVolume:(id)sender;
@end

Vous allez maintenant ajouter quelques lignes de code pour donner vie à ces contrôles.

Mise en place d'un timer

Cliquez sur ViewController.m dans le volet de navigation. Vous allez insérer du code juste au-dessus de l'instruction [audioPlayer play].

Votre première action va consister à mettre en place un « timer », c'est-à-dire un mécanisme qui déclenchera l'exécution d'une méthode à intervalles réguliers. Cette méthode sera utilisée pour mettre à jour le contrôle Progress View pendant la lecture du fichier audio :

playbackTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:@selector(miseAJour:)
userInfo:nil
repeats:YES];

Cette instruction initialise l'objet NSTimer playbackTimer en utilisant la méthode scheduledTimerWithTimeInterval. Cette dernière demande cinq paramètres.

  • La durée entre deux exécutions de la méthode, en secondes. Ici 0,5 seconde, soit deux fois par seconde.

  • L'objet dans lequel se trouve la méthode à exécuter périodiquement. Ici, la valeur self indique que l'objet se trouve dans l'application.

  • Le nom de la méthode à exécuter. Ici, miseAJour.

  • Les informations à passer à la méthode. Ici, la valeur nil indique qu'aucune information n'est passée à la méthode miseAJour.

  • La répétition ou la non-répétition de l'exécution de la méthode. Ici, la valeur YES provoque la répétition de la méthode miseAJour jusqu'à ce que le timer soit désactivé.

Affichage de la durée totale du fichier audio

Vous allez ajouter deux lignes de code dans la méthode viewDidLoad, juste avant le message [super viewDidLoad];.
Pour afficher la durée totale du fichier audio dans le Label, commencez par définir la variable longueur de type float, et stockez-y la durée totale du fichier audio :

float longueur=audioPlayer.duration;

Il ne reste plus qu'à afficher cette valeur dans le contrôle Label dureeTotale :

dureeTotale.text = [NSString stringWithFormat: @"Durée totale : %i secondes",(int)longueur];

Cette instruction peut paraître un peu complexe pour quelque chose d'aussi simple qu'afficher une valeur dans un Label. Sa longueur s'explique par le fait qu'elle ne se contente pas de stocker une variable dans une autre. Rappelez-vous : la durée du fichier audio a été stockée dans un nombre à virgule (float). Dans un premier temps, ce nombre est converti en un entier pour supprimer la virgule ((int)longueur), puis en un NSString ([NSString stringWithFormat:) pour assurer la compatibilité avec la propriété text du Label.

La méthode viewDidLoad doit maintenant ressembler à ceci :

- (void)viewDidLoad
{
AudioSessionInitialize (NULL, NULL, NULL, (__bridge void *)self);
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);
NSData *soundFileData;
soundFileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"morceau.mp3" ofType:NULL]]];
audioPlayer = [[AVAudioPlayer alloc] initWithData:soundFileData error:NULL];
if(!([audioPlayer prepareToPlay]))
NSLog(@"La méthode prepareToPlay a renvoyé la valeur FALSE");
audioPlayer.delegate = self;
[audioPlayer setVolume:1.0f];
playbackTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:@selector(miseAJour:)
userInfo:nil
repeats:YES];
[audioPlayer play];
float longueur=audioPlayer.duration;
dureeTotale.text = [NSString stringWithFormat: @"Durée totale : %i secondes",(int)longueur];
[super viewDidLoad];
}
Animation du Progress View

Vous devez certainement être pressés d'exécuter l'application pour voir le contrôle Progress View se mettre à jour pendant que le morceau est joué. Mais réfléchissez un peu. Ne croyez-vous pas qu'il manque quelque chose pour cela ?

Mais c'est bien sûr : la méthode miseAJour ! Voici le code à ajouter :

-(void)miseAJour:(NSTimer*)timer
{
float total=audioPlayer.duration;
float f=audioPlayer.currentTime / total;
laPosition.progress=f;
}

La propriété progress d'un contrôle Progress View définit la position de la barre de progression. De type float, elle est comprise entre 0.0 (complètement à gauche) et 1.0 (complètement à droite). Pour déplacer la barre en fonction de la position dans le morceau, il suffit de diviser la position actuelle par la durée du morceau et de l'affecter à la propriété progress. C'est précisément ce que fait cette méthode.

Dans un premier temps, la durée totale du morceau est stockée dans la variable float total :

float total=audioPlayer.duration;

Dans un deuxième temps, la position actuelle (audioPlayer.currentTime) est divisée par la durée du morceau (total) et affectée à la variable float f:

float f=audioPlayer.currentTime / total;

Enfin, dans un troisième temps, la variable f est affectée à la propriété progress du contrôle Progress View, ce qui provoque sa mise à jour :

laPosition.progress=f;

Cliquez sur l'icône Run et observez le déplacement de la barre de progression. Impressionnant, non ?

Détection de la fin du son et arrêt du timer

Cette courte récréation terminée, retournons au code.

Quelques lignes plus tôt, nous parlions de la création d'un timer avec la méthode scheduledTimerWithTimeInterval. Comme il a été vu, la méthode miseAJour est exécutée indéfiniment deux fois par seconde. Vous serez d'accord avec moi : cette méthode n'a plus aucune utilité lorsque le morceau a été entièrement joué. C'est pourquoi nous allons y mettre fin à ce moment-là.

Une courte recherche dans la documentation Apple montre que la méthode exécutée lorsque le morceau est entièrement joué, a pour nom audioPlayerDidFinishPlaying.

Une courte recherche dans la documentation Apple ? J'ai recherché et je n'ai rien trouvé ! Puis-je avoir quelques explications ?

Si un événement est généré lorsque le morceau a été entièrement joué, c'est dans le protocole AVAudioPlayerDelegate qu'il faut le rechercher. Vous êtes d'accord avec moi ? Ce delegate est en effet en charge de tous les événements en rapport avec l'objet AVAudioPlayer audioPlayer utilisé dans cette application. Pour trouver la méthode exécutée lorsque le morceau a été entièrement joué, j'ai donc tout naturellement consulté l'aide sur le protocole AVAudioPlayerDelegate. Pour cela, j'ai affiché le fichier d'en-têtes (1), cliqué sur AVAudioPlayerDelegate (2), puis sur AVAudioPlayerDelegate Protocol Reference (3), comme à la figure suivante.

Trouver la méthode audioPlayerDidFinishPlaying

Le clic sur AVAudioPlayerDelegate Protocol Reference provoque l'affichage de la fenêtre d'aide. Quelques secondes suffisent pour comprendre que la méthode recherchée est audioPlayerDidFinishPlaying.

Après cet intermède, définissez la méthode suivante :

-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
[playbackTimer invalidate];
}

Lorsque le fichier audio a été entièrement joué, la méthode invalidate est appliquée à l'objet playbackTime, ce qui provoque la suppression du timer :

[playbackTimer invalidate];
Réglage du niveau sonore avec le Slider

Vous allez maintenant donner vie au contrôle Slider pour que l'utilisateur puisse régler le niveau sonore.

Rappelez-vous : une action de type Value Changed a été définie pour le contrôle Slider. Chaque fois que la position du curseur sera modifiée par l'utilisateur, la méthode action correspondante (c'est-à-dire la méthode leVolume) sera exécutée. Ajoutez les instructions suivantes dans cette méthode :

- (IBAction)leVolume:(id)sender
{
UISlider *slider = (UISlider*) sender;
[audioPlayer setVolume:slider.value];
}

La ligne 3 définit l'objet slider de classe UISlider à partir du contrôle Slider (sender) :

UISlider *slider = (UISlider*) sender;

La ligne 4 applique la méthode setVolume à l'objet audioPlayer en lui transmettant la position du curseur (slider.value) dans le contrôle Slider :

[audioPlayer setVolume:slider.value];

C'est aussi simple que cela. Vous pouvez tester, cela fonctionne parfaitement !

Ajout d'un arrière-plan

Pour terminer en beauté, vous allez ajouter un fond d'écran à l'application. Procurez-vous une image au format JPG ou PNG de 320x480 pixels. Au besoin, redimensionnez une image existante. Une fois en possession de l'image, faites-la glisser depuis le Finder vers le dossier Resources de l'application et confirmez son insertion dans les ressources en cochant la case Copy items into destination group's folder (if needed).

Pour utiliser cette image en arrière-plan de la vue, cliquez sur ViewController.m dans le volet de navigation et ajoutez la ligne suivante au début de la méthode viewDidLoad :

self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"arb.jpg"]];

Comme vous pouvez le voir, la propriété backgroundColor de l'arrière-plan de la vue (self.view) est utilisée pour afficher l'arrière-plan. Cette propriété est initialisée avec une image (initWithPatternImage) nommée « arb.jpg » (imageNamed:@"arb.jpg").

Vous pouvez cliquer sur Run et profiter de votre application. La figure suivante représente mon rendu final.

Mon rendu final

L'application se trouve dans le dossier audioPlayer-v2.

ViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
@interface ViewController : UIViewController <AVAudioPlayerDelegate>
{
AVAudioPlayer * audioPlayer;
NSTimer* playbackTimer;
}
@property (weak, nonatomic) IBOutlet UILabel *dureeTotale;
@property (weak, nonatomic) IBOutlet UIProgressView *laPosition;
- (IBAction)leVolume:(id)sender;
@end
ViewController.m
#import "ViewController.h"
@implementation ViewController
@synthesize dureeTotale;
@synthesize laPosition;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"arb.jpg"]];
AudioSessionInitialize (NULL, NULL, NULL, (__bridge void *)self);
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);
NSData *soundFileData;
soundFileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"morceau.mp3" ofType:NULL]]];
audioPlayer = [[AVAudioPlayer alloc] initWithData:soundFileData error:NULL];
if(!([audioPlayer prepareToPlay]))
NSLog(@"La méthode prepareToPlay a renvoyé la valeur FALSE");
audioPlayer.delegate = self;
[audioPlayer setVolume:1.0];
playbackTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:@selector(miseAJour:)
userInfo:nil
repeats:YES];
[audioPlayer play];
float longueur=audioPlayer.duration;
dureeTotale.text = [NSString stringWithFormat: @"Durée totale : %i secondes",(int)longueur];
[super viewDidLoad];
}
-(void)miseAJour:(NSTimer*)timer
{
float total=audioPlayer.duration;
float f=audioPlayer.currentTime / total;
laPosition.progress=f;
}
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
[playbackTimer invalidate];
}
- (IBAction)leVolume:(id)sender
{
UISlider *slider = (UISlider*) sender;
[audioPlayer setVolume:slider.value];
}
- (void)viewDidUnload
{
[self setDureeTotale:nil];
[self setLaPosition:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
@end

Enregistrement audio

Les iPhone, iPod Touch et iPad disposent d'un microphone. Voyons comment l'utiliser pour créer un dictaphone élémentaire.

Cette application reposera sur l'utilisation du framework AVFoundation, et en particulier de deux de ses classes : AVAudioRecorder (pour l'enregistrement) et AVAudioPlayer (pour la lecture). Les événements relatifs aux objets de ces deux classes seront manipulés dans le code de la vue, par l'intermédiaire des delegate AVAudioRecorderDelegate et AVAudioPlayerDelegate.

Création du projet

Définissez un nouveau projet basé sur le modèle Single View Application et donnez-lui le nom « audioRecorder ». Ajoutez le framework AVFoundation au projet. Vous devriez maintenant savoir le faire, je ne détaillerai donc pas la manipulation.

Définition de l'interface et du fichier d'en-têtes

Cliquez sur MainStoryboard.storyboard dans le volet de navigation et ajoutez trois Round Rect Button au projet en faisant apparaître le texte « REC » (« REC » vient de record, qui veut dire « enregistrer » en français.), « STOP » et « JOUE » sur ces trois boutons.

Contrôle-glissez-déposez tour à tour ces trois contrôles dans le fichier d'en-têtes, juste au-dessus du @end final et définissez (respectivement) les actions enregistre, arrete et joue pour l'événement Touch Up Inside.

L'interface est maintenant terminée. Jusqu'ici, tout va bien !

Cliquez sur ViewController.h dans le volet de navigation.
Comme il a été précisé au début de cette section, cette application va s'appuyer sur les classes AVAudioRecorder et AVAudioPlayer. Les événements générés par ces deux classes seront gérés dans le code de la vue (ViewController.m).

Ajoutez une instruction #import pour faire référence au framework AVFoundation et une référence aux delegate dans la déclaration de l'interface :

#import <AVFoundation/AVFoundation.h>
@interface audioRecorderViewController : UIViewController <AVAudioRecorderDelegate, AVAudioPlayerDelegate>
{
...
}

Pour terminer, définissez les objets audioRecorder de classe AVAudioRecorder et audioPlayer de classe AVAudioPlayer :

AVAudioRecorder *audioRecorder;
AVAudioPlayer *audioPlayer;

Le code du fichier d'en-têtes devrait maintenant ressembler à ceci :

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface ViewController : UIViewController <AVAudioRecorderDelegate, AVAudioPlayerDelegate>
{
AVAudioRecorder *audioRecorder;
AVAudioPlayer *audioPlayer;
}
- (IBAction)enregistre:(id)sender;
- (IBAction)arrete:(id)sender;
- (IBAction)joue:(id)sender;
@end

Initialisation de l'objet audioRecorder

Avant de pouvoir lancer l'enregistrement, il faut initialiser l'objet audioRecorder. Cette opération se fera dès le lancement de l'application, dans la méthode viewDidLoad. Complétez cette méthode comme suit :

- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *chemins;
NSString *cheminDoc;
chemins = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
cheminDoc = [chemins objectAtIndex:0];
NSString *soundFilePath = [cheminDoc stringByAppendingPathComponent:@"monSon.caf"];
NSDictionary *recordSettings = [NSDictionary
dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:AVAudioQualityMin],
AVEncoderAudioQualityKey,
[NSNumber numberWithInt:16],
AVEncoderBitRateKey,
[NSNumber numberWithInt: 2],
AVNumberOfChannelsKey,
[NSNumber numberWithFloat:44100.0],
AVSampleRateKey,
nil];
NSURL *URLson = [NSURL fileURLWithPath:soundFilePath];
NSError *error = nil;
audioRecorder = [[AVAudioRecorder alloc]
initWithURL:URLson
settings:recordSettings
error:&error];
if (error) NSLog(@"Erreur à l'initialisation de l'objet audioRecorder : %@", [error description]);
else [audioRecorder prepareToRecord];
}

Ne soyez pas effrayés ! Nous allons commenter tout ce code qui, comme vous le verrez, n'a rien d'insurmontable.

Pour des raisons de sécurité, seule une très petite partie du système de fichier est accessible en écriture sur un device iOS. Chaque application dispose d'un dossier « Documents » dans laquelle elle peut stocker les fichiers qu'elle manipule. Pour accéder à ce dossier, il faut dans un premier temps connaître son chemin. C'est la raison d'être des instructions des lignes 5 à 9.

On commence par définir l'objet chemins de classe NSArray, puis l'objet cheminDoc de classe NSString :

NSArray *chemins; NSString *cheminDoc;

Pour trouver le chemin du dossier « Documents », il suffit de faire appel à la méthode NSSearchPathForDirectoriesInDomains en lui indiquant que le chemin recherché concerne le dossier « Documents » :

chemins = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

Cette instruction n'a rien de compliqué : elle se contente de reprendre le gabarit indiqué dans l'aide :

NSArray * NSSearchPathForDirectoriesInDomains (
NSSearchPathDirectory directory,
NSSearchPathDomainMask domainMask,
BOOL expandTilde
);

en lui indiquant le dossier recherché (NSDocumentDirectory) et l'emplacement de ce dossier (NSUserDomainMask). La valeur YES pour le paramètre expandTilde indique que les éventuels tildes dans le chemin doivent être transformés en un chemin complet. Une fois de plus, ces informations proviennent de la documentation Apple.

Le NSArray chemins étant initialisé, l'instruction suivante extrait la première information de ce tableau et la stocke dans le NSString cheminDoc. C'est ainsi que cheminDoc contient le chemin complet du dossier « Documents » de l'application :

cheminDoc = [chemins objectAtIndex:0];

Le son enregistré sur le device sera stocké dans le fichier « monSon.caf ».

L'instruction suivante (ligne 9) concatène ce nom avec le chemin du dossier « Documents » et stocke le tout dans la variable NSString soundFilePath :

NSString *soundFilePath = [cheminDoc stringByAppendingPathComponent:@"monSon.caf"];

Arrivés à ce point dans le code, nous avons un objet NSString nommé soundFilePath qui contient le chemin du fichier monSon.caf dans lequel le son sera enregistré.

Dans l'étape suivante (lignes 11 à 21), nous définissons l'objet recordSettings de type NSDictionary qui rassemble tous les paramètres en rapport avec l'enregistrement :

NSDictionary *recordSettings = [NSDictionary
dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:AVAudioQualityMin],
AVEncoderAudioQualityKey,
[NSNumber numberWithInt:16],
AVEncoderBitRateKey,
[NSNumber numberWithInt: 2],
AVNumberOfChannelsKey,
[NSNumber numberWithFloat:44100.0],
AVSampleRateKey,
nil];

Ce dictionnaire est constitué d'un ensemble de paires objet/clé. Sont ainsi définis :

  • la qualité d'enregistrement : AVEncoderAudioQualityKey, qui est ici initialisé à AVAudioQualityMin ;

  • la profondeur d'encodage : AVEncoderAudioQualityKey réglé à 16 bits ;

  • le nombre de canaux d'enregistrement : AVNumberOfChannelsKey pour un enregistrement mono ;

  • la fréquence d'échantillonnage : AVSampleRateKey réglé sur 22050 Hz.

Jusqu'ici, nous avons défini l'adresse du fichier dans lequel le son sera enregistré et les paramètres d'enregistrement. Il ne reste plus qu'à préparer le device à l'enregistrement en initialisant l'objet audioRecorder. Cette opération va se faire avec la méthode initWithURL qui demande trois arguments :

  • l'adresse du son de type NSURL ;

  • le NSDictionary dans lequel se trouvent les paramètres d'enregistrement ;

  • un code d'erreur de type NSError.

Nous avons bien l'adresse du son au format NSString… mais pas au format NSURL. Il est donc nécessaire d'effectuer une conversion. Rien de plus simple, grâce à la méthode fileURLWithPath :

NSURL *URLson = [NSURL fileURLWithPath:soundFilePath];

La variable error, de type NSError, est ensuite définie :

NSError *error = nil;

Nous pouvons (enfin !) initialiser l'objet audioRecorder :

audioRecorder = [[AVAudioRecorder alloc]
initWithURL:URLson
settings:recordSettings
error:&error];

Si cette initialisation produit une erreur, nous l'affichons dans la console :

if (error) NSLog(@"Erreur à l'initialisation de l'objet audioRecorder : %@", [error description]);

Si tout se passe bien lors de l'initialisation, la méthode prepareToRecord est appliquée à l'objet audioRecorder :

else [audioRecorder prepareToRecord];

Cette instruction déclenche la création du fichier monSon.caf et informe iOS que l'application est sur le point de lancer un enregistrement.

Écriture du code pour les Rounded Rect Button

Il ne reste plus qu'à écrire le code attaché aux méthodes action des trois boutons. Rassurez-vous, cette tâche va être élémentaire.

Repérez la méthode enregistre et complétez-la comme suit :

- (IBAction)enregistre:(id)sender
{
[audioRecorder record];
}

Comme vous pouvez le voir, pour commencer l'enregistrement, il suffit d'appliquer la méthode record à l'objet audioRecorder.

Repérez la méthode arrete et complétez-la comme suit :

- (IBAction)arrete:(id)sender
{
[audioRecorder stop];
}

Ici encore, le code utilisé est très simple : pour arrêter l'enregistrement, il suffit d'appliquer la méthode stop à l'objet audioRecorder.

Repérez la méthode joue et complétez-la comme suit :

- (IBAction)joue:(id)sender
{
NSError *error;
audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:audioRecorder.url
error:&error];
audioPlayer.delegate = self;
if (error)
NSLog(@"Error: %@", [error description]);
else
[audioPlayer play];
}

Cette méthode est un peu plus longue, mais elle ne présente aucune difficulté. Après avoir défini la variable error de type NSError :

NSError *error;

l'objet audioPlayer est initialisé avec la méthode initWithContentsOfURL :

audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:audioRecorder.url
error:&error];

L'instruction suivante (ligne 8) indique que les messages en provenance de l'objet audioPlayer seront traités dans la classe ViewController. Cette instruction n'est pas vraiment obligatoire, car nous ne traitons aucuns des messages envoyés par l'objet audioPlayer, mais le code est plus « propre » si elle y est insérée.

Si l'initialisation de l'objet audioPlayer produit une erreur, elle est affichée (dans le simulateur uniquement) :

if (error)
NSLog(@"Error: %@", [error description]);

Dans le cas contraire, le son est joué :

else
[audioPlayer play];
Un arrière-plan pour enjoliver l'application

Maintenant que vous savez à quel point il est simple d'ajouter un arrière-plan à une vue, pourquoi ne pas en profiter pour donner un peu d'allure à cette application.

Procurez-vous une image de 320~x~480 pixels. Si nécessaire, redimensionnez une image existante pour qu'elle ait cette taille. Placez cette image dans les ressources de l'application et ajoutez l'instruction suivante au début de la méthode viewDidLoad (dans cet exemple, l'image a pour nom « fond0.jpg ») :

self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"fond0.jpg"]];

Lancez l'application sur un device (elle ne fonctionne pas dans le simulateur) et amusez-vous à enregistrer tout ce qui vous passe par la tête ! Vous trouverez mon résultat à la figure suivante.

Mon application une fois terminée

L'application se trouve dans le dossier audioRecorder.

ViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface ViewController : UIViewController <AVAudioRecorderDelegate, AVAudioPlayerDelegate>
{
AVAudioRecorder *audioRecorder;
AVAudioPlayer *audioPlayer;
}
- (IBAction)enregistre:(id)sender;
- (IBAction)arrete:(id)sender;
- (IBAction)joue:(id)sender;
@end
ViewController.m
#import "ViewController.h"
@implementation ViewController
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"fond0.jpg"]];
NSArray *chemins;
NSString *cheminDoc;
chemins = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
cheminDoc = [chemins objectAtIndex:0];
NSString *soundFilePath = [cheminDoc stringByAppendingPathComponent:@"monSon.caf"];
NSDictionary *recordSettings = [NSDictionary
dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:AVAudioQualityMin],
AVEncoderAudioQualityKey,
[NSNumber numberWithInt:16],
AVEncoderBitRateKey,
[NSNumber numberWithInt: 2],
AVNumberOfChannelsKey,
[NSNumber numberWithFloat:44100.0],
AVSampleRateKey,
nil];
NSURL *URLson = [NSURL fileURLWithPath:soundFilePath];
NSError *error = nil;
audioRecorder = [[AVAudioRecorder alloc]
initWithURL:URLson
settings:recordSettings
error:&error];
if (error)
NSLog(@"Erreur à l'initialisation de l'objet audioRecorder : %@", [error description]);
else
[audioRecorder prepareToRecord];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)enregistre:(id)sender
{
[audioRecorder record];
}
- (IBAction)arrete:(id)sender
{
[audioRecorder stop];
}
- (IBAction)joue:(id)sender
{
NSError *error;
audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:audioRecorder.url
error:&error];
audioPlayer.delegate = self;
if (error)
NSLog(@"Error: %@", [error description]);
else
[audioPlayer play];
}
@end

En résumé

  • Pour jouer des sons sur un device, vous pouvez passer par les « System Sound Services » du framework AudioToolbox. Cette technique est réservée aux sons courts. Elle est très simple à mettre en œuvre.

  • Pour jouer des sons sur un device, vous pouvez aussi utiliser un AVAudioPlayer. Cette technique peut jouer des sons courts ou longs. Elle repose sur l'utilisation des frameworks AVFoundation et AudioToolbox, mais aussi la mise en place du delegate AVAudioPlayerDelegate, la définition d'un objet AVAudioPlayer, la mise en place de ressources dans l'application pour stocker le fichier audio à jouer et l'utilisation de méthodes sur l'objet AVAudioPlayer pour contrôler le son pendant qu'il est joué.

  • Les iPhone, iPod Touch et iPad disposent d'un microphone. Vous pouvez l'utiliser pour enregistrer des éléments audio. Pour cela, vous devez utiliser la classe AVAudioRecorderDelegate du framework AVFoundation.

Exemple de certificat de réussite
Exemple de certificat de réussite