Guide de programmation pour PolySnd v2.0  
Guide de programmation pour PolySnd v2.0

  -- Le site --
· News
· Moi
· Liens
·
 Forum
· Me Contacter

  -- Mes projets sur TI --
· Blib
· Librairie PolySnd
· PolySnd Player
· PolySnd MIDI Converter
· PolySnd Converti
· Arkanoid
· Windows ST

 

  -- Rubriques --
· PolySnd v1.0
· PolySnd v1.2
· PolySnd v1.3
· PolySnd v2.0
· Guide de programmation

 

   

Guide de programmation pour PolySnd 2.0 en ASM et en C.

 

Objectifs:

  Ce guide vous permettra de débuter dans la programmation audio avec PolySnd version 2.0 dans vos programmes en assembleur ou en C avec TIGCC. Ce guide propose des exemples de codes et des conseils sur l'utilisation des fonctions de PolySnd v2.0. En tout cas ce guide admet que vous avez quelques connaissances en ASM ou en C et que par conséquent vous êtes capable de suivre les diverses étapes. Seulement l'exemple n°1 sera en ASM et en C mais les exemples suivant ne seront qu'en C.

  Ce guide vous donnera tout au long des astuces qui on était employé pour PolySnd Player dont les sources sont disponible.

  Dans nos exemples en C nous utiliserons la version statique de PolySnd mais il est tout à fait possible d'utiliser la version dynamique qui nécessite toute fois sur votre TI un Kernel et la librairie polysnd2.**z.

 

Installation et préparation de l'environnement de programmation:

  Que vous programmez en C ou en ASM vous devez disposer d'un compilateur, TIGCC permet d'écrire et compiler des programmes écrit en C ou en ASM et ce dans un environnement assez sympathique, vous devez donc vous procurer la dernière version de TIGCC.

  PolySnd version 2.0 nécessite la version 0.95 de TIGCC ou supérieur.

Voir le site officiel de TIGCC.

Télécharger la dernière version de TIGCC.

 

Un premier programme:

  Nous allons réaliser notre premier programme audio, le but de ce programme et de jouer une fréquence précise pendant une certaine durée, nous allons donc aborder les bases pour programmer correctement avec PolySnd v2.0. Au départ nous devons choisir le langage dans le quel nous voulons créer notre programme sous TIGCC, pour cela si vous coder en Assembleur il vous suffit de cliquer sur 'File/New/Project'

Vous devez donc obtenir un projet vierge sans fichier ni code.

  Si vous désirer apprendre à utiliser PolySnd v2.0 en programmant en C, vous devez créer une nouvelle feuille de code en cliquant sur le menu 'File/New/C Source File'

  Si vous désirer apprendre à utiliser PolySnd v2.0 en programmant en ASM, vous devez créer une nouvelle feuille de code en cliquant sur le menu 'File/New/A68K Assembly Source File'

  Maintenant nous devons inclure au projet la librairie PolySnd v2.0, dans le cas de l'ASM nous nous contenterons d'inclure seulement le header (bibliothèque de fonctions) qui ce trouve dans le répertoire 'header/Dynamique/ASM/polysnd2.h' de PolySnd, quand au projet en C nous devons inclure le bon header et la librairie (portant l'extension a), pour cela vous devez inclure l'header ce trouvant dans le répertoire 'header/Statique/C/polysnd2.h' et la librairie qui ce trouve dans le dossier 'bin/polysnd2.a'.

 Pour ajouter un fichier à votre projet vous devez cliquer sur le menu 'Project/Add Files...' dans l'environnement de TIGCC.

  Une fois cette étape réalisé vous devez posséder une liste de 2 fichier pour le projet en ASM et 3 fichiers pour le projet en C.

 

Nouveau projet utilisant PolySnd v2.0 en Assembleur:

 

Nouveau projet utilisant PolySnd v2.0 en C:

  Il vous reste à enregistrer le projet et à renommer le fichier principal (New File). Ceci est la base de tout programme en C ou en ASM sur TIGCC, de plus nous avons inclut la librairie audio PolySnd v2.0, beaucoup d'autres librairies procéde de cette façon comme ExtGraph, GraphX ou encore XLib mais fonctionnant qu'avec un certain type de formats et de programmation qui sont expliquer dans la documentation, sachez que pour PolySnd v2.0 il est possible de programmer en Nostub et en Kernel, de plus dans le langage de programmation de son choix (en ASM ou en C).

  Dans la convention de ce guide nous utiliserons le format Kernel pour la programmation en ASM qui nécessitera sur votre calculatrice une version de Preos (0.67 ou supérieur) et polysnd2.**z (suivant votre modèle de TI). Quand à la programmation en C nous utiliserons le format Nostub et donc la possibilité d'avoir directement la librairie dans son programme, par conséquent votre programme fonctionnera sans Preos et sans la librairie polysnd2.**z sur votre calculatrice.

 

Réalisation du programme:

  Attaquons-nous maintenant à la réalisation de notre programme qui aura pour but de jouer un LA à une fréquence de 440 Hz de durée 3 secondes avec un tempo de 120 bpm.

  Comment allons nous faire? C'est simple, il suffira tout d'abord d'appliquer par défaut un code nécessaire pour le bon fonctionnement de PolySnd v2.0 (ce code n'est pas obligatoire, il s'occupe de désactiver les auto int n°1 et n°2, voir la documentation de PolySnd pour plus d'informations sur ce sujet). Ensuite nous allons initialiser la librairie PolySnd avec les fonctions EnableSound et InstallSound et nous allons ensuite réaliser le code permettant de créer une fréquence de 440 Hz.

