conversion 16
bits mono en stéréo
Les données du sample
16 bits mono ne possèdent que 2 octets. Le sample stéréo,
4 octets: 2 octets pour la voie de gauche, et 2 octets pour la voie
de droite. Pour convertir le mono en stéréo, il suffit
d'ajouter 2 octets de plus, et de modifier l'en-tête du fichier
pour le nouveau format. Autrement dit, nous pouvons copier tout
simplement la piste mono existante (gauche) sur une nouvelle piste
(droite). Ainsi, nous obtiendrons un sample stéréo,
mais mono à l'écoute... Il est aussi possible (et
facile), d'ajouter des effets à la 2ème piste, pour
différencier les deux voies! Ces effets sont obtenues par
différentes méthodes de calcul (transformation des
données). Cependant, nous n'en verrons ici, pour l'instant!
Donc, pour cette conversion du mono
vers stéréo, aucun calcul compliqué
ne sera vraiment nécessaire. J'en profiterai donc pour m'attarder
davantage sur l'explication de la gestion de la copie des données...
|
Réalisation
du programme:
Ce qui est important à mon avis, ce sont les vérifications
et la gestion des erreurs pour la copie du fichier! Pour commencer,
je vérifie que l'ouverture du fichier source est bien possible
avec la fonction FileExists. Cette fonction me dit si
ce fichier est bien présent sur le disque ou non. Puis, j'ouvre
ce fichier source, et je copie l'en-tête du fichier (44 octets)
dans le buffer nommé BufS.
Ce buffer servira à obtenir et vérifier le format
du sample (par la suite). Pour le moment, je vérifie la taille,
et d'éventuelles erreurs d'accès, grâce à
IOResult et à la directive
de compilation {$I+}. Le fichier est refermé
avant l'affichage des éventuelles erreurs. Nous le réouvrirons
après si aucune erreur n'est décelée.
IF NOT(FileExists(Source))THEN
BEGIN ShowMessage('Impossible d''ouvrir '+Source);EXIT;END;
{$I-} AssignFile(Fsour,Source);
Filemode:=2;
Reset(Fsour,1);
Size:=FileSize(Fsour);
BlockRead(Fsour,BufS,44,res);
CloseFile(Fsour);
{$I+} IF(IOResult<>0)OR(Size<116)THEN {$I-}
BEGIN ShowMessage('Impossible d''ouvrir '+Source);EXIT;END;
Je vais maintenant
vérifier la validité de son format, en contrôlant
quelques octets de son en-tête, en particulier le format (16
bits), le mode (mono), et la fréquence. La fonction CreateHeader permet un test supplémentaire
(à peu près identique). Cette fonction renvoie FALSE
si la création d'une en-tête avec ses paramètres
poserait un problème. Cela permet aussi de s'assurer que
la copie de l'en-tête s'est bien déroulée:
Freq:=(bufS[27]*$1000000)+(bufS[26]*$10000)+(bufS[25]*$100)+bufS[24];
IF(BufS[22]<>1)OR(BufS[34]<>16)OR
(NOT CreateHeader(Size,BufS[22],bufS[34],Freq))THEN
BEGIN
ShowMessage('Format de '+source+' invalide');EXIT;END;
Une fonction
spéciale est mise en place pour permettre de connaître
la taille disponible sur le lecteur. Si l'espace libre est insuffisant
pour copier le nouveau fichier destination, un message d'erreur
est affiché, et la processus s'interrompt. La détection
d'espace libre est faite avec la fonction GetDiskFreeSpaceEx de Delphi. Il existe un équivalent
pour les autres compilateurs... Etant donné que cette fonction
a besoin de plusieurs variable pour fonctionner, j'ai simplifier
en regroupant tout dans une fonction appellée GetDiskSize:
FUNCTION getdisksize(lecteur:string):int64;
VAR Drive:array[0..255]of char; TailleDisque:int64;
BEGIN TRY
TailleDisque:=0; strPCopy(Drive,lecteur);
GetDiskFreeSpaceEx(Drive,Result,TailleDisque,nil);
EXCEPT Result:=0;END; END;
Je m'en sert comme ceci:
IF(getdisksize( copy(ExpandFilename(dest),1,3))<Size2)THEN
BEGIN
ShowMessage('Espace insuffisant pour
la copie');EXIT;END;
Un dernier test
est nécessaire, celui de la création du fichier de
destination. Pendant ce test, je profite que le fichier est ouvert
pour créer et copier la nouvelle en-tête (16 bits stéréo),
à condition de connaître à l'avance la taille
finale qu'aura le fichier (Size2). Dans le cas actuel (mono vers
stéréo), il suffit de multiplier par deux la taille
du fichier source, et d'ajouter la taille de l'en-tête (44
octets):
{$I-} AssignFile(Fdest,Dest);
Filemode:=2;
Rewrite(Fdest,1);
CreateHeader(Size2,2,16,Freq);
BlockWrite(Fdest,Header,44,res2);
CloseFile(Fdest);
{$I+} IF(IOResult<>0)THEN {$I-}
BEGIN ShowMessage('Impossible de créer '+dest);EXIT;END;
Une
fois tous ces tests réalisés avec succès, il
est possible de traîter le sample... En résumé:
Test si le fichier source existe
Test d'ouverture du fichier source
Lecture et test du format du sample source
Test de l'espace libre pour la copie
Test de création du fichier destination
SOURCE DU PROGRAMME
|