1- Introduction.
2- Les améliorations apportées.
3- Comment fabriquer ou obtenir un adaptateur Jack 3.5 mm <-> 2.5 mm?
4- Fonctionnement de la librairie et précautions à prendre.
5- Utiliser PolySnd v2.0 dans un programme.
6- Informations à propos des niveaux de gris et de l'auto int n°5.
7- Liste et descriptions des fonctions de PolySnd v2.0.
8- Points sur la consommation de ressources avec PolySnd v2.0.
9- Utiliser PolySnd v2.0 avec Genlib.
10-Tableau des durées.
11-Améliorer la qualité du son.
12-Me contacter.


1. Introduction. 
  

   PolySnd v2.0 est une librairie audio optimisée pour la programmation de jeux sous TI68K. Son but est d'apporter un maximum de fonctions et de confort de programmation. Elle a été totalement réécrite et repensée comparé aux autres versions. La version 2.0 permet enfin de jouer du son en tâche de fond avec des niveaux de gris… Elle est aussi capable de jouer du PCM qualité 1 bit à 8000 Hz, idéal pour des effets sonores dans les jeux.

 

2. Les améliorations apportées.

   PolySnd v2.0 est la seule librairie qui soit capable de jouer des musiques, des effets sonores, une simple fréquence et même du PCM (format WAV) dans des programmes sans que celle-ci ne bloque son processus. Elle est capable de jouer des musiques sur 2 canaux (2 voies), avec des niveaux de gris et ce sans ralentir le programme en cours. Elle incorpore 4 fonctions de gestions de données (Musiques, Effets sonores, simple fréquence, gestion de données WAV en stéréo), diverses fonctions informant sur l'état de la librairie et d'autres fonctions sur le traitement des données musicales. PolySnd v2.0 est idéale pour les programmes audio comme (Player, Programmes de composition musical ou encore simple démos graphique…), c'est la seule librairie audio sur tout supports confondus (calculatrices) d'être utilisable dans des programmes même nécessitant une grande puissance.

PolySnd v2.0 est le fruit de nombreux mois de recherche et de développement, j'espère quelle comblera tout vos désirs.

 

3. Comment fabriquer ou obtenir un adaptateur Jack 3.5 mm <-> 2.5 mm ?

   PolySnd v2.0 nécessite un adaptateur Jack 3.5 mm en 2.5 mm stéréo, en effet PolySnd v2.0 est une librairie polyphonique en stéréo et donc pour pouvoir sortir du son sur un casque (conseillé car sur d'autre supports, le son risque d'être parasité) ou sur des enceintes, vous devez absolument posséder un adaptateur.

Si vous n'avez pas d'adaptateur Jack 3.5 mm en 2.5 mm, vous pouvez vous en procurer un dans certains magasins, si ce n'est pas possible vous pouvez vous en fabriquer un avec peu de matériel, pour ça, suivez la procédure ci-dessous :

Matériels :

- Prise Jack Mâle 2.5 mm.
Vous pouvez en trouver une dans un magasin d'électronique ou en récupérant la prise Jack d'un cordon fourni avec la TI.

- Prise Jack Femelle 3.5 mm.
Se trouve facilement dans les grandes surfaces ou dans des magasins d'électronique.

- Fer à souder, avec de l'étain.
- Ruban adhésif Noir.
Vous devez relier ensemble la masse, et les 2 fils de données.

Le fil gris correspond à la masse, et les fils rouge et bleu, aux données.


Ce schéma peut être adapté avec une prise Jack Mâle 3.5 mm.


4. Fonctionnement de la librairie et précautions à prendre pour créer un programme.

   Pour pouvoir jouer du son dans un programme en tâche de fond (background) c'est à dire faire dérouler un programme tout en jouant de la musique… Cette librairie utilise l'auto interruption n°5 poussée au maximum (8 KHz sur HW2 et 11 KHz sur HW1) mais elle reste toujours disponible aux programmeurs grâce à une fonction incluse dans PolySnd v2.0. Cette auto interruption étant redirigée vers les routines de PolySnd v2.0, certaines fonctions de l'AMS (Advanced Mathematic Software) seront inutilisables c'est pourquoi vous devez utiliser des équivalents.

Pour que cette librairie fonctionne correctement, vous devez désactiver certaines interruptions :

- L'auto Int n°1, utilisée par l'AMS pour restaurer la ligne de statut (status line), et pour afficher le statut des touches. Utilisée par certaines fonctions.

- L'auto Int n°2, utilisée par ngetchx de l'AMS (Perturbe la librairie, importante à désactiver).

Au cours de cette documentation, les exemples permetteront de mieux comprendre comment sont désactivé ces 2 interruptions.

 

5. Utiliser PolySnd v2.0 dans un programme.

Version dynamique :

   Ne peut être seulement utilisé que si vous programmez en mode kernel, vous devez dans ce cas posséder un kernel et la librairie PolySnd v2.0 sur votre TI.
Votre programme nécessitera donc la présence de PolySnd v2.0 sur votre TI pour fonctionner.
Vous trouverez la librairie dans le répertoire bin puis l'header dans le répertoire headers/dynamique.


Version statique

   Si votre programme est développé en nostub ou en kernel, vous désirez que votre programme fonctionne sans la présence de la librairie PolySnd v2.0 et que celle-ci ce trouve en interne dans le programme, vous devrez utiliser la version statique de PolySnd v2.0, les avantages de la version statique sont que vous économiserez de la place car votre programme utilisera seulement les fonctions qu'il a besoin de la librairie, vous trouverez la librairie au format statique dans le répertoire bin et l'header dans le répertoire headers\statique.


Conclusion :

   Il est préférable d'utiliser la version dynamique pour des programmes très petits et ne se limitant qu'à une séquence audio (morceaux de musiques ou simples effets sonores). Ces programmes n'ont que pour seul but, exécuter une musique… Elle ne peut être utilisée dans des programmes en nostub.