Code en ASM:

; Assembly Source File
; Created 09/10/2003, 22:16:51
           include      "doorsos.h"                                                                       ;Bibliothèque Kernel avec ROM_CALLS
           include      "polysnd2.h"                                                                      ;Librairie PolySnd v2.0
                               
           xdef         _ti89                                                                                  ;Compile pour TI89
           xdef         _ti92plus                                                                            ;Compile pour TI92+
           xdef         _main                                                                                ;Entrée du programme
           xdef         _comment                                                                         ;Commentaire du programme
                               
_main: 
          move.w      #$0700,d0                                                                        ;Désactive toutes les interruptions
          trap            #1 
          move.l        $64,int1                                                                            ;Sauvegarde l'adresse de l'auto-int n°1
          move.l        $68,int2                                                                            ;Sauvegarde l'adresse de l'auto-int n°2
          move.l        #empty_handler,$40064                                                    ;Inhibe auto int n°1
          move.l        #empty_handler2,$40068                                                   ;Inhibe auto int n°2
          moveq.w     #0,d0 
          trap            #1                                                                                    ;Active toutes les interruptions
                               
          bsr             GetCalculator                                                                    ;Renvoie le model de TI dans calc
                               
          jsr              polysnd2::EnableSound                                                       ;Active le port I/O en mode son
          jsr              polysnd2::InstallSound                                                        ;Installe PolySnd
                               
           ;Votre code
;-----------------------------------------------------
;Fonction qui attend l'appuye d'une touche 
;-----------------------------------------------------
loop_key:                                                                                                      ;Boucle clavier
          cmp.b        #0,calc                                                                               ;Si TI89
          beq            key_89                                                                              ;key_89
          bne            key_92                                                                              ;key_92 focntionne aussi sur V200
key_89: 
          move.w      #6,d0                                                                                 ;Repére ESC
          bsr             masque
          btst.b          #0,d0
          beq            fin                                                                                      ;Si pressé fin
          bne            loop_key                                                                             ;Sinon loop
key_92: 
          move.w      #8,d0                                                                                  ;Repéré ESC
          bsr             masque 
          btst.b          #6,d0
          beq             fin                                                                                      ;Si pressé fin
          bra             loop_key                                                                             ;sinon loop
                               
fin: 
          jsr              polysnd2::UninstallSound                                                      ;Désinstalle PolySnd
          jsr              polysnd2::DisableSound                                                        ;Remet le port I/O à  son état par défaut.
                               
          move.w      #$0700,d0                                                                           ;Désactive interruptions
          trap            #1
          move.l        int1(PC),$40064                                                                  ;Remet à son état courant l'auto int 1
          move.l        int2(PC),$40068                                                                  ;Remet à son état courant l'auto int 2
          moveq        #0,d0 
          trap            #1                                                                                      ;Active interruptions
          rts 
;Interruption vide, l'auto int n°1 ne sera pas executé
empty_handler:
          rte
;Désactive l'auto int n°2 
empty_handler2:
          sf.b              $60001b                                                                           ;Permet d'inhiber l'interruption clavier du TIOS
          rte 
                               
 ;----------------------------------
;Detection de la calculatrice
;----------------------------------
 GetCalculator:
         move.l          a1,-(a7)                                                                           ;Sauvegarde a1
         move.l          $C8,a0                                                                             ;Addresse pour vérifier si TI-89 ou TI-92 Plus
         move.b         #1,calc                                                                             ;Prédéfinis comme TI-92 Plus
         move.l          a0,d1                                                                                ;Prépare d1
         and.l             #$400000,d1                                                                     ;Si ~0 alors TI-92 Plus sinon TI-89 ou V200
         bne              __calculator                                                                     ;Dans cas TI-92 Plus alors Fin
         move.b         #0,calc                                                                              ;Prédéfinis comme TI-89
         move.l          $2F*4(a0),a1                                                                    ;Prépare condition
         cmp.b           #200,2(a1)                                                                        ;Si 200 alors TI-89
         bcs               __calculator                                                                     ;Donc Fin
         move.b         #2,calc                                                                             ;Donc V200
__calculator:
         move.l          (a7)+,a1                                                                           ;Restaure a1
         rts
                               
                               
 ;----------------------------------------------------------------------
 ;Masque pour la lecture du clavier 
 ;********************************************
 ;********************************************
 ;masque une ligne du clavier
 ;----------------------------------------------------------------------
 ;d0=ligne -> d0=réponse
;;********************************************
 masque:
       move.l           d1,-(a7)
       move.w         #$FFFE,d1
       rol.w             d0,d1
       clr.w             d0
       move.w         d1,($600018)
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       move.b         ($60001B),d0
       move.l          (a7)+,d1
       rts
;------------
;Variables
;------------
int1  dc.l  0                          ;Ancienne auto int n°1
int2  dc.l  0                          ;Ancienne auto int n°2
calc dc.b 0                          ;Modèle de la calculatrice
;Commentaire du programme
_comment   dc.b "Example 1",0
       end

  Voici le code de base d'un programme en ASM utilisant PolySnd, avant de d'installer PolySnd nous désactivons les interruptions inutile pour permettre d'utiliser au maximum les ressources du processeur, nous récupérons le modèle de la calculatrice dans la variable calc, ensuite nous appelons PolySnd qui s'occupe d'installer l'interruption audio. La fonction suivante s'occupe seulement de faire une boucle jusqu'à ce que la touche ESC soit pressé et ce sur n'importe quel modèle de calculatrice.

  Nous allons donc ajouter le code nécessaire pour créer du son et donc jouer notre fréquence de 440 Hz, si vous essayez tel quel ce programme vous n'obtiendrez pas grand chose, pour l'instant nous attendons l'appui sur la touche ESC pour quitter.

