Compact Disc Audio track
.cda est une extension de nom de fichier désignant un petit fichier conforme à la spécification RIFF Le format de fichier CDA est un format Microsoft, .
Les fichiers CDA (Compact Disc Audio) sont générés par Windows lorsque ce système d'exploitation accède à un CD Audio. Chaque titre du CD Audio est alors vu comme un fichier de 44 octets, et d'extension ".cda". Les fichiers sont nommés "Track01.cda", "Track02.cda", etc.
Le fichier .cda copié sur l'ordinateur est inutile sans le CD, puisqu'il ne s'agit que d'un raccourci vers le CD. Les fichiers .cda ne contiennent pas les données sonores, mais indiquent où commence et s'arrête chaque piste sur le disque. Si le fichier est "copié" du CD vers un ordinateur, il ne peut pas être utilisé seul car il ne s'agit que d'un raccourci vers une partie du disque. Toutefois, certains programmes d'édition audio et de création de CD chargeront, du point de vue de l'utilisateur, les fichiers .cda comme s'il s'agissait de véritables fichiers de données audio, et permettront à l'utilisateur de les écouter.
Organisation d'un fichier CDA
offset | longueur | contenu |
---|---|---|
0x00 | 4 | les 4 caractères ASCII "RIFF" |
0x04 | 4 | la taille du chunk suivant : toujours 36 (44 - 8), sur 4 octets (ordre Intel) |
0x08 | 4 | identifiant du chunk : les 4 caractères ASCII "CDDA" |
0x0C | 4 | les 3 caractères ASCII "fmt" suivi d'un espace |
0x10 | 4 | longueur du chunk : toujours 24, sur 4 octets (ordre Intel) |
0x14 | 2 | version du format CD, sur 2 octets (ordre Intel). En , vaut toujours 1. |
0x016 | 2 | numéro de la plage, sur 2 octets (ordre Intel). La première plage a le numéro 1. |
0x18 | 4 | identifiant calculé par Windows pour cdplayer.exe. |
0x1c | 4 | offset de la plage, en nombre de frames (ordre Intel) |
0x20 | 4 | durée de la plage, en nombre de frames (ordre Intel) |
0x24 | 1 | position de la plage : frames |
0x25 | 1 | position de la plage : secondes |
0x26 | 1 | position de la plage : minutes |
0x27 | 1 | un octet nul (valeur binaire 0) |
0x28 | 1 | durée de la plage : frames |
0x29 | 1 | durée de la plage : secondes |
0x2a | 1 | durée de la plage : minutes |
0x2b | 1 | un octet nul (valeur binaire 0) |
La taille d'un fichier CDA étant fixe, ainsi que son organisation, il n'y a toujours qu'un seul et unique chunk, nommé "CDDA" (signifiant Compact Disc for Digital Audio).
L'identifiant créé par Windows est utilisé par le lecteur de CD de Windows 95 et Windows 98 (cdplayer.exe). Ce lecteur ne sait pas se connecter à FreeDB ou CDDB. Pour qu'il puisse afficher le nom de l'artiste et le titre des morceaux, il faut entrer manuellement ces informations dans le fichier cdplayer.ini (dans le répertoire d'installation de Windows), dans une section nommée d'après cet identifiant. Cet identifiant n'a aucun rapport avec le DiscId utilisé par FreeDB ou CDDB, c'est une création purement Microsoft, pour l'usage précité.
La position et la longueur des plages utilisent des frames comme unité. Il y a 75 frames par seconde. C'est le plus petit bloc de données qui peut être lu depuis un CD audio, correspondant à un secteur du CD.
Toutes les informations qui nécessitent plusieurs octets sont codées avec l'order-byte Intel (petit boutiste).
Exemple d'analyse d'un fichier CDA, en Perl
Le programme de démonstration fourni est un script Perl. Il faut lancer le script avec un paramètre : le chemin vers le répertoire ou le disque contenant les fichiers CDA.
#! /bin/perl -w use strict; my $path_cda; # chemin vers les CDA (paramètre du script) my $data_cda; # contenu d'un fichier CDA my @liste_cda; # la liste des fichiers CDA du répertoire my $fic_cda; # le nom du fichier CDA courant my $mins; my $secs; my $frames; # tester qu'un argument a été fourni $path_cda = shift; die("argument: le nom du répertoire") if (!defined($path_cda)); # ouvrir, lire, puis refermer le fichier CDA opendir(DIR_CDA, $path_cda) or die ("impossible d'ouvrir le répertoire $path_cda"); @liste_cda = grep /.*cda$/i, readdir(DIR_CDA); closedir(DIR_CDA); print "plage début durée début durée\n"; print " frames frames min:sec:frm min:sec:frm\n"; foreach $fic_cda (@liste_cda) { # charger le contenu du fichier CDA dans une variable open(CDA, "<:raw", $path_cda.$fic_cda) or die("impossible d'ouvrir le fichier $fic_cda"); $data_cda = <CDA>; close(CDA); # vérifier la taille du fichier, et le header die "taille invalide" if (length($data_cda) != 44); die "entête invalide" if (substr($data_cda, 0, 0x0f) ne "RIFF\$\x00\x00\x00CDDAfmt"); # afficher le numéro de la plage printf sprintf("%02d ", ord(substr($data_cda, 0x16, 1))); # afficher les informations sur la plage : position en frames $frames = unpack("V", substr($data_cda, 0x1c, 4)); printf sprintf("%06d ", $frames); # afficher les informations sur la plage : durée en frames $frames = unpack("V", substr($data_cda, 0x20, 4)); printf sprintf("%06d ", $frames); # afficher les informations sur la plage : position min:sec:frames ($frames, $secs, $mins) = unpack("CCC", substr($data_cda, 0x24, 3)); printf sprintf("%02d:%02d:%02d = %06d frm ", $mins, $secs, $frames, ((($mins * 60) + $secs) * 75) + $frames); # afficher les informations sur la plage : durée min:sec:frames ($frames, $secs, $mins) = unpack("CCC", substr($data_cda, 0x28, 3)); printf sprintf("%02d:%02d:%02d = %06d frm", $mins, $secs, $frames, ((($mins * 60) + $secs) * 75) + $frames); print "\n"; }
Dans les colonnes affichant la position et la durée au format minutes:secondes:frames, le script ajoute le nombre de frames équivalent à cette durée. La position dans les deux systèmes devrait être identique. Dans la pratique on observe pourtant une différence de 150 frames, correspondant aux 2 secondes de prégap (voir le Red Book).
Résultats du script
Le script ci-dessus a été lancé sur l'album « Some Great Reward » du groupe Depeche Mode. Les résultats sont recopiés ci-dessous, une colonne « durée pochette » contenant la durée indiquée sur la pochette a été ajoutée.
plage début durée début durée durée pochette frames frames min:sec:frm min:sec:frm 01 000032 017015 00:02:32 = 000182 frm 03:46:65 = 017015 frm 3:46 02 017047 022780 03:49:22 = 017197 frm 05:03:55 = 022780 frm 5:03 03 039827 017398 08:53:02 = 039977 frm 03:51:73 = 017398 frm 3:51 04 057225 021387 12:45:00 = 057375 frm 04:45:12 = 021387 frm 4:45 05 078612 014570 17:30:12 = 078762 frm 03:14:20 = 014570 frm 3:14 06 093182 020045 20:44:32 = 093332 frm 04:27:20 = 020045 frm 4:27 07 113227 018970 25:11:52 = 113377 frm 04:12:70 = 018970 frm 4:12 08 132197 021068 29:24:47 = 132347 frm 04:40:68 = 021068 frm 4:40 09 153265 028952 34:05:40 = 153415 frm 06:26:02 = 028952 frm 6:26
On retrouve la différence de deux secondes entre les deux champs « position ».
La durée affichée par une platine CD ou par les logiciels de lecture peut être :
- la durée indiquée dans le fichier CDA, le nombre de frames ayant été ignoré
- la durée indiquée dans le fichier CDA, avec arrondi à la seconde la plus proche.