Par contre la version statique doit être utilisé dans de gros projet comme programmes audio, jeux, démos sonores, éditeur de partitions…

Il est conseillé de choisir correctement en fonction de votre programme le format de la librairie, vous ne pourrez qu'économiser de la mémoire si ce choix est bien fait.

 

6. Informations à propos des niveaux de gris et de l'auto int n°5.

   PolySnd v2.0 a été testé avec les routines de niveaux de gris de TIGCC, pour que les niveaux de gris fonctionnent correctement avec PolySnd v2.0 vous devez utiliser la fonction USE_GRAY_WITH_POLYSND avant l'appel de GrayOn. USE_GRAY_WITH_POLYSND n'est en fait une définition faisant appel à un hack de TIGCC, il n'est pas garanti que cette ligne fonctionne dans les versions de TIGCC antérieure ou supérieur à la version 0.94. Cette ligne à pour but de ne pas désactiver et de dérégler l'auto int 5 utilisé par PolySnd v2.0 lors du passage de la routine de niveaux de gris via l'auto int 1.

PolySnd v2.0 utilise peux de ressources de l'auto int 5 c'est pourquoi il est possible de l'utiliser dans vos programmes à une fréquence de paramétrable grâce à la fonction SetInterrupt5Rate, par défaut l'auto int 5 tourne à 1 Hz.Voir liste des fonctions.

 

7. Liste et descriptions des fonctions de PolySnd v2.0.

   La liste est donnée sous forme de prototypes pour le C et en assembleur, un exemple en assembleur sera donné pour chaque fonction. Vous trouverez au dessus des exemples le passage des arguments par registres pour la programmation en Asssembleur. Les fonctions en C commence toutes avec le prefixe pSnd_.

Tout arguments eronné ne sont pas pris en compte par la librairie est peuvent être source de plantage plus ou moins sévére. Je ne suis en aucun cas responsable des pertes de données et dommage subit par une mauvaise utilisation de la librairie

Liste des fonctions de PolySnd v2.0

EnableSound
DisableSound
InstallSound
UninstallSound
Initialize
SetTempo_voice[1|2]
GetTempo_voice[1|2]
SetState
SetLoop
SetBeep_voice[1|2]
PlayFX_voice[1|2]
GetFrequency_voice[1|2]
PortStatus
Interrupt5
PlaySound_voice[1|2]
GetLength_voice[1|2]
GetTime
GetState
GetMode
GetLoop
Time_voice[1|2]
SetTime_voice[1|2]
VoiceState
SetVoiceState
SetIntMask
AddNotes_voice[1|2]
PlayWAV_voice[1|2]
Sample_voice[1|2]
GetNote_voice[1|2]
_Ptridle_voice[1|2]
_time_counter_voice[1|2]
_note_time_counter_voice[1|2]
_SkipData_voice[1|2]
PlayMode
SetLength_voice[1|2]
SetInterrupt5Rate

USE_GRAY_WITH_POLYSND

 

void pSnd_EnableSound (void) ;
jsr    polysnd2 ::EnableSound

Initialise le port I/O.

   Cette fonction initialise le port I/O en bas niveau pour permettre de sortir des impulsions sous forme binaire, généralement cette fonction est appelée en première et est suivie de InstallSound. Elle inhibe aussi l'auto int n°4.

 

void pSnd_DisableSound (void) ;
jsr    polysnd2 ::DisableSound

Remet le Port I/O à son état courant.

   Cette fonction active le port I/O en haut niveau pour rendre la main au TIOS et ainsi être géré correctement.

 

void pSnd_InstallSound (void) ;
jsr    polysnd2 ::InstallSound

Input:     -
Output:  -
Del:        d0

Installe l'interruption audio.

   Redirige l'auto int 5, initialise les variables de PolySnd v2.0 et installe l'interruption audio.
Cette fonction se situe généralement après EnableSound.

A savoir que cette fonction initialise toute les valeurs de PolySnd v2.0. par défaut PolySnd v2.0 est en mode Stéréo et le mode loop est mis à 0.

 

void pSnd_UninstallSound (void) ;
jsr    polysnd2 ::UninstallSound

Input:     -
Output:  -
Del:        d0

Desinstall l'interruption audio.

   Cette fonction redirige l'auto int 5 à son état et à sa valeur initiale. Elle désactive toutes les fonctions de PolySnd v2.0.


void pSnd_Initialize (void);
jsr    polysnd2 ::Initialize

Input:     -
Output:  -
Del:       d0, a0

Remet à zéro les variables de PolySnd v2.0.

   Cette fonction remet à zéro les variables systèmes de PolySnd v2.0. Elle annule toutes musiques ou tout effets sonores en cours.

 

void pSnd_SetTempo_voice1 (unsigned short tempo) ;
void pSnd_SetTempo_voice2 (unsigned short tempo);
#define pSnd_SetTempo (tempo);

move.w  #120,d0
jsr          polysnd2::SetTempo_voice[1|2]

Input:    d0.w = Tempo
Output:  -
Del:       d1, d2

Règle le tempo sur la voie choisie.

   Le tempo est donné en bpm. La valeur du tempo doit se situer entre 1 et 15 850 bpm, ce tempo est indicatif et plus sa valeur sera élevée, moins il sera précis.

A savoir que cette fonction fait partie de l'initialisation de PolySnd v2.0.

 

unsigned short pSnd_GetTempo_voice1 (void) ;
unsigned short pSnd_GetTempo_voice2 (void);

jsr polysnd2::GetTempo_voice[1|2]

Input:     -
Output:  d0.w
Del:       d1

Renvoie le tempo en cours de la voie choisie.

   Cette fonction retourne le tempo en cours en bpm, la valeur du tempo est indicatif et peut donc posséder une certaine marge d'erreur.

 

void pSnd_SetState (unsigned char state) ;

move.b  #_ALLVOICES,d0
jsr          polysnd2::SetState

