Suivez-nous sur X
|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : Amiga E - les datatypes
(Article écrit par Pierre Girard et extrait d'Amiga News - septembre 1996)
|
|
La découverte de ce mois-ci concernera les datatypes dont tout le monde a certainement entendu parler. Le but de notre grand
jeu sera de réussir à programmer une application qui se servira des datatypes disponibles dans votre répertoire classes/datatypes/
et devs:datatypes/. Je vous préviens tout de suite qu'il me manquait beaucoup d'informations pour réaliser cet article et
qu'il reflète donc plus mon expérience personnelle que la méthode à utiliser.
Principe
Le principe des datatypes est très intéressant. Il s'agit de petits programmes, que l'on trouve généralement dans le domaine
public, et qui permettent aux logiciels gérant ce système de charger et d'interpréter correctement des fichiers qu'ils ne
géraient pas à l'origine. Un exemple sera plus parlant. Vous récupérez chez un ami des images au format TIFF (beurk !)
que ne gère pas votre afficheur d'images préféré (par exemple VT). Il vous suffit d'installer le datatype TIFF et
de lancer la commande "VT image datatypes". C'est souvent très utile et il existe des datatypes pour gérer les sons, les
images, le texte, les fichiers binaires... Voilà pour la partie utilisateur mais quel est l'intérêt pour le programmeur ?
La programmation...
L'utilité pour le programmeur est que les routines de conversions des sons, des images... ont déjà été réalisées par d'autres.
En gros, il ne lui reste plus qu'à traiter une image, par exemple, comme si elle était au format IFF. Des structures spéciales
sont "remplies" par le datatype concerné avec la résolution, le nombre de couleurs, les différents bitmaps... Cette méthode
épargne un temps précieux au programmeur qui n'a plus à se soucier des 1228 formats d'images existants (les PC peuvent en
prendre de la graine !).
... orientée objet
Le problème (ou l'avantage suivant les personnes) est que l'implémentation de la "datatypes.library" est orientée objet,
utilisant les fonctions BOOPSI d'Intuition. Les différentes classes sont implémentées comme des bibliothèques partagées.
Quel est donc le problème, me direz-vous ? Il est double : tout d'abord, il faut avoir des notions de programmation
orientée objet (les miennes sont faibles). Ensuite, le manque de documentation pour programmer la bibliothèque "datatypes"
est flagrant. Ainsi, il faut passer du temps à éplucher les autodocs et les includes pour déchiffrer les différentes méthodes
et autres structures utilisées.
En pratique
J'ai choisi d'illustrer cet article par un petit programme qui joue vos sons grâce aux datatypes. Après la désormais classique
gestion des arguments, nous créons un nouvel objet "datatype" à l'aide de la fonction NewDTObjectA(nom, attributs) de la
datatype.library. Ici, le type de source est un fichier (Tag DTA_SOURCETYPE), donc le nom est directement le chemin complet
de celui-ci. Le Tag DTA_GROUPID spécifie le type d'objet que nous voulons créer (ici, c'est bien-sûr un son). Les autres tags
sont facultatifs (excepté TAG_DONE) et permettent seulement d'initialiser des valeurs dès la création de l'objet comme ici,
par exemple, le volume et le nombre de fois qu'il faut répéter le son. Ensuite, il faut récupérer les attributs qui nous
intéressent à savoir la structure VOICEHEADER qui est pointée par vhdr et qui contient des valeurs utiles, "l'adresse" de
l'échantillon ainsi que sa longueur.
Reste à jouer le son, ce qui est réalisé par le doMethodA(objet, méthode). La méthode DTM_TRIGGER permet de déclencher un
événement, qui est dans notre cas de jouer le son (STM_PLAY). Si nous quittions tout de suite le programme, le son serait
interrompu tout de suite à cause du DisposeDTObject(). La meilleure solution (la plus précise) consisterait à calculer la
durée du son et à utiliser le timer.device pour une précision à la microseconde près. Nous nous contenterons de faire un
Delay() arrondi à la seconde au-dessus (car la division nous renvoie un entier)) exprimé en "ticks" (impulsions, 50 par seconde).
Petites précisions...
La fonction doMethodA() fait partie de l'amiga.lib (module boopsi.m). Je ne sais pas si ce module existe dans toutes les versions
du E. Si vous ne trouvez pas ce module dans le répertoire habituel, je vous conseille de vous procurer la dernière version de
l'archive (v3.2) ou à défaut d'essayer d'utiliser la fonction DoGadgetMethodA() d'Intuition. Voilà, pour ce mois-ci. Lisez
bien les autodocs et soumettez-moi vos idées !
/* Lire un son via les datatypes */
MODULE 'datatypes','datatypes/datatypes','datatypes/datatypesclass'
MODULE 'datatypes/soundclass'
MODULE 'exec/memory','exec/execbase','utility/tagitem'
MODULE 'amigalib/boopsi'
ENUM ER_OPENLIB,ER_ARGS,ER_OBJET,ER_FILE,ER_MEM
DEF nom[120]:STRING
DEF duree
DEF sample,samplelength
DEF o
DEF rdargs,arguments[5]:ARRAY OF LONG
DEF vhdr:PTR TO voiceheader
PROC main() HANDLE
IF (datatypesbase:=OpenLibrary('datatypes.library',39))=0 THEN
Raise(ER_OPENLIB)
IF rdargs:=ReadArgs('/A',arguments,NIL)=0 THEN Raise(ER_ARGS)
StrCopy(nom,arguments[0],ALL)
FreeArgs(rdargs)
IF (o:=NewDTObjectA(nom,
[DTA_SOURCETYPE,DTST_FILE,
DTA_GROUPID,GID_SOUND,
SDTA_VOLUME,64,
SDTA_CYCLES,1,
TAG_DONE]))=0 THEN Raise(ER_OBJET)
GetDTAttrsA(o,
[SDTA_VOICEHEADER,{vhdr},
SDTA_SAMPLE,{sample},
SDTA_SAMPLELENGTH,{samplelength},
TAG_DONE])
/* On joue le son */
doMethodA(o,[DTM_TRIGGER,NIL,STM_PLAY,NIL])
duree:=(((samplelength/vhdr.samplespersec)*50)+50)
Delay(duree)
/* On libère l'objet et la "datatypes.library" */
DisposeDTObject(o)
CloseLibrary(datatypesbase)
EXCEPT
IF o THEN DisposeDTObject(o)
IF datatypesbase THEN CloseLibrary(datatypesbase)
SELECT exception
CASE ER_OPENLIB
WriteF('can''t open librarien')
CASE ER_ARGS
WriteF('Bad argsn')
CASE ER_OBJET
WriteF('sn',nom)
PrintFault(IoErr(),'')
CASE ER_FILE
WriteF('Can''t open file sn',nom)
CASE ER_MEM
WriteF('Can''t allocate memory')
ENDSELECT
ENDPROC
|
|