Voici le programme final avec le code ajouté:

; Assembly Source File
; Created 09/10/2003, 22:16:51
           include      "doorsos.h"                                                                       ;Bibliothèque Kernel avec ROM_CALLS
           include      "polysnd2.h"                                                                      ;Librairie PolySnd v2.0
                               
           xdef         _ti89                                                                                  ;Compile pour TI89
           xdef         _ti92plus                                                                            ;Compile pour TI92+
           xdef         _main                                                                                ;Entrée du programme
           xdef         _comment                                                                         ;Commentaire du programme
                               
_main: 
          move.w      #$0700,d0                                                                        ;Désactive toutes les interruptions
          trap            #1 
          move.l        $64,int1                                                                            ;Sauvegarde l'adresse de l'auto-int n°1
          move.l        $68,int2                                                                            ;Sauvegarde l'adresse de l'auto-int n°2
          move.l        #empty_handler,$40064                                                    ;Inhibe auto int n°1
          move.l        #empty_handler2,$40068                                                   ;inhibe auto int n°2
          moveq.w     #0,d0 
          trap            #1                                                                                    ;Active toutes les interruptions
                               
          bsr             GetCalculator                                                                    ;Renvoie le modèle de TI dans calc
                               
          jsr              polysnd2::EnableSound                                                       ;Active le port I/O en mode son
          jsr              polysnd2::InstallSound                                                        ;Installe PolySnd
 
;Nouveau code 
;-----------------------------------------------------        
          move.w      #120,d0                                                                            ;Prépare le tempo à 120 bpm sur le canal 1
          jsr              polysnd2::SetTempo_voice1                                               

          move.b       #_MONO,d0                                                                    ;Régle PolySnd en mode MONO, seul le canal 1 sera utilisé
          jsr              polysnd2::PlayMode

          move.w      #440,d0                                                                             ;Régle la fréquence à 440 Hz
          move.b       #192,d0                                                                             ;De durée 3*(32*2) cycles (1 temp = 32cycles) donc 3s
          jsr              polysnd2::SetBeep_voice1                                                  ;Paramètres pour SetBeep_voice1

          move.b      #_VOICE1,d0                                                                    ;Active que le canal 1 (le son est en mono)
          jsr             polysnd2::SetState
;-----------------------------------------------------
;Fonction qui attend l'appuye d'une touche 
;-----------------------------------------------------
loop_key:                                                                                                      ;Boucle clavier
          jsr             polysnd2::GetState                                                              ;Récupére l'état des canals
          cmp.b       #_VOICE1,d0                                                                    ;Compare VOICE1 avec d0
          bne           fin                                                                                      ;VOICE1 terminée alors fin
 ;-----------------------------------------------------
         
          cmp.b        #0,calc                                                                               ;Si TI89
          beq            key_89                                                                              ;key_89
          bne            key_92                                                                              ;key_92 focntionne aussi sur V200
key_89: 
          move.w      #6,d0                                                                                 ;Repére ESC
          bsr             masque
          btst.b          #0,d0
          beq            fin                                                                                      ;Si pressé fin
          bne            loop_key                                                                             ;Sinon loop
key_92: 
          move.w      #8,d0                                                                                  ;Repéré ESC
          bsr             masque 
          btst.b          #6,d0
          beq             fin                                                                                      ;Si pressé fin
          bra             loop_key                                                                             ;sinon loop
                               
fin: 
          jsr              polysnd2::UninstallSound                                                      ;Désinstalle PolySnd
          jsr              polysnd2::DisableSound                                                        ;Remet le port I/O à  son état par défaut.
                               
          move.w      #$0700,d0                                                                           ;Désactive interruptions
          trap            #1
          move.l        int1(PC),$40064                                                                  ;Remet à son état courant l'auto int 1
          move.l        int2(PC),$40068                                                                  ;Remet à son état courant l'auto int 2
          moveq        #0,d0 
          trap            #1                                                                                      ;Active interruptions
          rts 
;Interruption vide, l'auto int n°1 ne sera pas executé
empty_handler:
          rte
;Désactive l'auto int n°2 
empty_handler2:
          sf.b              $60001b                                                                           ;Permet d'inhiber l'interruption clavier du TIOS
          rte 
                               
 ;----------------------------------
;Detection de la calculatrice
;----------------------------------
 GetCalculator:
         move.l          a1,-(a7)                                                                           ;Sauvegarde a1
         move.l          $C8,a0                                                                             ;Addresse pour vérifier si TI-89 ou TI-92 Plus
         move.b         #1,calc                                                                             ;Prédéfinis comme TI-92 Plus
         move.l          a0,d1                                                                                ;Prépare d1
         and.l             #$400000,d1                                                                     ;Si ~0 alors TI-92 Plus sinon TI-89 ou V200
         bne              __calculator                                                                     ;Dans cas TI-92 Plus alors Fin
         move.b         #0,calc                                                                              ;Prédéfinis comme TI-89
         move.l          $2F*4(a0),a1                                                                    ;Prépare condition
         cmp.b           #200,2(a1)                                                                        ;Si 200 alors TI-89
         bcs               __calculator                                                                     ;Donc Fin
         move.b         #2,calc                                                                             ;Donc V200