Input:    d0.b
Output:  -
Del:        -

Règle l'états des voies.

   Cette option permet de mettre en pause/jouer un canal audio en fonction d'un bit. par défaut elle est mise à zéro et donc en pause pour les 2 voies, n'oublier d'activer PolySnd v2.0 à l'initialisation.

Le canal 1 correspond au bit 0 et le canal 2 au bit 1, lorsque le bit d'un canal est à 1, le canal est activé, si le bit est à 0, le canal est en pause.


#define NOVOICE      0
#define VOICE1          1
#define VOICE2          2
#define ALLVOICES  3

_NOVOICE      equ  0
_VOICE1          equ  1
_VOICE2          equ  2
_ALLVOICES  equ  3

Cette fonction ne peut prendre en paramètre que ses énumérations.

 

void pSnd_SetLoop (unsigned char loop) ;

move.b  #_ALLVOICES,d0
jsr          polysnd2::SetLoop

Input:    d0.b
Output:  -
Del:        -

Règle la répétition de son.

   Cette option permet de répéter en boucle une musique, des effets sonores ou une simple fréquence, elle a pour but de faciliter le programmeur pour le développement de jeux, si une musique est jouée sur le canal 1 et quelle doit être jouée en boucle, PolySnd v2.0 s'en chargera en regardant la valeur passée par SetLoop.
Attention, il n'est pas conseillé de jouer en boucle une musique en stéréo avec cette fonction car les voies risquent d'être désynchronisées. Voir fonction VoiceState.

Cette fonction ne peut prendre en paramètre que les énumérations cités plus haut.


void pSnd_SetBeep_voice1 (unsigned short freq, unsigned char duree) ;
void pSnd_SetBeep_voice2 (unsigned short freq, unsigned char duree) ;

move.w  #440,d0
move.b   #30,d1
jsr          polysnd2::SetBeep_voice[1|2]

Input:    d0.w = Frequence
              d1.b = Longueur
Output:  -
Del:       d0

Régle PolySnd v2.0 en mode simple fréquence sur le canl voulu.

   Cette fonction permet de jouer une simple fréquence sur le canal de son choix. pour jouer ce mode, n'oubliez pas de régler correctement SetSate.

 

void pSnd_PlayFX_voice1 (unsigned short *list);
void pSnd_PlayFX_voice2 (unsigned short *list);

lea   SoundFX(PC),a0
jsr    polysnd2::PlayFX_voice[1|2]

Input:    a0
Output:  -
Del:        d0

Joue un effet sonore sur le canal voulu.

  Cette fonction permet de jouer des effets sonores (bruitages) sur le canal voulu. Cette fonction demande en paramètre un pointeur correspondant à des données codées en short.

En C pour utiliser correctement cette fonction vous devez utiliser une liste à une dimension qui se compose de cette façon :

fréquence, durée, fréquence, durée… fréquence, durée, fin

Les fréquences sont comprises entre 1 et 32768, 0 est considéré comme une pause.
Les durées ici, peuvent aller de 1 à 255..


Voici un exemple de données, effet sonore pour PlayFX… :

unsigned short MySoundFX[]={5000,30,
                                                    485,10,
                                                    8000,90,
                                                    7000,50,
                                                    6542,45,
                                                    0xFFFF};

0xFFFF (65535) signale à PolySnd v2.0 la fin de l'effet sonore, il est important à mettre, sans lui, PolySnd v2.0 sera perdu.

Les xx correspondent aux fréquences de l'effet sonore MySoundFX.
Les yy correspondent aux durées des fréquences associées, les durées dépendent du tempo.

En assembleur MySoundFX donnera :

MySoundFX :
dc.w 5000,30
dc.w 485,10
dc.w 8000,90
dc.w 7000,50
dc.w 6542,45
dc.w $FFFF

Attention: N'oubliez pas d'utiliser correctement SetSate pour activer cette fonction.

 

unsigned short pSnd_GetFrequency_voice1 (void);
unsigned short pSnd_GetFrequency_voice2 (void);

jsr polysnd2::GetFrequency_voice[1|2]

Input:    -
Output:  d0.w
Del:        -

Renvoie la fréquence en cours sur le canal voulu.

  Cette fonction renvoie la fréquence en train d'être jouée sur le canal voulu. La fréquence est comprise entre 0 est 32768.

 

unsigned char pSnd_PortStatus (void) ;

jsr polysnd2 ::PortStatus

Input:    -
Output:  d0.b
Del:        d0

Renvoie l'état du port I/O en bas niveau.

  Cette fonction permet de savoir quand la librairie émet des impulsions. Le canal 1 correspond au bit 0 et le canal 2 au bit 1, si un bit est armé alors la tension traversant le fil de donné du canal correspondant est à 0 V si le bit est désarmé la tension est à ~3V. Cette fonction est utile pour la création d'un oscilloscope à ondes en créneaux…
Cette fonction renvoie juste l'état du port (0x60000E).

 

void pSnd_Interrupt5 (INT_HANDLER) :

lea        interrupt(PC),a0
jsr         polysnd2 ::Interrupt5

Interrupt_handler:
move.w #$2700,sr
...
rte

Input:    a0
Output:  -
Del:        -

Auto Int n°5 de PolySnd v2.0.

  Cette fonction permet d'utiliser l'auto Int n°5 avec PolySnd v2.0. Elle tourne à une fréquence précise de 1 Hz par défaut. Elle est paramètrable grâce à la fonction SetInterrupt5Rate.

Exemple en C :

INT_HANDLER OldInt1 = NULL;
INT_HANDLER OldInt2 = NULL;

volatile unsigned long counter ;

DEFINE_INT_HANDLER (Interrupt_handler5)
{
  counter++;
}

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

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

  counter=0;

  pSnd_EnableSound ();
  pSnd_InstallSound ();

  pSnd_Interrupt5 (Interrupt_handler5);
  while (_keytest (RR_ESC)!=TRUE) printf_xy (0,0,"%ul",counter);

  pSnd_UninstallSound ();
  pSnd_DisableSound ();

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

Dans ce programme counter sera incrémenté de 1, 1 fois par secondes.

 

void pSnd_PlaySound_voice1 (unsigned char *);
void pSnd_PlaySound_voice2 (unsigned char *);

lea  channel(PC),a0
jsr    polysnd2::PlaySound_voice[1|2]

Input:    a0
Output:  -
Del:        d0


Joue une musique sur le canal voulu.

  Cette fonction permet de jouer une musique sur le canal voulu. Cette fonction demande un pointeur sur des données en char.

En C pour utiliser correctement cette fonction vous devez utiliser une liste à une dimension qui se compose de cette façon :

note_octave,durée, note_octave, durée… note_octave, durée, fin

Les notes suivies de leur octave sont définies grâce à un tableau de fréquences, regardez le fichier header en C ou en ASM pour connaître les notes dans leurs formats. Ce procédé est identique pour les durées.
Les bémols sont notés b et les dièses d en C et en ASM. Une note est toujours précédée d'un tiret _. N'hésitez pas à ouvrir les fichiers polysnd2.h dans le répertoire headers pour voir les écritures des notes et durées...


Voici un exemple de données effets sonores pour PlaySound en C:

unsigned char channel[]={_do0,noire,
                                          _fa5,blanche,
                                          _sold4,croche,
                                          _sib9,croche_pointee,
                                          0xFF} ;

Le 0xFF indique à PolySnd v2.0 la fin des données musical.

En assembleur channel donnera :

channel :
dc.b  _do0,noire
dc.b  _fa5,blanche
dc.b  _sold4,croche
dc.b  _sib9,croche_pointee
dc.b  $FF

Attention, certaines fonctions de PolySnd v2.0 ne peuvent être utilisées qu'avec ce mode là.
N'oubliez pas d'utiliser correctement SetSate pour activer cette fonction.

 

unsigned char pSnd_GetLength_voice1 (void);
unsigned char pSnd_GetLength_voice2 (void);

jsr polysnd2::GetLength_voice[1|2]

Input:    -
Output:  d0.b
Del:        d0

Renvoie la durée d'une note.

  Cette fonction permet de connaître la durée d'une fréquence ou note en train d'être jouée. Idéal pour suivre l'avancée d'un morceau de musique ou d'effets sonores.

 

unsigned short pSnd_GetTime (unsigned char *PtrData, unsigned short Tempo);

lea        channel(PC),a0
move.w #120,d2
jsr         polysnd2::GetTime

Input:    a0 = PtrData
              d2.w = Tempo
Output:  d0.w
Del:       d0, d1, d2 ,a0

Renvoie le temps total d'une musique.

  Renvoie le temps que mettra PolySnd v2.0 pour jouer une musique, ce temps est renvoyé en secondes. Cette fonction ne fonctionne qu'avec des données musicales sous la forme de PlaySound…
Cette fonction est extérieure à PolySnd v2.0 et modifiera en rien son comportement. Elle permet de faciliter le travail du programmeur. Idéal pour un player ou pour estimer la durée d'une musique.

Attention: Le temps donné est une approximation et donc il n'est pas précis.

 

unsigned char pSnd_GetState (void);

jsr polysnd2 ::GetState

Input:    -
Output:  d0.b
Del:        d0

Renvoie l'état d'un canal.

  Renvoie l'état d'un canal et indique si le canal est en pause ou non. Le canal 1 correspond au bit 0 et le canal 2 au bit 1, si ce bit est armé, du son est joué sur le canal correspondant, si le bit est désarmé le canal est en pause.

Ces énumérations sont valables pour tester les canaux :

#define NOVOICE      0
#define VOICE1          1
#define VOICE2          2
#define ALLVOICES  3

_NOVOICE      equ  0
_VOICE1          equ  1
_VOICE2          equ  2
_ALLVOICES  equ  3

  VoiceState est assez identique mais elle est utilisée pour une fonction bien précise, utilisez GetState pour savoir si du son est joué sur un canal et VoiceState si un canal a terminé de jouer une simple fréquence, une musique ou un effet sonore. GetState donne l'état courant de PolySnd v2.0 et VoiceState l'état du mode en cours.

 

unsigned char pSnd_GetMode (void);

jsr polysnd2::GetMode

Input:    -
Output:  d0.b
Del:        d0

Renvoie le type de données que PolySnd v2.0 est en train d'exécuter.

  Cette fonction permet de savoir si une simple fréquence, un effet sonore, une musique ou encore des données WAV sont en train d'être joué sur un canal.
Cette fonction suit un codage bien précis pour connaître le mode de données exécuté.

Les bits 0 à 3 concerne le canal 1 et les bits 4 à 7, le canal 2, si :

0001 = beep (simple fréquence)
0010 = PlayFX (effet sonore)
0100 = PlayWAV (WAV)
1000 = PlaySound (musique)

Ces énumérations suivantes sont valables pour tester les canaux :
#define BEEP_VOICE1       1
#define BEEP_VOICE2       16
#define FX_VOICE1           2
#define FX_VOICE2           32
#define SOUND_VOICE1   8
#define SOUND_VOICE2   128
#define WAV_VOICE1        4
#define WAV_VOICE2        64

_BEEP_VOICE1      equ  1
_BEEP_VOICE2      equ  16
_FX_VOICE1           equ  2
_FX_VOICE2           equ  32
_SOUND_VOICE1  equ  8
_SOUND_VOICE2  equ  128
_WAV_VOICE1       equ  4
_WAV_VOICE2       equ  64

Exemple pour un effet sonore sur le canal 1 et une musique sur le canal 2. 1000 0010

En C :

if (pSnd_GetMode ()==(FX_VOICE1 | SOUND_VOICE2)) {…}


En ASM:

jsr           polysnd2::GetMode           ;appel de GetMode
move.b  #_FX_VOICE1,d1           ;d1 contient 0000 0010
ori.b      #_SOUND_VOICE2,d1  ;effectue un OU logique avec 0000 0010 et 1000 0000, d1 contient 1000 0010
cmp.b    d0,d1                                ;si d0=d1
beq        continue                            ;alors aller à continue
rts                                                  ;sinon fin

continue:
....

 

unsigned char pSnd_GetLoop (void);

jsr polysnd2::GetLoop

Input:    -
Output:  d0.b
Del:        d0

Renvoie si le mode loop est activé sur un canal.

  Cette fonction renvoie si le mode loop est activé sur un canal. Le bit 0 correspond au canal 1 et le bit 1 au canal 2. Si le bit est armé, le mode loop est activé, si le bit est désarmé le mode loop est désactivé. Ce mode n'est pas disponible pour les données WAV.

Ces énumérations sont valables pour tester les canaux :

#define NOVOICE      0
#define VOICE1          1
#define VOICE2          2
#define ALLVOICES  3

_NOVOICE      equ  0
_VOICE1          equ  1
_VOICE2          equ  2
_ALLVOICES  equ  3

 

unsigned short pSnd_Time_voice1 (void);
unsigned short pSnd_Time_voice2 (void);

jsr polysnd2::_Time_voice[1|2]

Input:    -
Output:  d0.w
Del:        d0

Renvoie le temps écoulé en secondes depuis le début d'une simple fréquence, d'un effet sonore ou d'une musique sur le canal voulu.

  Cette fonction renvoie le temps écoulé depuis le début d'une simple fréquence, d'un effet sonore ou d'une musique sur le canal voulu. Ce temps est donné en secondes. Idéal pour un player. Ce temps peut être initialisé à tout moment grâce à SetTime_voice [1|2]. A savoir que lors de la fin d'un mode, le compteur de temps s'initialise mais continu a être incrémenté.

 

void pSnd_SetTime_voice1 (unsigned short time),
void pSnd_SetTime_voice2 (unsigned short time);
#define pSnd_SetTime (time);

move.w  #60,d0
jsr          polysnd2::SetTime_voice[1|2]

Input:    d0.w = Time
Output:  -
Del:        d0

Change la valeur du compteur de temps écoulé sur le canal voulu.

  Cette fonction change la valeur du compteur permettant de déterminer le temps écoulé d'un morceau de musique… Utile pour ce positionner dans une musique. La valeur spécifiée doit être en secondes.

 

unsigned char pSnd_VoiceState (void) ;

jsr polysnd2 ::VoiceState

Input:    -
Output:  d0.b
Del:        -

Renvoie l'état d'un canal.

  Cette fonction permet de déterminer si un mode a fini de jouer du son… Le bit 0 correspond au canal 1 et le bit 1 au canal 2, si ce bit est armé le mode est en train d'être joué sur le canal correspondant, si le bit est désarmé, PolySnd v2.0 a fini de jouer le mode…

Cette fonction est utile pour synchroniser et répéter en boucle une musique en stéréo.

Ces énumérations sont valables pour tester les canaux :

#define NOVOICE      0
#define VOICE1          1
#define VOICE2          2
#define ALLVOICES  3

_NOVOICE      equ  0
_VOICE1          equ  1
_VOICE2          equ  2
_ALLVOICES  equ  3

Exemple pour jouer une musique en stéréo en boucle sans utiliser la fonction loop :

SetVoiceState (ALLVOICES);

while (_keytest (RR_ESC)==FALSE)
{
  if (pSnd_VoiceState ()==NOVOICE) {pSnd_PlaySound_voice1 (channel1); pSnd_PlaySound_voice2 (channel2); pSnd_SetState (ALLVOICES);}
  ....
}

 

void pSnd_SetVoiceState (unsigned char state);

move.b  #_VOICE1,d0
jsr          polysnd2::SetVoiceState

Input:    d0.b = Voices
Output:  -
Del:        -

Règle VoiceState.

  Attention, cette fonction permet de régler VoiceState en fonction de ses besoins.
La valeur passée par SetVoiceState sera initialisée si une musique est rejouée ou si PolySnd v2.0 a été configuré pour recevoir un autre traitement de données. Utilisez cette fonction à titre de résultats temporaire.
Cette fonction n'est pas identique à GetState, GetState renvoie l'état courant de PolySnd v2.0 et VoiceState l'état courant du mode en cours.

 

void pSnd_SetIntMask (unsigned short mask);

move.w  #$2700,d0
jsr          polysnd2::SetIntMask

Input:    d0.w = mask
Output:  -
Del:        -

Règle le masque d'interruptions de PolySnd v2.0.

  Cette fonction est assez importante si vous avez du mal à utiliser PolySnd v2.0 avec d'autres interruptions et que vous constatez que l'auto Int 1… est ralentie, ce masque permet à PolySnd de désactiver ou ne pas désactiver certaines interruptions lors du passage de l'interruption de PolySnd v2.0. La valeur du masque doit se situer entre 0x2100 et 0x2700. par défaut ce masque est à 0x2400.

 

void pSnd_AddNotes_voice1 (unsigned char nbr) ;
void pSnd_AddNotes_voice2 (unsigned char nbr) ;
#define AddNotes (unsigned char addnts);

move.b  #12,d0
jsr          polysnd2::AddNotes_voice1

Input:    d0.b = AddNote
Output:  -
Del:        -

Permet de jouer un morceau avec un nombre de notes au dessus/ ou en dessous des notes d'origine.

  Dans la fonction en Assembleur toutes les notes de musique seront jouant 12 notes (1 octave) au-dessus de la note originale. Cette fonction est utile pour permettre d'augmenter/ diminuer d'une octave une musique sans devoir la modifier.

 

unsigned char pSnd_GetNote_voice1 (void);
unsigned char pSnd_GetNote_voice2 (void);

jsr polysnd2::GetNote_voice[1|2]