__calculator:
         move.l          (a7)+,a1                                                                           ;Restaure a1
         rts
                               
                               
 ;----------------------------------------------------------------------
 ;Masque pour la lecture du clavier 
 ;********************************************
 ;********************************************
 ;masque une ligne du clavier
 ;----------------------------------------------------------------------
 ;d0=ligne -> d0=réponse
;;********************************************
 masque:
       move.l           d1,-(a7)
       move.w         #$FFFE,d1
       rol.w             d0,d1
       clr.w             d0
       move.w         d1,($600018)
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       nop
       move.b         ($60001B),d0
       move.l          (a7)+,d1
       rts
;------------
;Variables
;------------
int1  dc.l  0                          ;Ancienne auto int n°1
int2  dc.l  0                          ;Ancienne auto int n°2
calc dc.b 0                          ;Modèle de la calculatrice
;Commentaire du programme
_comment   dc.b "Example 1",0
       end

 

  Ce guide ne comportera que cette exemple de programme utilisant PolySnd v2.0 en ASM.

  Il ne vous reste plus qu'à essayer ce programme sur votre calculatrice, si celui-ci ne ce compile pas ou ne s'exécute pas correctement, veuillez vérifier que vous avez tout tapé correctement.

Télécharger example1.zip en ASM

 

Code en C:

  Nous allons maintenant écrire le même programme mais en C. Voyons voir à quoi ressemble le code de base.

// C Source File
// Created 11/10/2003; 17:13:50

#include <tigcclib.h>
#include "polysnd2.h"

INT_HANDLER OldInt1 = NULL;
INT_HANDLER OldInt2 = NULL;

DEFINE_INT_HANDLER (myint2)
{
   pokeIO (0x60001B,0);
}

//Programme principal
void _main(void)
{
   OldInt1 = GetIntVec (AUTO_INT_1);
   OldInt2 = GetIntVec (AUTO_INT_2);
   SetIntVec (AUTO_INT_1, DUMMY_HANDLER);
   SetIntVec (AUTO_INT_2, myint2);

   pSnd_EnableSound ();
   pSnd_InstallSound ();

   while(_keytest (RR_ESC)==FALSE);

   pSnd_UninstallSound ();
   pSnd_DisableSound ();

   SetIntVec (AUTO_INT_1, OldInt1);
   SetIntVec (AUTO_INT_2, OldInt2);
}

 

  Ceci est la base d'un programme en C utilisant PolySnd v2.0, ce programme ne fait pas grand chose, il attend juste l'appui de la touche ESC. Voyons voir ce que donne le code en C pour jouer une fréquence de 440 Hz pendant 3 secondes, qui peut être à tout moment interrompus.

Voici le programme final avec le code ajouté:

// C Source File
// Created 11/10/2003; 17:13:50

#include <tigcclib.h>
#include "polysnd2.h"

INT_HANDLER OldInt1 = NULL;
INT_HANDLER OldInt2 = NULL;

DEFINE_INT_HANDLER (myint2)
{
   pokeIO (0x60001B,0);
}

//Programme principal
void _main(void)
{
   OldInt1 = GetIntVec (AUTO_INT_1);
   OldInt2 = GetIntVec (AUTO_INT_2);
   SetIntVec (AUTO_INT_1, DUMMY_HANDLER);
   SetIntVec (AUTO_INT_2, myint2);

   pSnd_EnableSound ();
   pSnd_InstallSound ();

   pSnd_SetTempo_voice1 (120);
   pSnd_PlayMode (MONO);

   pSnd_SetBeep_voice1 (440,192);
   pSnd_SetState (VOICE1);

   while ((_keytest (RR_ESC)==FALSE) && (pSnd_GetState()==VOICE1));

   pSnd_UninstallSound ();
   pSnd_DisableSound ();

   SetIntVec (AUTO_INT_1, OldInt1);
   SetIntVec (AUTO_INT_2, OldInt2);
}

  Voilà donc le programme finit, comme vous le remarquez nous avons tout d'abord réglé le tempo à 120 bpm sur le canal n°1, puis ensuite nous avons configuré la librairie en mono. Nous avons réglé la fonction SetBeep sur le canal n°1 et ensuite avec SetState nous permettons de jouer ce mode. Reste à dire au programme d'attendre la pression de la touche ESC ou la fin du mode SetBeep pour quitter le programme.

  Si vous voulez plus d'explications sur les fonctions de PolySnd v2.0, veuillez lire la documentation fournis dans le pack.

Télécharger example1.zip en C

 

Un second projet:

  Nous avons vu pour l'instant comment ce forme un programme en C ou en ASM utilisant PolySnd, notre exemple utilisait des fonctions simple de PolySnd v2.0, maintenant nous allons réaliser un programme capable de sortir une musique en stéréo en attendant la pression de la touche ESC ou la fin de la musique, pour cela nous allons procéder par étapes et nous aurons besoin de PolySnd MIDI Converter.

  Vous devez tout d'abord télécharger la musique 'Mario' que nous allons utiliser pour notre projet.

Télécharger Mario.mid

   Maintenant nous devons télécharger PolySnd MIDI Converter qui s'occupera de convertir ce fichier MIDI dans le format voulu pour notre programme.

Télécharger PolySnd MIDI Converter v3.2.1

  Après avoir téléchargé PolySnd MIDI Converter, il vous reste à l'installer sur votre disque dur. Une fois cette étape de terminée, nous allons commencer à réaliser notre projet.

 