Input:    -
Output:  d0.b
Del:        d0

Renvoie la note en cours d'être jouée.

  La valeur renvoyée correspond à l'index de la note dans la table des fréquences, 0 correspond à la pause, 1 à Do octave 0... Il est assez facile de repérer de cette façon une note avec son octave. La table de PolySnd v2.0 contient 120 notes répartie sur 10 octaves.

 

void *pSnd_Ptridle_voice1 (void *) ;
void *pSnd_Ptridle_voice2 (void *) ;

sub.l     a0,a0
jsr         polysnd2::_Ptridle_voice[1|2]

Input:    a0 = Ptr
Output:  a0
Del:        d0, a0

Renvoie/change le pointeur de données de PlaySound.

  Cette fonction permet de renvoyer le pointeur de données si l'argument spécifié est NULL ou égale à 0 en Assembleur. Si cette argument est différent de NULL ou de 0, le pointeur de données de PlaySound sera modifié. N'oubliez pas d'utiliser la fonction SetSate pour arrêter PolySnd v2.0 lors de votre modification et _SkipData_voice[1|2] pour remettre les valeurs à zéro de la donnée. Vérifiez que votre pointeur est correctement avant de faire toute modifcation, cette fonction peut être sources de plantages plus ou moins sérieux.

 

unsigned long pSnd_time_counter_voice1 (unsigned long counter) ;
unsigned long pSnd_time_counter_voice2 (unsigned long counter) ;

move.l   #5000,d0
jsr         polysnd2::_time_counter_voice[1|2]

Input:    d0.l = Counter
Output:  d0.l
Del:        d0

Renvoie/change le compteur de temps de PolySnd v2.0.

  Cette fonction permet de renvoyer le compteur de temps d'interruptions de PolySnd v2.0 si l'argument spécifié est NULL ou égale à 0 en Assembleur. Si cette argument est différent de NULL ou de 0, le compteur de temps sera modifié. Les incréments de ce compteur dépendent de la fonction SetInterrupt5Rate, par défaut 1 incrément de compteur correspond à 1 seconde. Cette fonction est disponible pour permetter de régler précisement le compteur de temps de chaque voies.

 

unsigned long pSnd_note_time_counter_voice1 (unsigned long counter) ;
unsigned long pSnd_note_time_counter_voice2 (unsigned long counter) ;

move.l  #0,d0
jsr        polysnd2::_note_time_counter_voice[1|2]

Input:    d0.l = Counter
Output:  d0.l
Del:        d0

Renvoie/change le compteur de temps de la note en cours.

  Cette fonction permet de renvoyer le compteur de temps d'interruptions de la note en cours de la fonction PlaySound, si l'argument spécifié est NULL ou égale à 0 en Assembleur. Si cette argument est différent de NULL ou de 0, le compteur de temps de la note sera modifié. Les incréments de ce compteur dépendent de la fonction SetInterrupt5Rate, par défaut 1 incrément de compteur correspond à 1 seconde. Cette fonction permet de savoir combien de cycles d'interruption la note en cours a été jouée.

 

void pSnd_SkipData_voice1 (void) ;
void pSnd_SkipData_voice2 (void) ;

jsr polysnd2::_SkipData_voice[1|2]

Efface les variables de la donné en cours.

  Cette fonctions remet à zéro les compteurs de données interne de PolySnd v2.0.

 

void pSnd_PlayMode (unsigned char mode);

move.b  #_MONO,d0
jsr          polysnd2::PlayMode

Input:    d0.b = PlayMode
Output:  -
Del:        -

Change le mode de lecture de PolySnd v2.0.

  Par défaut PolySnd v2.0 est en mode STEREO, ce mode permet de jouer sur 2 voies des modes différent ou identique. Malheuresement si vous joué une musique en stéréo, la consommation des ressources CPU est assez importante, environ 15%. Mais dans le cas contraire ou vous ne jouez qu'une musique ou que des bruitages sur un canal, vous pouvez utiliser le mode MONO, les fonctions suivit du préfixe voice2 seront ignoré jusqu'à changement du mode. L'avantage du mode MONO est de permettre de jouer des données en MONO sur les 2 canaux et de gagner énormément de ressources, soit une perte de 5% des ressources CPU. Ces valeurs sont indicatif car dépendent du mode utilisé, ici PlaySound et des données. Bien sûr si vous utilisez les fonctions PlayWAV ou encore PlayFX, la consommation CPU sera bien plus faible.

Ces énumération sont valables pour cette fonction:

#define MONO     0
#define STEREO  1

_MONO     equ  0
_STEREO  equ  1

 

void pSnd_SetLength_voice1 (unsigned char length);
void pSnd_SetLength_voice1 (unsigned char length);

move.b  #20,d0
jsr          polysnd2::SetLength_voice[1|2]

Input:    d0.b = length
Output:  -
Del:        -

Régle la durée de la note en cours.

  Cette fonction permet de régler le temps de la note en train d'être jouée.

 

void pSnd_SetInterrupt5Rate (unsigned short freq);

move.w  #500,d0
jsr          polysnd2::Setinterrupt5Rate

Input:    d0.w = Frequence
Output:  -
Del:        d0, d1, a0

Régle la fréquence de linterruption personnalisé de PolySnd (fonction Interrupt5).

  Cette fonction permet de changer la fréquence de la fonction Interrupt5, par défaut celle-ci est à 1 Hz mais il est possible de monter jusq'à 11569 Hz sur HW et 8192 Hz sur HW2, plus la fréquence de l'interruption Interrupt5 de PolySnd v2.0 est élevé plus la consommation CPU augmente.

Les fonctions de temps dépendent de la fréquence de cette interruption.

 

Fonctions numériques, PolySnd v2.0 est capable de jouer du son qualitée 1 bits à un taux d'échantillionage à 8000 Hz en numérique. Ce mode à été développé pour permettre de jouer des bruitages réaliste dans des jeux, comme bruits de pas, voies...

void pSnd_PlayWAV_voice1 (unsigned char *wav,unsigned short size);
void pSnd_PlayWAV_voice2 (unsigned char *wav,unsigned short size);
#define pSnd_PlayWAV (unsigned char *wav,unsigned short size);

lea         sound_wav(PC),a0
move.w  #fin_sound-sound_wav,d0
jsr          polysnd2::PlayWAV_voice[1|2]

sound_wav :
dc.b  50,85,124,158,25…

fin_sound :

Input:    a0 = PtrData
              d0.w = Size
Output:  -
Del:        -

Voici un exemple d'utilisation de PlayWAV en C :

INT_HANDLER OldInt1 = NULL;
INT_HANDLER OldInt2 = NULL;

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

unsigned char sound_wav[]={50,85,124,158,25…};

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_PlayMode (MONO);

  pSnd_Sample_voice1 (8192);
  pSnd_PlayWAV_voice1 (sound_wav,sizeof (sound_wav));

  pSnd_SetState (ALLVOICES);

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

  pSnd_UninstallSound ();
  pSnd_DisableSound ();

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

Permet de jouer des données WAV en qualité 1 bit à 8000 Hz.

  Il est possible de jouer du WAV (son numérique) avec PolySnd v2.0. Dans cette exemple 8192 bits sont lus par secondes (1024 octets/s), il est possible de diminuer la taille des données au détriment de la qualité en changeant le taux d'échantillonnage (voir Sample_voice[1|2]).
Il a était souhaitable d'utiliser une qualité 1 bit pour PolySnd v2.0 car les testes effectué avec des qualité supérieure jusqu'à 8 bits n'était pas satisfaisante en taille mémoire.

 

void pSnd_Sample_voice1 (unsigned short);
void pSnd_Sample_voice2 (unsigned short);
#define pSnd_Samples (sample);

move.w  #4000,d0
jsr          polysnd2::Sample_vioice[1|2]

Input:    d0.w = sample
Output:  -
Del:        -

Régle le taux d'échantillionage.

  Cette fonction permet de diminuer ou augmenter la vitesse de lecture des données et ainsi permettre de diminuer la taille des fichiers. Dans l'exemple en Assembleur le taux d'échantillonnage est de 4000 Hz. PolySnd v2.0 est capable d'aller jusqu'à 8192 Hz. Les données WAV ne peuvent être produite que par le logiciel Converti fournis dans un autre pack.

 

USE_GRAY_WITH_POLYSND

  Cette définition ne peut être utilisée en C que sous TIGCC, elle a pour but de faire fonctionner correctement PolySnd v2.0 avec les niveaux de gris de TIGCC.
Cette définition doit se situer juste avant GrayOn ().
Il n'est pas assuré que cette définition fonctionne dans les futurs versions de TIGCC dans ce cas vous devez savoir que la routine de gestion des niveaux de gris ne doit pas désactiver l'auto Int 5 lors de son passage, si ce n'est pas le cas vous constaterez un ralentissement et un son assez grave de PolySnd v2.0, ou tout autre comportements bizarre, c'est pour ça qu'il faut configurer correctement les masques d'interruptions des interruptions que vous utilisez.

 

8. Points sur la consommation de ressources avec PolySnd v2.0.

  Suivant les différent mode de lecture de données, les données elle-même ou encore la configuration de PolySnd v2.0 (Mono ou stéréo), la consommation de ressources CPU est variable et peut être élevée ou très très faible. Si vous jouez une musique en mode stéréo sur 2 voies qui comporte un tempo assez élevé et des durées de notes assez faible, la consommation CPU peut monter jusqu'à 15% avec seulement PolySnd v2.0. Si vous jouez en mode MONO une musique vous perderez environ 5% des ressources CPU au maximum. Suivant le mode vous pouvez perdre seulement 2% des ressources ou bien plus, par conséquent il n'est pas assuré que dans un programme PolySnd v2.0 ralentisse plus ou moins celui-ci. C'est pourquoi vous devez bien réfléchir à l'incorporation du son dans votre programme ou jeu et éviter au maximum de jouer des musiques sur 2 voies directement dans un jeu demandant beaucoup de ressources CPU. Prévilégiez plutôt des musiques sur 2 voies dans des menus...

 

9. Utiliser PolySnd v2.0 avec Genlib.

  Pour utiliser correctement Genlib avec PolySnd v2.0 vous devez tout d'abord initialiser la librairie Genlib puis intercepter l'interruption n°5 de Genlib grâce à l'adresse 0x74. Une fois cette opération effectué il vous reste à initialiser PolySnd v2.0, créer une interruption avec la fonction Interrupt5 de PolySnd v2.0, dans cette interruption executer l'interruption de Genlib.

Attention: L'interruption de PolySnd v2.0 tourne à 5000 Hz et celle de Genlib à 90 Hz, par conséquent vous devez créer une fonction dans l'interruption de PolySnd v2.0 capable d'executer tout les 90 Hz l'interruption de Genlib.

En ASM:

jsr        genlib::init                          ;Initialise Genlib
move.l  $74,GenlibInt                   ;Sauvegarde l'auto int n°5 de Genlib dans GenlibInt
jsr        polysnd2::EnableSound    ;Initialise le Port I/O
jsr        polysnd2::InstallSound      ;Initialise PolySnd, attention: N'oublier pas à la fin de restaurer PolySnd et Genlib

lea       myint5(PC),a0                 ;Interruption de PolySnd v2.0
jsr        polysnd2::Interrupt5
... ;votre code
rts

myint5:
addi.l  #590,counter                      ;90/5000*32768
cmpi   #32473,counter                  ;32768-590/2
ble      execute_genblib_interrupt   ;Si 32473 est plus petit ou égale à counter alors executer interruption de genlib
rte                                                ;Fin de l'interruption de PolySnd

execute_genlib_interrupt:
subi      #32768,counter                :Soustrait 32768 à counter
move.l GenlibInt(PC),-(a7)           ;Execute interruption de Genlib
rts