Réalisation du projet:

  Ouvrez TIGCC et réaliser un projet en C avec PolySnd v2.0 ce nommant 'example2', procédez de la même façon que pour notre premier programme. Vous devez vous retrouver avec un projet constitué de cette façon:

  Nous allons pour l'instant enregistrer notre projet et mettre de côté TIGCC pour pouvoir convertir 'Mario', ouvrez PolySnd MIDI Converter, vous devez vous retrouver avec cette environnement:

  Cliquez sur le 'File/Open' et choisissez 'Mario', la liste 'Tracks' dans 'Convert tracks' doit ce remplir avec 3 pistes classé. Dans 'Data type' cochez la case C et dans 'Management of PolyNotes' cochez la case 'Last Note'.

  La zone 'Data type' permet de choisir le langage dans le quel on veut que les données soit traduite.

  La zone 'Management of PolyNotes' définit le comportement du convertisseur lorsqu'il rencontre plusieurs notes joué en même temps, le mode:

- Alternation (Alterné) joue toutes les notes mais avec une durée de 1 cycle ce qui augmente dans des cas considérablement la taille des données mais la qualité s'en trouve bien meilleur.

- Average frequency (Frequence moyenne), parmis toutes les notes, le convertisseur cherche la note moyenne, ce mode est assez moyen en qualité et peu des fois donner des résultats assez inattendus, il est généralement utilisé dans des musique dont le nombre de PolyNote est élevé.

- First note (Première note), dans la liste des notes, le convertisseur prend la première note, ce mode est le plus économique mais donne des résultats horrible pour la plupart des fichiers MIDI, généralement il est utilisé pour des fichiers MIDI assez simple.

- Last Note (Dernière note), dans la liste des notes, le convertisseur prend la dernière note, ce mode est très très économique et donne un bon rapport en qualité et en taille, c'est ce mode là que nous allons utiliser pour convertir Mario, dans la mesure ou Mario possède très peu de PolyNotes qui ne sont pas importante. Ce mode s'adapte parfaitement dans la plupart des musique sauf dans celle composé de beaucoup de PolyNotes.

  PolySnd MIDI Converter offre de multiple informations et il est possible de modifier certains paramètres comme:

- Add octaves (Ajouter octave), ce mode permet de monter ou descendre la musique à partir du MIDI d'un certain nombres d'octaves, plus ce nombre est élevé plus la musique convertie sera aigus et inversement, il est possible d'entrer un argument négatif mais attention, si dans vos données vous avez un octave inférieur à 0 ou supérieur à 9 vous ne pourrais pas l'utiliser, PolySnd possède au maximum 10 octaves notée de 0 à 9.

- Division of duration (Division de durée), ce mode permet d'augmenter ou diminuer le tempo d'origine, plus la valeur est petite plus le tempo est élevé et plus la musique à une meilleur qualité dans le cas du mode 'Alternation' et dans le cas contraire vous obtenez des données de plus petite taille qui peuvent voir leur qualité diminuer dans le cas ou vous perdez des notes. Il est possible d'entrer un nombre à 2 chiffres après la virgule. Le convertisseur vous donnera la valeur du nouveau tempo de PolySnd comparé au tempo réel du MIDI.

  Sur ces explications vous serez capable de convertir n'importe quel MIDI et de modifier certains paramètres suivant ce que vous recherchez (qualité audio ou taille des données), mais reste un point assez important, car il n'est pas réellement conseilléde convertir un MIDI tel quel qui de plus contienténormément de pistes (plus de 4), vous devrez pour cela le modifier et effacer les pistes inutile pour PolySnd, comme vous le savez PolySnd est capable de jouer que 2 pistes (une par canal) voir plus si le mode 'Alternation' est coché. Pour voir la procédure de retouche d'un fichier MIDI, allez dans la rubrique consacré à PolySnd MIDI Converter.

Revenons à la conversion de 'Mario', vous devez vous retrouver avec les bon paramètres:

  Vous constatez que la musique 'Mario' comporte 3 pistes pour le convertisseur, or réellement 'Mario' comporte 2 piste, la piste n°1 est en faite une piste contenant des informations mais sans aucune note. La plupart des morceau possède cette structure mais il peut exister des exceptions.

  Nous allons tout d'abord convertir un par un les tracks et les enregistrer dans des fichiers, pour cela cliquer sur le chiffre 2 dans le menu Tracks et faite le passer à droite avec le bouton ">" ou avec un double clique, le bouton 'Convert' devient disponible, cliquez dessus. Le convertisseur créer les données à travers divers étapes qui sont affiché en bas, une fois les étapes terminé, le bloc note de Windows s'ouvre avec les données sous la forme du langage choisit. Fermez le bloc note et cliquez sur le menu 'File/Save ' de PolySnd MIDI Converter, choisissez le répertoire ou ce trouve le projet de l'exemple 2 et nommez le fichier 'mario1.h'. Ouvrez ce fichier avec un éditeur de texte et modifier 'unsigned char channel []' par 'unsigned char mario_channel1 []'.

  Nous allons procéder de la même façon pour convertir la piste n°3 de 'Mario' mais auparavant vous devez enlever de la liste 'Convert tracks' l'ancienne piste qui a été convertie. Une fois la conversion terminé de la piste n°3, enregistré les données dans le fichier 'mario2.h' dans le répertoire de votre projet. Ouvrez ce fichier avec un éditeur de texte et modifier 'unsigned char channel []' par 'unsigned char mario_channel2 []'.

  Nous n'utiliserons plus PolySnd MIDI Converter à partir de maintenant, nous devons maintenant inclure dans notre projet les fichiers 'mario1.h' et 'mario2.h' et écrire le code permettant de jouer cette musique. Pour cela cliquez sur le menu 'Project/Add Files'.

  Pour déclarer ses 2 fichiers dans notre programme nous allons écrire ses lignes en dessous de '#include "polysnd2.h"'