En C:

INT_HANDLER GenlibInt = NULL;
volatile unsigned long counter=0


//5000 Hz
DEFINE_INT_HANDLER (myint5)
{
  counter+=590; //90/5000*32768
   
  if (counter>32473) //32768-590/2
  {
    counter-=32768;
    ExecuteHandler(GenlibInt);
  }
}

void _main (void)
{
 counter=0;

 gl_init ();
 GenlibInt=GetIntVec(AUTO_INT_5);
 pSnd_EnableSound ();
 pSnd_InstallSound ();
 pSnd_Interrupt5(myint5);
 ...
 //Votre code
}

N'oubliez pas de restaurer correctement Genlib et PolySnd v2.0 ainsi que de désactiver au début les auto int n°1 et 2 pour PolySnd v2.0.

 

10. Tableau des durées.

  PolySnd v2.0 est capable de jouer n'importe quelle note sur 10 octaves, les octaves sont notées de 0 à 9. La liste des notes et des durées n'est pas exhaustive, il est possible de la compléter selon vos critères.

Une note est précédée d'un tiret puis suivie du nom de la note, puis son type (bémol ou dièse) et enfin le numéro de l'octave. Pour un DO dièse d'octave 5 vous noterez : _dod4.

Une pause sera notée pause ou 0.

Voici le tableau des durées, la référence de PolySnd v2.0 est la noire avec une durée de 32 cycles de tempo. 32 cycles est équivalents à 1 temps.

Type
Syntaxe
Durée
Ronde ronde 4 temps
Blanche Blanche 2 temps
Blanche pointée blanche_pointee 2+ 1/2 temps
Noire pointée noire_pointee 1+1/2 temps
Noire noire 1 temps
Croche pointée croche_pointee 1/2+1/4 temps
Croche croche 1/2 temps
Double croche double_croche 1/4 temps
Triple croche triple_croche 1/8 temps
Quadruple croche quadruple_croche 1/16 temps
Soupir soupir 1 temps
Soupir pointé soupir_pointe 1+1/2 temps

Il existe des abréviations, regardez le fichier polysnd2.h.

 

11. Améliorer la qualité du son.

  Il est possible d'améliorer la qualité du son en fabriquant un passe bas sur chaque voie. Vous devez posséder 2 condensateurs de 47 pF et 2 résistances de 470 kohms

Ce passe bas a pour but de transformer les ondes sous forme de créneaux en ondes sinusoïdales.

 

12. Me contacter.

  N'hésitez pas à me contacter pour toutes suggestions, critiques, rapport de bugs ou tout simplement m'envoyer vos créations musicales ou tout autre programme utilisant PolySnd v2.0. geoffrey.anneheim@wanadoo.fr

 

Remerciements :

Florian Drevet pour son superbe Zguide qui m'a permis d'apprendre l'assembleur très facilement

Xavier Vassor, Julien Muchembled, Zeljko Juric, Kevin Kofler, Sebastian Reichelt, Jean Canazzi, Niklas Brunlid, Philipp Winkler pour le compilateur TIGCC SDK et le fichier d'aide très complet. Tout particulièrement Kevin Kofler qui m'a aidé dans la réalisation de cette librairie.

Vertyos alias bob64, Kevin Kofler, MacInToc, EvaSDK, jackiechan, nEUrOne, Uther Lightbringer, Squale92, BiHi, XDanger, Ximoon, fabedal, Nil, ExtendeD, Godzil, squalyl et Brunni pour leurs aides, critiques et suggestions. N'hésitez pas à faire un tours sur : yAronet.com

Grand merci à Jérémie Luissiez (Vil) et Paul Froissart (Pollux) pour la routine de wave2asm.

MasterSam pour son exemple Only For You. (Un bonne exemple pour PolySnd Player).
Son site WEB : http://perso.wanadoo.fr/mastersam.rc

Raphael Domenge pour avoir contribué à PolySnd v2.0.

Brunni l'auteur de converti pour PolySnd et bien faiteur de nombreuses améliorations...

PolySnd v2.0 a été testé et développé sur une TI-92 plus, HW2 ROM: 2.05 et 2.08. Elle a été testé sur AMS 2.05, 2.08 et 2.09 ainsi que sur Pedrom v0.76. Grand merci à Patrick Pelissier (PpHd).

Merci à Malcolm Smith (TRgenius) pour l'exemple Avoid et pour son aide.

Et je n'oublie pas Iros, sans lui je n'aurais pas plus adapter PolySnd pour les HW1.

Je n'oublie pas aussi bien d'autres personnes qui m'ont aidés à réaliser cette librairie ainsi que mes bêtas testeurs. ;o)


Logiciels et outils pour PolySnd v2.0 :

PolySnd MIDI Converter: Convertisseur MIDI en format PolySnd v2.0, il permet d'obtenir des données en C, ASM ou pour PolySnd Player.

PolySnd Converti : Convertisseur WAV en données 1 bit pour PolySnd v2.0, il permet de convertir un WAV en C ou en ASM.

PolySnd Player : Joueur de musiques, les musiques prennent peu de place. Il est capable de renvoyer une multitude d'informations sur la musique en cours.

 

Peut être que j'aurais le temps de développer ses outils.

'PolySnd Kit Programmer Basic' : Réalisez vos compositions en TI-BASIC.

'PolySnd Partition Editor': Réalisez vos musiques notes à notes avec cette éditeurs.


Reste plus qu'à vous faire des programmes avec PolySnd v2.0… :o)

Visitez http://www.ticalc.org pour trouvez ses logiciels, kernel…
Visitez mon site dédié au TI68K et à mes projets : TISofts

Me contacter: Geoffrey ANNEHEIM

PolySnd v2.0 est sous le label d'OrageStudio. N'hésitez pas à y faire un tour.

 

Copyright 2003 by Geoffrey ANNEHEIM