#include "mario1.h"
#include "mario2.h"

  Une fois la déclaration des fichiers, nous allons écrire le code qui devra s'occuper de jouer la musique de 'Mario'. Vous devez ajouter ce code en dessous de 'pSnd_InstallSound ();'

pSnd_PlayMode (STEREO);
pSnd_SetTempo (105);

pSnd_PlaySound_voice1 (mario_channel1);
pSnd_PlaySound_voice2 (mario_channel2);

pSnd_SetState (ALLVOICES);

pSnd_PlayMode (STEREO), s'occupe de régler PolySnd v2.0 en mode stéréo ce qui signifie qu'il est possible d'utiliser un mode différent ou des données différente sur un canal, contrairement au mode mono qui ignore les fonctions basé sur voice2 (canal n°2) et donc le mode est joué sur les 2 canals.

pSnd_SetTempo, aurait plus être remplacé par pSnd_SetTempo_voice1 et pSnd_SetTempo_voice2, en effet pSnd_SetTempo est une définition qui permet de régler le tempo des 2 canals en même temps. Dans notre exemple nous avons un tempo de 105 bpm pour 'Mario' sur les 2 canals.

pSnd_PlaySound_voice[1|2], s'occupe de mettre PolySnd v2.0 en mode 'MIDI' sur le canal 1 ou 2, l'argument spécifié doit être une série de données audio. Dans notre exemple mario_channel1 et mario_channel2.

pSnd_SetState (ALLVOICES), enfin cette instruction permet de dire à PolySnd v2.0 de jouer les modes précédemment configuré sur le ou les canals voulu. Dans notre exemples nous activons la lecture des données MIDI sur tout les canals.

  Maintenant il nous reste à ajouter la ligne qui nous permettra de quitter le programmant en pressant la touche ESC ou en attendant la fin de la musique.

while ((_keytest (RR_ESC)==FALSE) && (pSnd_GetState()!=NOVOICE1));

  pSnd_GetState()!=NOVOICE, signifie que tant que tout les canals ne sont pas terminé, nous continuons la boucle, de façon plus logique nous auront plus remplacer cette ligne par:

while ((!_keytest (RR_ESC)) && (!(pSnd_GetState()==NOVOICE1)));

  Cette ligne contenant une boucle vide n'exécute aucunes instructions et pourtant la musique continue à être joué, pourquoi? PolySnd v2.0 est une librairie multitâche dans le fait qu'il est possible d'exécuter une série d'instructions en même temps que du son ce joue en tâche de fond. Dans notre exemple le son commence à l'instruction pSnd_SetState qui s'occupe 'd'activer' PolySnd v2.0, le programme ce déroule et la librairie joue le son en même temps, elle ne s'arrêtera que lorsque vous aurez modifier son comportement avec une fonction de PolySnd ou que les données quelle doit lire soit épuisé. Voyez PolySnd v2.0 comme les niveaux de gris sur TI, quand vous programmé une image en niveau de gris, vous avez juste besoin de spécifier les plans et non contrôler l'écran, c'est le même principe pour PolySnd, vous spécifiez des données sonores et la librairie fait le reste.

  Grâce au 2 premiers exemples vous voyez qu'il est assez plaisant et facile de programmer avec PolySnd v2.0, de plus son incorporation dans des projets demandant beaucoup de ressources est possible tel que les jeux, player...

  Dans notre prochain exemple nous allons voir comment utiliser PolySnd v2.0 dans un projet s'occupant d'afficher une balles sur l'écran et de jouer des sons et ce sans interrompre le mouvement de la balle pendant que le son est joué. Nous étudierons ensuite comment bloquer une action en attendant la fin d'un son.

Télécharger example2.zip

 

Animation d'une balle avec du son (partie n°1):

  Dans ce programme nous allons vraiment commencer à exploiter les performances de PolySnd v2.0, nous allons réaliser un programme réalisant le déplacement d'une balle avec un angle de 45°, chaque rebond sur l'écran correspondera à un son.

  Créez un nouveau projet en C avec la librairie PolySnd v2.0 que vous nommerez 'example3' avec le code de base pour initialiser PolySnd v2.0.

  Nous allons tout d'abord réaliser le programme sans s'occuper du son, nous devons tout d'abord définir le sprite et les déplacements de la balle, après avoir fait ceci, nous réaliseront les effets sonores et nous appliquerons à chaque collisions un son différent.

 

Réalisation du sprite (image) de la balle:

unsigned char ball_sprite [] = {0b00111100,
                                                0b01111110,
                                                0b11111111,
                                                0b11111111,
                                                0b11111111,
                                                0b11111111,
                                                0b01111110,
                                                0b00111100};
                                   

Inserez ce code en dessous de:

DEFINE_INT_HANDLER (myint2)
{
   pokeIO (0x60001B,0);
}

Notre sprite fait du 8x8 pixels, nous allons nous attquer au code de gestion de la balle.

 

Réalisation du code de déplacement de la balle:

  La position de notre balle sera définis par 2 variables xpos et ypos qui indiquerons ça positions en X et Y, à chaque passage de boucle, nous incrémenterons ses variables avec un facteur indiquant la direction de la balle, soit xdir pour son déplacement suivant X et ydir suivant Y. Pour afficher et effacer correctement la balle, nous l'afficherons avec un OU logique à la fin de la boucle et nous l'effacerons avec OU exclusif (XOR) au début de la boucle, bien sûr nous prenderons soin d'afficher la balle avec une bonne vitesse et avec une boucle d'attente.

Voici le code du programme:

// C Source File
// Created 11/10/2003; 17:13:50

#include <tigcclib.h>
#include "polysnd2.h"

INT_HANDLER OldInt1 = NULL;
INT_HANDLER OldInt2 = NULL;

DEFINE_INT_HANDLER (myint2)
{
   pokeIO (0x60001B,0);
}

unsigned char ball_sprite [] = {0b00111100,
                                                0b01111110,
                                                0b11111111,
                                                0b11111111,
                                                0b11111111, 
                                                0b11111111, 
                                                0b01111110,
                                                0b00111100};

//Programme principal
void _main(void)
{
   int i;

   short xpos = (LCD_WIDTH-1)/2;
   short ypos = (LCD_HEIGHT-1)/2;
   char xdir = 1, ydir = 1;

   OldInt1 = GetIntVec (AUTO_INT_1);
   OldInt2 = GetIntVec (AUTO_INT_2);
   SetIntVec (AUTO_INT_1, DUMMY_HANDLER);
   SetIntVec (AUTO_INT_2, myint2);

   pSnd_EnableSound ();
   pSnd_InstallSound ();

   ClrScr ();
   Sprite8 (xpos, ypos,8 ,ball_sprite, LCD_MEM, SPRT_OR);

   while (_keytest (RR_ESC)==FALSE)
   {
      Sprite8 (xpos, ypos, 8, ball_sprite, LCD_MEM, SPRT_XOR);

      xpos+=xdir; ypos+=ydir;

      if (xpos+8 > (LCD_WIDTH-1)) xdir = -1;
      if (xpos < 0) xdir =1;
      if (ypos+8 > (LCD_HEIGHT-1)) ydir = -1;
      if (ypos < 0) ydir = 1;

      Sprite8 (xpos, ypos, 8, ball_sprite, LCD_MEM, SPRT_OR);

      for (i=0; i<10000; i++);
   }

   pSnd_UninstallSound ();
   pSnd_DisableSound ();

   SetIntVec (AUTO_INT_1, OldInt1);
   SetIntVec (AUTO_INT_2, OldInt2);
}

  Nous allons nous occuper maintenant des divers parties de ce code pour mieux comprendre ce programme et ainsi pouvoir y introduire des séquences sonores sans trop de difficultés.

   int i;

   short xpos = (LCD_WIDTH-1)/2;
   short ypos = (LCD_HEIGHT-1)/2;
   char xdir = 1, ydir = 1;

Ici nous définissons les variables qu'utilisera le programme:

i est va permettre juste d'être utilisé dans la boucle de temporisation.

xpos et ypos sont les variables qui vont permettre de situer la balle sur l'écran de telle sorte que ça coordonné soit (xpos,ypos), ici nous les inialisons de tel sorte qu'au lancement du programme la balle ce situe au centre de l'écran et ce sur n'importe quel modèle de calculatrice.

xdir et ydir permettent de définir le sens de déplacement de la balle, dans notre programme, ses variables ne pourrons prendre que 2 valeurs (-1 ou 1), si xdir=1, la balle ce déplacera vers la droite et si xdir=-1, vers la gauche, s'est le même principe pour ydir. Si ydir=-1, la balle ce déplacera vers le haut et si ydir=1, vers le bas.

Voilà nos variables, maintenant nous devons les exploiter:

   ClrScr ();
   Sprite8 (xpos, ypos,8 ,ball_sprite, LCD_MEM, SPRT_OR);

   while (_keytest (RR_ESC)==FALSE)
   {
      Sprite8 (xpos, ypos, 8, ball_sprite, LCD_MEM, SPRT_XOR);

      xpos+=xdir; ypos+=ydir;

      if (xpos+8 > (LCD_WIDTH-1)) xdir = -1;
      if (xpos < 0) xdir =1;
      if (ypos+8 > (LCD_HEIGHT-1)) ydir = -1;
      if (ypos < 0) ydir = 1;

      Sprite8 (xpos, ypos, 8, ball_sprite, LCD_MEM, SPRT_OR);

      for (i=0; i<10000; i++);
   }

  Nous effacons tout d'abord l'écran avec ClrScr (à savoir que c'est une fonction de TIGCC) et nous affichons la balle avec sprite8 en mode OU logique.

  La boucle while execute une série d'instruction entre {} tant que la condition est vrai, ici tant que nous n'avons pas appuyez sur la touche ESC. Après nous nous occupons d'effacer la balle sur l'écran en l'affichant avec sprite8 mais en mode OU exclusif (XOR), nous ajoutant xdir à xpos et ydir à ypos de telle sorte d'effectuer le mouvement de la balle. Une fois cette étape d'effectué, il faut vérifier que la balle ne sorte pas de l'écran, pous cela on applique des collisions entre les points ce situant à l'extremité de la balle donc si nous voulons tester correctement si il y a collisions avec le bas de l'écran et la balle nous devons ajouter 8 à xpos dans notre condition car la balle fait 8 pixels de hauteur et procéder de la même façon pour les autres collisions, mais au lieu de changer xpos ou ypos dans notre résultat , nous changerons les vecteurs de directions xdir ou ydir. Et ensuite pour finir nous affichons la balle avec sprite8 en mode OU logique et nous effectuons une boucle de temporisation avec for pour que la balle ne soit pas trop rapide et que son temps d'affichage soit visible.

Nous allons donc maintenant créer les 4 séquences audio de collisions avec l'écran, pour cela vous devez créer un nouveau fichier du type header (portant l'extension h) que vous nommerez 'sounds_ball.h' et l'inclure dans le projet en tapant au début du code '#include "sounds_ball.h"'. Ouvrez le fichier 'sounds_ball.h' et copiez le code suivant:

//C Source File
//Created 11/10/2003; 17:13:50
//Collision avec la gauche
unsigned short collide_left[]={2500,15,
                                               1415,21,
                                               1000,30,
                                               2000,10,
                                               0xFFFF};

//Collision avec la droite
unsigned short collide_right[]={5500,15,
                                                 2415,21,
                                                 3000,30,
                                                 4000,10,
                                                 0xFFFF};

//Collision vers le haut
unsigned short collide_up[]={1250,10,
                                              2300,30,
                                              3800,10,
                                              4500,10,
                                              0xFFFF};

//Collision vers le bas
unsigned short collide_down[]={5845,5,
                                                   600,10,
                                                   5423,30,
                                                   8645,20,
                                                   0xFFFF};

  Voici enfin notre fichier 'sounds_ball.h' remplit de données sonores, ici nous avons réaliser 4 listes de données pour PlayFX, les données de PlayFX s'ordonnent de façon précise:

fréquence, durée, fréquence, durée .... fréquence, durée, 0xFFFF

  La fréquence peut aller de 0 (considéré comme une pause) à 32768 Hz, ses valeurs ne sont pas précise et les durées vont de 1 à 255 et sont en cycles tempo, soit 32 correspondant à une noire. Ce mode est très difficile à utiliser mais produit des résultats assez impressionnant. (note: c'est le seul mode qui n'a pas de logiciel de conversion). Une liste de données pour PlayFX doit toujhours ce terminer par 0xFFFF et ce pour indiquer ça fin à PolySnd v2.0.

Voici maintenant le code du programme principal, nous avons juste modifié les conditions lors de collisions:

// C Source File
// Created 11/10/2003; 17:13:50

#include <tigcclib.h>
#include "polysnd2.h"

INT_HANDLER OldInt1 = NULL;
INT_HANDLER OldInt2 = NULL;

DEFINE_INT_HANDLER (myint2)
{
   pokeIO (0x60001B,0);
}

unsigned char ball_sprite [] = {0b00111100,
                                                0b01111110,
                                                0b11111111,
                                                0b11111111,
                                                0b11111111, 
                                                0b11111111, 
                                                0b01111110,
                                                0b00111100};

//Programme principal
void _main(void)
{
   int i;

   short xpos = (LCD_WIDTH-1)/2;
   short ypos = (LCD_HEIGHT-1)/2;
   char xdir = 1, ydir = 1;

   OldInt1 = GetIntVec (AUTO_INT_1);
   OldInt2 = GetIntVec (AUTO_INT_2);
   SetIntVec (AUTO_INT_1, DUMMY_HANDLER);
   SetIntVec (AUTO_INT_2, myint2);

   pSnd_EnableSound ();
   pSnd_InstallSound ();

   pSnd_PlayMode (MONO);
   pSnd_SetTempo (1000);

   ClrScr ();
   Sprite8 (xpos, ypos,8 ,ball_sprite, LCD_MEM, SPRT_OR);

   while (_keytest (RR_ESC)==FALSE)
   {
      Sprite8 (xpos, ypos, 8, ball_sprite, LCD_MEM, SPRT_XOR);

      xpos+=xdir; ypos+=ydir;

      if (xpos+8>(LCD_WIDTH-1))
     {
          xdir=-1;
          pSnd_PlayFX_voice1 (collide_right);
          pSnd_SetState (VOICE1);
     }

     if (xpos<0)
     {
          xdir=1;
          pSnd_PlayFX_voice1 (collide_left);          
          pSnd_SetState (VOICE1);
     }

     if (ypos+8>(LCD_HEIGHT-1))
     {
          ydir=-1;     
          pSnd_PlayFX_voice1 (collide_down);
          pSnd_SetState (VOICE1);
     }

     if (ypos<0)
     {
          ydir=1;
          pSnd_PlayFX_voice1 (collide_up);
          pSnd_SetState (VOICE1);
     }

      Sprite8 (xpos, ypos, 8, ball_sprite, LCD_MEM, SPRT_OR);

      for (i=0; i<10000; i++);
   }

   pSnd_UninstallSound ();
   pSnd_DisableSound ();

   SetIntVec (AUTO_INT_1, OldInt1);
   SetIntVec (AUTO_INT_2, OldInt2);
}

  Nous réglons PolySnd v2.0 en mode mono grâce à pSnd_PlayMode puis nous paramètrons le tempo à 1000 bpm avec SetTempo, ici pSnd_SetTempo_voice1 aurait suffit.

  Dans chaque conditions de collisions nous jouant un son ce trouvant dans le fichier 'sounds_ball.h' avec pSnd_PlayFX_voice1 et nous donnons l'ordre à PolySnd v2.0 de jouer le mode de la voie1 avec pSnd_SetState (VOICE1), ici comme nous sommes en mono, VOICE1 suffit. PolySnd v2.0 n'attend pas qu'un mode soit finit de jouer pour executer le suivant, celui qui était en cours et ignoré au profit du nouveau mode et des nouvelles données (bien sûr il est toujours possible de programmer une gestion de modes...).

Télécharger example3.zip partie 1.

 

Animation d'une balle avec du son (partie n°2):

  Nous allons réaliser le même programme que précédément mais cette fois si en donnant la priorité au son et donc bloquant le cours du programme lorsqu'un son est joué. Vous allez constater que la balle subira des ralentissements. Mais cette méthode est utile dans le cas ou vous devez executer des actions en fonction du son.