π
<-
Chat plein-écran
[^]

News 2024

News 2023
Août (2)
Juin (3)
Mai (4)
Avril (1)

News 2022
Août (3)
Juin (1)
Mai (1)
Mars (2)

News 2021
Août (12)
Juin (2)
Mai (7)
Avril (3)
Mars (1)

News 2020
Août (15)
Juin (7)
Mai (7)
Avril (19)
Mars (4)

News 2019
Août (4)
Juin (6)
Mai (1)
Avril (3)
Mars (1)

News 2018
Août (11)
Juin (3)
Mai (10)
Avril (2)
Mars (4)

News 2017
Août (15)
Juillet (18)
Juin (1)
Mai (7)
Avril (4)
Mars (7)

News 2016
Août (17)
Juillet (16)
Juin (2)
Mai (2)
Avril (1)
Mars (5)

News 2015
Août (25)
Juin (4)
Mai (9)
Avril (4)
Mars (10)

News 2014
Août (4)
Juin (11)
Mai (12)
Avril (9)
Mars (12)
Janvier (13)

News 2013
Octobre (11)
Août (5)
Juin (9)
Mai (12)
Avril (10)
Mars (7)
Janvier (10)

News 2012
Août (12)
Juillet (10)
Juin (13)
Mai (22)
Avril (8)
Mars (5)

News 2011
Octobre (23)
Août (1)
Juin (29)
Mai (11)
Avril (5)
Mars (3)

News 2010
Août (2)
Juin (5)

News 2009
Août (1)
Juin (1)
Mai (1)
Avril (1)
Mars (1)

Offre TI aide équipement établissements - rentrée 2021

Nouveau messagede critor » 05 Mai 2021, 12:03

Enseignant ? Texas Instruments lance son offre d'aide à l'équipement pour la rentrée 2021, à l'attention des collèges et lycées de France métropolitaine, DOM, et AEFE.

Pour en bénéficier, il suffit que ton établissement scolaire recommande l'achat de calculatrices Texas Instruments ou organise un achat groupé de calculatrices Texas Instruments, et ce de façon exclusive aux promotions d'élèves entrantes (c'est-à-dire pour l'ensemble des classes de Sixième, des classes de Seconde ou Première selon la politique du lycée, et des classes de première année de BTS ou CPGE).

Tu as jusqu'au 30 novembre 2021 inclus pour remplir le formulaire de participation et joindre ton justificatif.

Le justificatif pourra être au choix la liste de fournitures scolaires et/ou lettre de rentrée à l'attention des familles, ou encore la facture d'achat groupé, le tout bien évidemment visé conforme par le chef d'établissement.

Devra donc y figurer au choix la mention de calculatrice(s) Texas Instruments, et à l'exclusion bien sûr de toute marque de calculatrices concurrente. :#non#:

11506Mais dans le cadre d'un achat groupé cela ne devrait pas être bien difficile, aucune obligation donc d'engager l'ensemble de tes collègues du lycée cette année ! :bj:

En récompense de cette fidélité, tu pourras recevoir 1 produit gratuit au choix et ce pour chaque tranche de 30 élèves concernés ! :bj:
Cette année tu as l'embarras du choix avec pas mal de nouveautés et exclusivités : :D
  • 1 calculatrice graphique formelle TI-Nspire™ CX II-T CAS
  • 1 calculatrice graphique exacte TI-Nspire™ CX II-T
  • 1 licence logiciel TI-Nspire™ CX Premium (édition enseignant pour Windows/Mac)
    11325
  • 1 calculatrice graphique semi-exacte (QPiRac) TI-83 Premium CE Edition Python
  • 1 calculatrice graphique semi-exacte (QPiRac) TI-82 Advanced Edition Python
  • 1 licence logiciel TI-SmartView™ CE (émulateur de TI-83 Premium CE Edition Python à installer sur Windows/Mac)
  • 1 clé USB TI-SmartView™ CE 5.5 (émulateur permanent TI-83 Premium CE Edition Python utilisable sous Windows/Mac sans installation ni licence - si tu disposes déjà d'une de ces clés USB dans une ancienne version, tu pourras la mettre à jour gratuitement en version 5.5 et es donc libre de choisir autre chose)
    72889049
  • 1 interface TI-Innovator Hub
  • 1 robot TI-Innovator Rover
  • 1 TI-Innovator I/O Module Pack (pack de 1 capteur + 3 actionneurs Grove : capteur de lumière, servomoteur, moteur à vibration, et LED blanche)
    75847588758975907591

    121327512
  • 1 sonar (capteur de distance) + 1 TI-RGB Array (rampe de 16 diodes RGB)
    12502
  • 1 cahier d'activités Python Eyrolles
  • 1 calculatrice scientifique semi-exacte (QPiRac) TI-Collège Plus Solaire
  • 1 licence logiciel TI-SmartView™ (émulateur de TI-Collège Plus Solaire à installer sur Windows/Mac)
Du matériel qui pourra donc être conservé de façon mutualisée pour être utilisé par les enseignants, prêté ponctuellement à des élèves ayant cassé/perdu leur machine, des élèves dans le besoin ou encore pour des projets d'élèves, donné en récompense à des élèves méritants (s'étant illustrés lors de concours, olympiades, rallyes ou tout simplement dans leur investissement scolaire)... les possibilités ne manquent pas ! :D

Mais quelle générosité, merci Texas Instruments ! :favorite:

Lien : https://education.ti.com/fr/enseignants ... r-programs
Lien vers le sujet sur le forum: Offre TI aide équipement établissements - rentrée 2021 (Commentaires: 0)

Jeu-concours enseignants Calcuso & TI avec 5000€ de lots !

Nouveau messagede critor » 10 Mai 2021, 13:36

Jusqu'au 10 juin 2021 inclus, Calcuso, distributeur scolaire de calculatrices et accessoires Casio, Hewlett Packard, NumWorks, Sharp et Texas Instruments, organise un grand jeu concours.

La participation est ouverte à l'ensemble des enseignants en Sciences dans un lycée de France métropolitaine, île de Beauté incluse.

127243 gros lots t'ont été très généreusement constitués en partenariat avec Texas Instruments :
  1. lot classe d'une valeur de 4383€ : 35 calculatrices TI-83 Premium CE Edition Python accompagnées chacune de l'ensemble des accessoires et options qui font la signature de Calcuso :
  2. lot télétravail d'une valeur de 479€ : tablette graphique XP Pen Deco 03 accompagnée ici encore de nombre d'accessoires :
    • webcam Full HD Logitech C922 Pro Stream
    • casque stéréo sans fil Jabra Evolve 65
    • support pour ordinateur Fatorm 10-17"
    • anneau lumineux LAVKOW 16cm
    • microphone Blue Snowball Black iCE
    • enceinte portable KATMAI E7-L
    • clef USB Texas Instruments
    • carnet Texas Instruments
    L'idéal pour l’enseignement à distance ; la tablette graphique est un bel outil pour les Mathématiques, notamment pour écrire, corriger ou montrer des formules. De plus, la webcam, le casque stéréo sans fil, l’anneau lumineux, le microphone, le haut-parleur portable et le support pour ton ordinateur feront de toi un expert de la visioconférence ! :D
  3. lot enseignant d'une valeur de 382€ : calculatrice graphique Texas Instruments au choix, accompagnée de :
    • robot pilotable TI-Innovator Rover
    • interface TI-Innovator Hub
    • TI-Innovator Breadboard pack
    • comme ci-dessus, tous les accessoires Calcuso mais correspondant au modèle de calculatrice choisi
    Le meilleur de la technologie Texas Instruments ; l'écosystème TI-Innovator permet d'étendre les fonctionnalités des calculatrices Texas Instruments. De quoi donner une dimension concrète et ludique à la programmation ainsi qu'aux concepts mathématiques, et les rendre accessible à tous dans le cadre de projets STEM ! :D
    9049129127592

Pour participer et tenter de gagner c'est très simple, il te suffit de remplir le formulaire lié ci-dessous d'ici le 10 juin 2021 avant minuit, avec :
  • tes informations professionnelles
  • le gros lot que tu souhaites gagner, car oui c'est toi qui choisis ;)
Et pas de perdant, tu gagnes directement 25% de réduction sur l'intégralité du catalogue Calcuso ! :bj:

Lien de participation : https://docs.google.com/forms/d/e/1FAIp ... w/viewform
Lien vers le sujet sur le forum: Jeu-concours enseignants Calcuso & TI avec 5000€ de lots ! (Commentaires: 15)

img2calc: conversion image → Python toutes calculatrices

Nouveau messagede critor » 18 Mai 2021, 11:13

Dans une série d'articles précédents nous te présentions img2calc, notre service en ligne gratuit sur TI-Planet te permettant de convertir tes images pour ta calculatrice.

Étaient donc gérés de nombreux formats d'images pour tes programmes Basic :
  • .8ca ou .8ci pour TI-83 Premium CE et TI-84 Plus CE
  • .8xi, .83i, .82i, .73i, .85i ou .86i pour les TI-83 Plus (compatible TI-84 Plus et TI-82 Plus), TI-83 (compatible TI-82 Stats et TI-76.fr), TI-82, TI-73, TI-85 et TI-86
  • .c2p pour Casio fx-CP400 et fx-CG500
  • .g3p pour Casio Graph 90+E et fx-CG50/20/10

Était également géré le cas très particulier du format IM8C.8xv spécifique aux scripts Python TI-83 Premium CE et TI-84 Plus CE.

Si tu programmais en Python sur une machine autre qu'une TI-83 Premium CE et TI-84 Plus CE, jusqu'à présent img2calc n'était donc pas en mesure de t'aider à incorporer des images. :'(

Pas possible donc de te lancer dans des projets Python graphiques ambitieux sans te taper au préalable toute l'étude du codage et de la compression d'images.

13917Sur TI-Planet il y a de grands jours et de très grands jours... ;)

Voici aujourd'hui une mise à jour majeure de img2calc te permettant de convertir les images de ton choix pour tes scripts Python sur calculatrices, et cette fois-ci pour l'ensemble des modèles ! :bj:

Un nouveau sélecteur Mode t'est proposé à cette fin en haut de la page de l'outil, permettant donc au choix de générer :
  • comme jusqu'à présent une ressource image à appeler par un programme Basic ou Python
  • ou maintenant directement du code Python à incorporer dans tes scripts

En cliquant donc sur ce dernier onglet tu obtiens le bel éventail de bibliothèques Python de tracé par pixels supportées : :D
  • ti_draw (TI-Nspire CX II)
  • graphic (TI-Nspire CX II avec KhiCAS, TI-Nspire CX avec KhiCAS et NumWorks avec KhiCAS)
  • nsp (TI-Nspire avec Micropython)
  • ti_graphics (TI-83 Premium CE et TI-84 Plus CE éditions Python)
  • casioplot (Casio Graph 90/35+E II, fx-9750/9860GIII et fx-CG50)
  • hpprime (HP Prime)
  • kandinsky (NumWorks)

Le convertisseur te produit un script Python, aussi bien téléchargeable que visualisable en coloration syntaxique sur la page en question, et directement utilisable avec :
  • le codage de ton image
  • une fonction prête à l'emploi permettant d'afficher ton image à la position de ton choix :bj:
  • un exemple d'utilisation
Le codage se veut optimisé en taille afin de permettre sur la plupart des modèles des affichages d'images plein écran, ce qui n'est pas incompatible avec des optimisations en performances bien au contraire comme nous allons voir ! :D

Non non, tu ne rêves pas, quelque soit ton cursus ou ton niveau tu peux dès maintenant obtenir des images directement prêtes à l'emploi pour tes jeux, interfaces ou projets Python sur ta calculatrice ; plus aucune limite à ton imagination ou ta créativité ! :bj:


C'est un travail intensif qui nous a conduits à ce résultat. Nous allons tenter de t'expliciter les différents choix faits pour les scripts générés.





1) Compactage des données image

Go to top

Prenons pour le moment quelque chose de très simple. Supposons donc que tu souhaites afficher l'image 15×15 pixels ci-contre dans un de tes scripts Python.

Un premier codage très naïf dit true color de ton image pourrait alors ressembler à ça :
Code: Tout sélectionner
image = [
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[054,111,159],[255,255,255],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[255,255,255],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,204,062],[255,204,062],[255,255,255],
[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],
[054,111,159],[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],
[054,111,159],[054,111,159],[054,111,159],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],
[255,255,255],[054,111,159],[054,111,159],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,255,255],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,255,255],[255,204,062],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,204,062],[255,255,255],[255,255,255],[255,255,255],[255,255,255],[255,255,255],
]

Il s'agit donc d'une liste des couleurs de pixels, de gauche à droite puis de haut en bas, les couleurs étant codées en triplets de valeurs Rouge-Vert-Bleu, l'implémentation la plus fréquente sur calculatrices.

Ce premier codage est toutefois catastrophique en terme de consommation mémoire.

Commençons par expliciter de quoi l'on parle. Les interpréteurs MicroPython ou similaires qui tournent sur nos calculatrices font appel à différents types de mémoires :
  • La mémoire de stockage, qui contient physiquement tes scripts prêts à l'emploi.
  • La pile (stack) qui référence, à l'exécution, les objets Python créés. Sa capacité limite donc le nombre d'objets Python pouvant coexister simultanément en mémoire.
  • Le tas (heap) qui stocke, à l'exécution, le contenu des objets Python créés. Il limite donc la taille globale utilisée pour les données de ces différents objets.
Voici quelques consommations heap valides pour les plateformes 32 bits que sont à ce jour nos calculatrices :
  • pour un entier : 24 octets de base + 4 octets si non nul + 4 octets pour chaque groupe de 30 bits utilisés au-delà des premiers 31 bits dans sa représentation binaire
  • pour une liste : 56 octets de base + 8 octets par élément + les tailles de chaque élément
Comme tu peux le constater le langage Python a le très gros défaut d'être un énorme consommateur de mémoire heap. Cette mémoire sera très souvent le facteur limitant lors de tes projets Python sur calculatrices, et il faut donc y faire très attention.

Ce premier codage consomme donc
$mathjax$56+15\times 15\times\left(8+56+3\times\left(8+28\right)\right)$mathjax$
soit 38,756 Ko de heap.

Rappelons donc les capacités heap des différentes solutions Python sur calculatrices :
  1. 252,1 Mo : HP Prime G2
  2. 15,6 Mo : HP Prime G1
  3. 2,068 Mo : TI-Nspire CX II
  4. 1,033 Mo : Casio Graph 90+E
  5. 101,262 Ko : Casio Graph 35+E II
  6. 33,582 Ko : NumWorks
  7. 18,354 Ko : TI-83 Premium CE Edition Python
  1. 252,1 Mo : HP Prime G2
  2. 15,6 Mo : HP Prime G1
  3. 4,100 Mo : TI-Nspire CX (Ndless + KhiCAS)
  4. 2,068 Mo : TI-Nspire CX II
  5. 1,033 Mo : Casio Graph 90+E
  6. 101,262 Ko : Casio Graph 35+E II
  7. 98,928 Ko : NumWorks (firmware Omega)
  8. 64,954 Ko : NumWorks N0110 (firmware Delta / Omega + appli KhiCAS)
  9. 33,582 Ko : NumWorks
  10. 25,235 Ko : NumWorks N0110 (firmware Delta)
  11. 18,354 Ko : TI-83 Premium CE Edition Python
  1. 252,1 Mo : HP Prime G2
  2. 15,6 Mo : HP Prime G1
  3. 2,068 Mo : TI-Nspire CX II
  4. 1,033 Mo : Casio Graph 90+E / fx-CG50
  5. 101,262 Ko : Casio Graph 35+E II / fx-9750/9860GIII
  6. 33,582 Ko : NumWorks
  7. 20,839 Ko : TI-83 Premium CE + TI-Python
  8. 18,354 Ko : TI-83 Premium CE Edition Python / TI-84 Plus CE Python Edition
  1. 252,1 Mo : HP Prime G2
  2. 15,6 Mo : HP Prime G1
  3. 4,100 Mo : TI-Nspire CX / CX II (Ndless + KhiCAS CX / KhiCAS CX II)
  4. 2,068 Mo : TI-Nspire CX II
  5. 2,050 Mo : TI-Nspire (Ndless + MicroPython)
  6. 1,033 Mo : Casio Graph 90+E / fx-CG50
  7. 258,766 Ko : Casio Graph 35/75+E / 35/75/95 / fx-9750/9860GII (SH4 - appli CasioPython)
  8. 101,262 Ko : Casio Graph 35+E II / fx-9750/9860GIII
  9. 98,928 Ko : NumWorks (firmware Omega)
  10. 64,954 Ko : NumWorks N0110 (firmware Omega + appli KhiCAS)
  11. 33,582 Ko : NumWorks
  12. 32,648 Ko : Casio Graph 35+E II / 35/75/85/95(SH3) / fx-9750/9860GIII / fx-9750/9860GII(SH3) / fx-9860G (appli CasioPython)
  13. 25,235 Ko : NumWorks N0110 (firmware Delta)
  14. 23,685 Ko : TI-83 Premium CE + TI-Python (firmware tiers)
  15. 20,839 Ko : TI-83 Premium CE + TI-Python
  16. 18,354 Ko : TI-83 Premium CE Edition Python / TI-84 Plus CE Python Edition

Et oui, codée de cette façon cette pauvre image de 15×15 pixels génère déjà une erreur de mémoire à l'exécution sur ta TI-83 Premium CE ou ta NumWorks munie du firmware officiel.

Si l'image n'a pas vocation à être modifiée pendant l'exécution de ton script Python, au lieu d'utiliser des listes on peut penser à utiliser des tuples. Un tuple s'utilise exactement comme une liste, la seule différence étant que son contenu n'est plus altérable après création.

Le tuple a l'avantage d'occuper un peu moins de place en heap qu'une liste :
  • pour une liste : 56 octets de base + 8 octets par élément + les tailles de chaque élément
  • pour un tuple : 40 octets de base + 8 octets par élément + les tailles de chaque élément
Une différence très légère certes, mais loin d'être négligeable lorsque comme ici on a affaire à une liste de listes. ;)

Nouvelle version donc :
Code: Tout sélectionner
image = (
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(054,111,159),(255,255,255),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(255,255,255),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,204,062),(255,204,062),(255,255,255),
(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),
(054,111,159),(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),
(054,111,159),(054,111,159),(054,111,159),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),
(255,255,255),(054,111,159),(054,111,159),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,255,255),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,255,255),(255,204,062),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,204,062),(255,255,255),(255,255,255),(255,255,255),(255,255,255),(255,255,255),
)


Cette fois-ci l'exécution de ce code consomme
$mathjax$40+15\times 15\times\left(8+40+3\times\left(8+28\right)\right)$mathjax$
soit 35,140 Ko de heap, un gain d'environ 9,33%.
Toujours pas suffisant toutefois pour espérer pouvoir afficher cette pauvre icône sur TI-83 Premium CE ou NumWorks...

Mais c'est bête donc de repréciser à chaque fois le tuple de couleur, alors qu'il n'y a ici que 3 couleurs différentes dans notre image, non ? ;)

L'étape d'optimisation suivante est d'externaliser les informations de couleurs dans une palette, ce que l'on appelle une image indexée :
Code: Tout sélectionner
palette = ((255,255,255), (054,111,159), (255,204,062))

image = (
0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,
0,0,0,0,1,0,1,1,1,1,1,0,0,0,0,
0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,
0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,0,2,2,0,
1,1,1,1,1,1,1,1,1,1,0,0,2,2,2,
1,1,1,1,0,0,0,0,0,0,0,2,2,2,2,
1,1,1,0,0,2,2,2,2,2,2,2,2,2,2,
0,1,1,0,2,2,2,2,2,2,2,2,2,2,2,
0,0,0,0,2,2,2,2,2,2,2,2,2,2,0,
0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,
0,0,0,0,2,2,2,2,2,2,2,0,0,0,0,
0,0,0,0,2,2,2,2,2,0,2,0,0,0,0,
0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,
)


Cela n'occupe plus que
$mathjax$40+3\times\left(8+40+3\times\left(8+28\right)\right)+40+15\times 15\times\left(8+28\right)$mathjax$
soit 8,648 Ko de heap. Un formidable gain d'environ 75,39%, notre icône est dès maintenant fonctionnelle sur tous les modèles ! :bj:
Toutefois c'est juste 15×15 pixels, nous t'avons promis des images plein écran, il y a encore du travail à faire... ;)

Une autre optimisation pour améliorer le format serait de regrouper plusieurs nombres entiers en un seul.

En effet, les valeurs sont toutes petites, et nous avons vu que les valeurs entières de 1 jusqu'à 2**30-1 soit 1073741823 occupaient de toutes façons la même taille. Que de place gâchée...

C'est une solution que nous avons déjà expérimentée pour les scripts de notre concours de rentrée 2020, et nous ne souhaitons pas la creuser ici.

Si elle permet des gains significatifs en consommation mémoire, elle complexifie fortement l'accès aux données qui sont alors ici à extraire d'un grand nombre entier par opérations binaires, et cela se fait donc au détriment des performances.

Passons plutôt directement à autre chose, la chaîne de caractères. En voici la consommation heap :
  • pour un tuple : 40 octets de base + 8 octets par élément + les tailles de chaque élément
  • pour une chaîne : 49 octets de base + 1 octet par caractère
À vide la chaîne occupe un peu plus de place en mémoire qu'un tuple, mais elle progresse beaucoup moins en taille au fur et à mesure de l'ajout des éléments.

Voici un codage en ce sens :
Code: Tout sélectionner
palette = ((255,255,255), (054,111,159), (255,204,062))

image = (
"\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x01\x00\x01\x01\x01\x01\x01\x00\x00\x00\x00"
"\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00"
"\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00"
"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x02\x02\x00"
"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x02\x02\x02"
"\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x02\x02\x02\x02"
"\x01\x01\x01\x00\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02"
"\x00\x01\x01\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02"
"\x00\x00\x00\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x00"
"\x00\x00\x00\x00\x02\x02\x02\x02\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x02\x02\x02\x02\x02\x02\x02\x00\x00\x00\x00"
"\x00\x00\x00\x00\x02\x02\x02\x02\x02\x00\x02\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x02\x02\x02\x02\x02\x00\x00\x00\x00\x00"
)

Une consommation heap ridicule qui n'est maintenant plus que de
$mathjax$40+3\times\left(8+40+3\times\left(8+28\right)\right)+49+15\times 15\times 1$mathjax$
soit 782 octets, un formidable gain d'encore environ 90,96% rien que par rapport au codage précédent ! :#tritop#:

On peut aller encore un tout petit peu plus loin avec un dernier type, bytes.

Les variables de type bytes s'utilisent comme des chaînes, mais à la différence sont optimisées pour le stockage d'octets (la où les chaînes stockent des caractères, et les caractères spéciaux peuvent occuper plusieurs octets).

Voici la différence en heap :
  • pour une chaîne : 49 octets de base + 1 octet par caractère
  • pour un bytes : 33 octets de base + 1 octet par octet

Et voici le codage ainsi modifié, pas bien compliqué :
Code: Tout sélectionner
palette = ((255,255,255), (054,111,159), (255,204,062))

image = (
b"\x00\x00\x00\x00\x00\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x01\x00\x01\x01\x01\x01\x01\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x01\x00\x00\x00\x00"
b"\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00"
b"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x02\x02\x00"
b"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x02\x02\x02"
b"\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x02\x02\x02\x02"
b"\x01\x01\x01\x00\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02"
b"\x00\x01\x01\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02"
b"\x00\x00\x00\x00\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x00"
b"\x00\x00\x00\x00\x02\x02\x02\x02\x00\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x02\x02\x02\x02\x02\x02\x02\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x02\x02\x02\x02\x02\x00\x02\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x02\x02\x02\x02\x02\x00\x00\x00\x00\x00"
)

Une consommation heap qui baisse très légèrement à
$mathjax$40+3\times\left(8+40+3\times\left(8+28\right)\right)+33+15\times 15\times 1$mathjax$
soit 766 octets.

Cela peut paraître négligeable, mais opter pour le type bytes ici adapté sur-mesures à ce que l'on fait devrait également avoir un impact sur les performances. ;)

Et voilà, avec ce dernier codage indexé en bytes et jusqu'à présent sans le moindre effort algorithmique, nous avons économisé 98,02% par rapport au codage initial true color.

img2calc convertit donc tes images sous la forme de bytes accompagnés d'une palette.




2) Compression des données image

Go to top

Nous allons mettre en œuvre maintenant une compression. La compression RLE est justement particulièrement bien adaptée aux images indexées que nous avons ici.

Selon un parcours de l'image de gauche à droite puis de haut en bas, cette compression accompagne chaque indication de couleur du nombre de pixels adjacents qui l'utilisent.

Par exemple avec notre image d'exemple, cela donne :
Code: Tout sélectionner
0(×5) 1(×5) 0(×9)
1(×1) 0(×1) 1(×5) 0(×8)
1(×7) 0(×11)
1(×4) 0(×5)
1(×10) 0(×4)
1(×11) 0(×1) 2(×2) 0(×1)
1(×10) 0(×2) 2(×3)
1(×4) 0(×7) 2(×4)
1(×3) 0(×2) 2(×10)
0(×1) 1(×2) 0(×1) 2(×11)
0(×4) 2(×10) 0(×5)
2(×4) 0(×11)
2(×7) 0(×8)
2(×5) 0(×1) 2(×1) 0(×9)
2(×5) 0(×5)

En prenant chacun de ces 43 blocs de couleur codé sur 2 octets (1 pour la couleur et 1 pour le nombre de pixels concerné) cela nous donnerait ici
$mathjax$40+3\times\left(8+40+3\times\left(8+28\right)\right)+33+43\times 2\times 1$mathjax$
soit plus que 627 octets.

Mais nous allons nous montrer encore un peu plus malins que ça. Nous choisissons le codage suivant permettant de stocker couleurs et longueurs dans le même octet :
  • la couleur codée de façon variable sur 1 à 8 bits selon la taille de la palette, permettant donc un maximum de 256 couleurs différentes
  • le dernier bit si non utilisé pour la couleur afin d'indiquer de prendre en compte l'octet suivant dans le compte des pixels
  • les bits restants (incluant donc éventuellement l'octet suivant) pour indiquer le nombre de pixels adjacents partageant cette même couleur
Comme nous n'avons ici que 3 couleurs, la couleur est codée sur 2 bits, ce qui laisse alors 5 bits pour coder la longueur sur le même octet. Aucun bloc ne dépassant ici les 32 pixels de large, tous les blocs sont ainsi codables sur 1 seul octet ! :bj:

Nous avons donc
$mathjax$40+3\times\left(8+40+3\times\left(8+28\right)\right)+33+43\times 1\times 1$mathjax$
soit 584 octets, un gain final de 98,49% par rapport au codage initial ! :bj:

Un gros avantage niveau performances de la compression par blocs RLE est justement que cela amène naturellement à allumer les lignes de pixels ainsi décrites via des appels fill_rect(), beaucoup plus rapides que des boucles d'appels de set_pixel().

Bien évidemment à condition qu'une fonction fill_rect() soit fournie par la bibliothèque graphique concernée. C'est le cas de presque toutes les bibliothèques, seule casioplot fait hélas exception à ce jour.

Cela ne nous servira pas pour des images de fond d'écran aujourd'hui, mais nous nous réservons également le droit d'avoir 1 couleur transparente dans la palette. Cela pourrait être utile pour l'affichage de certains sprites dans tes jeux. ;)

Voici la fonction de tracé d'image codée en ce sens :
Code: Tout sélectionner
#the image drawing function
#- rle : image RLE-compressed data
#- w : width of image
#- pal : palette of colors to use with image
#- itransp : index of 1 transparent color in palette or -1 if none
def draw_image(rle, x0, y0, w, pal, itransp=-1):
  i, x = 0, 0
  x0, y0 = int(x0), int(y0)
  nvals = len(pal)
  nbits = 0
  nvals -= 1
  while(nvals):
    nvals >>= 1
    nbits += 1
  maskval = (1 << nbits) - 1
  maskcnt = (0xFF >> nbits >> 1) << nbits
  while i<len(rle):
    v = rle[i]
    mv = v & maskval
    c = (v & maskcnt) >> nbits
    if (v & 0b10000000 or nbits == 8):
      i += 1
      c |= rle[i] << (7 - nbits + (nbits == 8))
    while c:
      cw = min(c, w - x)
      if mv != itransp:
        set_color(pal[mv])
        fill_rect(x0 + x, y0, cw, 1)
      c -= cw
      x = (x + cw) % w
      y0 += x == 0
    i += 1




3) Bibliothèques de tracé par pixels et caractéristiques

Go to top

Avant d'aller plus loin, détaillons les caractéristiques et capacités des différentes bibliothèques gérées par notre convertisseur, soit :
  • les dimensions de la zone graphique que l'on contrôle
  • le format de paramètre couleur et son affichage
  • les possibilités d'optimisation de l'affichage en double buffering ou multiple buffering
  • la présence d'une fonction fill_rect()
  • et les différentes adaptations que cela nécessite dans la boucle while c: de la fonction draw_image() précédente
C'est parti :
  • ti_graphics / TI-83 Premium CE et TI-84 Plus CE éditions Python :
    320×210 pixels, couleurs (R8,G8,B8) affichées en RGB-565, pas de double buffering, fonction fillRect(x, y, largeur, hauteur)
    Code: Tout sélectionner
    setColor(pal[mv])
    fillRect(x0 + x, y0, cw, 1)
  • ti_draw / TI-Nspire CX II :
    318×212 pixels, couleurs (R8,G8,B8) mais affichées en RGB-565, double buffering optionnel, fonction fill_rect(x, y, largeur, hauteur)
    Code: Tout sélectionner
    set_color(pal[mv])
    fill_rect(x0 + x, y0, cw, 1)
  • hpprime / HP Prime :
    320×240 pixels, couleurs RGB-888, multiple buffering optionnel, fonction fillrect(calque, x, y, largeur, hauteur, couleur_exterieur, couleur_interieur)
    Code: Tout sélectionner
    fillrect(calque, x0 + x, y0, cw, 1, pal[mv], pal[mv])
  • casioplot / Casio Graph 90+E et fx-CG50 :
    384×192 pixels, couleurs (R8,G8,B8) mais affichées en RGB-565, double buffering, fonction fill_rect(x, y, largeur, hauteur)
    Code: Tout sélectionner
    col = pal[mv]
    x1 = x0 + x
    for k in range(cw):
      set_pixel(x1 + k, y0, col)
  • casioplot / Casio Graph 35+E II et fx-9750/9860GIII :
    128×64 pixels, couleurs (R8,G8,B8) mais affichées en noir et blanc, fonction fill_rect(x, y, largeur, hauteur), double buffering
    Code: Tout sélectionner
    col = pal[mv]
    x1 = x0 + x
    for k in range(cw):
      set_pixel(x1 + k, y0, col)
  • kandinsky / NumWorks :
    320×222 pixels, couleurs (R8,G8,B8) affichées en RGB-565, pas de double buffering, fonction fill_rect(x, y, largeur, hauteur, couleur)
    Code: Tout sélectionner
    fill_rect(x0 + x, y0, cw, 1, pal[mv])
  • graphic / TI-Nspire CX II + KhiCAS, TI-Nspire CX + KhiCAS et NumWorks + KhiCAS :
    320×222 pixels, couleurs (R8,G8,B8) affichées en RGB-565, pas de double buffering, fonction draw_filled_rectangle(x, y, largeur, hauteur, couleur)
    Code: Tout sélectionner
    fill_rect(x0 + x, y0, cw, 1, pal[mv])
  • nsp / TI-Nspire CX + Micropython :
    320×240 pixels, couleurs RGB-565, multiple buffering, pas de fonction fill_rect()
    Code: Tout sélectionner
    col = pal[mv]
    x1 = x0 + x
    for k in range(cw):
      calque.setPx(x1 + k, y0, col)
  • nsp / TI-Nspire + Micropython :
    320×240 pixels, couleurs RGB-565 mais affichées en noir et blanc, multiple buffering, pas de fonction fill_rect()
    Code: Tout sélectionner
    col = pal[mv]
    x1 = x0 + x
    for k in range(cw):
      calque.setPx(x1 + k, y0, col)




4) Tailles et performances

Go to top

Afin de mieux illustrer les gains, changeons d'image d'exemple. Nous t'avions donc promis des affichages plein écran dignes de jeux vidéo, en voici justement une. ;)

Notre image dépasse ici les 256 couleurs, et seules 256 couleurs seront donc conservées pour la palette par l'outil de conversion. La compression utilisera donc ici 8 bits pour le codage de la couleur, et donc systématiquement 2 octets par bloc.

13912C'est donc parti avec la TI-Nspire CX II et sa bibliothèque ti_draw gérant 318×212 pixels.

La variable image occupe 110,217 Ko en mémoire, un jeu d'enfant pour les 2,068 Mo de heap de cette machine ! :bj:

Voici le prototype du script généré :
Code: Tout sélectionner
from ti_draw import fill_rect, set_color

def draw_image(rle, x0, y0, w, pal, itransp=-1):
  ...

palette = ( ... )
image = ( ... )

#image drawing code sample
from ti_draw import use_buffer, paint_buffer
use_buffer()
draw_image(image, 0, 0, 318, palette, -1)
paint_buffer()

Le code d'exemple fourni active ici le double buffering à des fins de rapidité en encadrant ces appels graphiques d'appels use_buffer() et paint_buffer(), te permettant cet affichage plein écran en 1min 13s selon la mesure du module time.

Pour référence si l'on n'utilise pas ces appels, le même affichage prend 3min 19,72s. Le double buffering semble donc ici permettre une accélération d'un facteur d'environ 2,75.
Dans les deux cas c'est très décevant mais pas forcément surprenant, les bibliothèques fournies par TI étant rarement connues pour leur optimisation en performances.

Une autre piste serait d'exploiter la bibliothèque dédiée propriétaire ti_image, mais cela nécessiterait la gestion du format de fichier .tns ce qui n'est pas chose aisée. Donc pour l'instant, convertir des images pour une utilisation avec ti_image n'est possible qu'avec le logiciel TI-Nspire CX payant.

13919La bibliothèque casioplot des Casio Graph 90+E et fx-CG50 gère pour sa part 384×192 pixels.

Avec la variable image qui occupe 118,199 Ko en mémoire, ici encore c'est facile comme bonjour pour les 1,033 Mo de heap de la calculatrice ! :bj:

Voici un schéma du code :
Code: Tout sélectionner
from casioplot import set_pixel

def draw_image(rle, x0, y0, w, pal, itransp=-1):
  ...

palette = ( ... )
image = ( ... )

#image drawing code sample
from casioplot import show_screen
draw_image(image, 0, 0, 384, palette, -1)
show_screen()

Précisons que le convertisseur prend la peine ici de ne pas mettre plus de 256 caractères par ligne, l'interface de la calculatrice refusant d'ouvrir les scripts avec des lignes plus longues (mais acceptant quand même de les exécuter).

Cela ne suffit toutefois pas à rendre le code visualisable sur calculatrice puisqu'il y a une autre limite allègrement dépassée avec l'image choisie ici, l'interface refuse également d'ouvrir les scripts dépassant les 300 lignes.

Ici pas d'appels fill_rect() puisque n'existant pas, mais des boucles de set_pixel().
Ce lourd handicap n'empêche pas la Casio Graph 90+E d'écraser complètement les TI-Nspire CX II avec ici un affichage en seulement 18s environ ! :bj:
(mesuré approximativement au chronomètre, le module time étant ici absent)

13918Restons chez Casio avec maintenant les Graph 35+E II, fx-9750GIII et fx-9860GIII. Même bibliothèque casioplot mais ici limitée à 128×64 pixels.

Toutefois l'écran étant ici monochrome, le convertisseur limite la palette à 2 couleurs (l'implémentation Python de Casio ne gérant de toutes façons pas les niveaux de gris). Ceci permet le codage RLE des couleurs sur seulement 1 bit et ainsi une compression fantastique, la variable image n'occupant que 593 octets ! Avec 101,262 Ko de heap, tu as même largement ici de quoi animer ton fond d'écran ! :bj:

Le script ne risquant pas de dépasser les 300 lignes avec une variable image aussi petite, le code est cette fois-ci visualisable et éditable directement depuis la calculatrice. :bj:

Code: Tout sélectionner
from casioplot import set_pixel

def draw_image(rle, x0, y0, w, pal, itransp=-1):
  ...

palette = ( ... )
image = ( ... )

#image drawing code sample
from casioplot import show_screen
draw_image(image, 0, 0, 128, palette, -1)
show_screen()


L'affichage plein écran est ici encore plus rapide, dans les 1,5s ! :D

13911Passons maintenant à KhiCAS, logiciel intégré de Mathématiques et Sciences installable sur TI-Nspire CX II et TI-Nspire CX. KhiCAS intègre un interpréteur Micropython avec sa propre bibliothèque de tracé par pixels, graphic.

graphic travaille en 320×222 pixels. La variable image occupe ici 115,159 Ko, ce qui en théorie ne cause donc strictement aucun problème aux 4,100 Mo de heap que permet KhiCAS sur ces machines.

Voici un résumé du code généré :
Code: Tout sélectionner
from graphic import fill_rect

def draw_image(rle, x0, y0, w, pal, itransp=-1):
  ...

palette = ( ... )
image = ( ... )

#image drawing code sample
draw_image(image, 0, 0, 320, palette, -1)

Le convertisseur évite ici que des lignes dépassent les 43000 caractères et quelques, sans quoi cela bloque KhiCAS.

Le module time est ici présent mais ne travaille qu'en secondes, estimant donc dans les 3s pour l'affichage.
Cela n'en reste pas moins formidable, révélant ainsi toute la véritable puissance de la machine ! :D

Cela confirme donc au passage que le problème de performances des TI-Nspire CX II vu plus haut venait bien de l'implémentation du module ti_draw officiel comme supposé.

Passons maintenant sur NumWorks avec 2 bibliothèques travaillant toujours en 320×222 pixels :
  • kandinsky, la bibliothèque officielle
  • et graphic, ici encore la bibliothèque de KhiCAS
Toujours 115,159 Ko donc, ce qui ne rentre en aucun cas dans le heap de la machine (98,928 Ko avec le firmware tiers Omega, 64,954 Ko avec KhiCAS, 33,582 Ko avec le firmware officiel).

Pour te tester ça malgré tout, il va donc nous falloir dégrader l'image. Nous pouvons au choix :
  • en réduire les dimensions
  • réduire le nombre de couleurs utilisées, ce qui a un effet direct sur le taux de compression RLE, puisque davantage de pixels adjacents se mettent alors à utiliser la même couleur
T'ayant promis des images plein écran pour des jeux, nous choisissons cette dernière solution.

On pourrait penser qu'il suffirait juste de supprimer quelques couleurs pour que cela marche déjà avec le firmware Omega... Mais non, en fait le heap n'est même pas le facteur limitant ici, il y en a un autre... :#roll#:

En effet, la calculatrice ne dispose dans tous les cas que d'une capacité de mémoire de stockage absolument ridicule face à toute la concurrence, seulement 32 Kio. Avec tous ses codages hexadécimaux sur 4 caractères, notre script les explose très largement.

13915En fait il nous faut ici descendre de 256 à 3 couleurs afin d'obtenir un script occupant moins de 32 Kio en mémoire de stockage. En conséquence la consommation heap de la variable image est ridicule, ici 6,793 Ko.

Voici un abrégé du code généré :
Code: Tout sélectionner
from kandinsky import fill_rect

def draw_image(rle, x0, y0, w, pal, itransp=-1):
  ...

palette = ( ... )
image = ( ... )

#image drawing code sample
draw_image(image, 0, 0, 320, palette, -1)

Code: Tout sélectionner
from graphic import fill_rect

def draw_image(rle, x0, y0, w, pal, itransp=-1):
  ...

palette = ( ... )
image = ( ... )

#image drawing code sample
draw_image(image, 0, 0, 320, palette, -1)

L'affichage prend ici 6,445s, mais la comparaison aux autres modèles n'est pas pertinente puisque le nombre de couleurs réduit implique un nombre de blocs restreint, et donc beaucoup moins d'appels à draw_line() pour remplir l'écran.

Après même si c'est regrettable d'être ainsi bridé pour des images plein écran, la solution img2calc reste librement utilisable pour incorporer des sprites dans tes jeux. ;)

13916Passons à la HP Prime et sa bibliothèque hpprime permettant de contrôler cette fois-ci tous les 320×240 pixels de l'écran.

La variable image occupe ici 122,573 Ko, ce qui n'est qu'une pauvre goutte d'eau dans l'océan des 252,1 Mo de heap de la HP Prime G2. Tu as ici de quoi jouer littéralement des cinématiques dans tes jeux Python ! :bj:

Voici le schéma du code :
Code: Tout sélectionner
from kandinsky import fill_rect

def draw_image(rle, x0, y0, w, pal, itransp=-1):
  ...

palette = ( ... )
image = ( ... )

#image drawing code sample
draw_image(image, 0, 0, 320, palette, -1)

Code: Tout sélectionner
from hpprime import fillrect

def draw_image(layer, rle, x0, y0, w, pal, itransp=-1):
  ...

palette = ( ... )
image = ( ... )

#image drawing code sample
from hpprime import eval
draw_image(0, image, 0, 0, 320, palette, -1)
eval("wait()")


Pas de module time ici, mais le chronomètre donne dans les 1,64s, absolument fantastique ! :bj:

Enfin, terminons avec les éditions Python des TI-83 Premium CE et TI-84 Plus CE.

La bibliothèque ti_graphics permet d'allumer jusqu'à 320×210 pixels.

Encore un problème de taille ici autre que le heap : les scripts Python que l'on transfère à la calculatrice ne peuvent en aucun cas dépasser les 64 Kio.

Mais ce n'est pas tout, car l'application Python refuse systématiquement de se lancer si elle détecte des scripts Python dépassant les 51,2 Ko.

13913C'est une fois ces deux contraintes respectées qu'il faut se préoccuper de la capacité absolument ridicule du heap de la machine, seulement 18,354 Ko.

Donc pas le choix, ici encore il nous faut réduire à 3 couleurs... La variable image occupe alors 6,467 Ko de heap, à rajouter bien sûr à la consommation de la palette ainsi qu'à celle de l'importation du module ti_graphics.

Voici le principe du code :
Code: Tout sélectionner
from ti_graphics import fillRect, setColor

def draw_image(rle, x0, y0, w, pal, itransp=-1):
  ...

palette = ( ... )
image = ( ... )

#image drawing code sample
from ti_system import disp_wait
draw_image(image, 0, 30, 320, palette, -1)
disp_wait()


En plus d'être grand consommateur de heap, l'affichage est ici très lent, 7min 21s mesurées au module time, et encore qu'est-ce que ça aurait été avec 256 couleurs comme sur les autres machines...

13914Dans le cas de ces calculatrices, tu ferais mieux d'opter pour la solution propriétaire dédiée du format IM8C.8xv, également gérée par img2calc.

Cela te permet de sortir les données images de ton script Python, et ainsi de supprimer complètement la barrière du heap.

Et par conséquent plus de problème de taille de script non plus ici, tu peux bénéficier de l'ensemble des 256 couleurs en seulement 0,606s ! :bj:




5) Liens d'accès

Go to top

Pour accéder à img2calc dès maintenant, c'est très simple. Outre une entrée dédiée dans la liste des convertisseurs au menu de TI-Planet, tu as 2 liens directs dont un court :
Lien vers le sujet sur le forum: img2calc: conversion image → Python toutes calculatrices (Commentaires: 17)

img2calc : images Python affichables avec zoom !

Nouveau messagede critor » 26 Mai 2021, 09:56

13917Nous t'avions déjà parlé d'img2calc, notre service universel et gratuit de conversion d'images pour calculatrices.

La semaine dernière, nous rajoutions la gestion des scripts Python à img2calc.

Tu pouvais convertir ton image en un script Python compatible au choix avec l'une des bibliothèques de tracé par pixels offertes par nos calculatrices :
  • ti_draw (TI-Nspire CX II)
  • graphic (TI-Nspire CX II avec KhiCAS, TI-Nspire CX avec KhiCAS et NumWorks avec KhiCAS)
  • nsp (TI-Nspire avec Micropython)
  • ti_graphics (TI-83 Premium CE et TI-84 Plus CE éditions Python)
  • casioplot (Casio Graph 90/35+E II, fx-9750/9860GIII et fx-CG50)
  • hpprime (HP Prime)
  • kandinsky (NumWorks)

Les images obtenues telles qu'inscrites dans les scripts générés sont optimisées en taille. À ce sujet, nous te renvoyons à l'article précédent.

Leur affichage s'effectue via une fonction draw_image(rle, x0, y0, w, pal, itransp=-1) incluse dans les scripts en question, avec :
  • rle : les données image compressées en RLE
  • x0 et y0 : les coordonnées en pixels du coin supérieur gauche où commencer l'affichage de l'image
  • w : la largeur en pixels de l'image
  • pal : la palette de couleurs à utiliser pour l'affichage de l'image
  • itransp : l'index dans la palette d'une éventuelle couleur transparente, ou sinon -1
Sur le genre de tracé que nous effectuons ici, les performances lors de l'affichage via cette fonction dépendent essentiellement du nombre d'appels aux primitives graphiques. Par primitives nous désignons les fonctions directement fournies par les différentes bibliothèques de tracé, exécutant donc non pas du code Python mais du code machine.

Nos images étant compressées en RLE leur affichage s'effectue la plupart du temps à coups d'appels à la primitive fill_rect(x, y, largeur, hauteur) afin de tracer des lignes horizontales, c'est-à-dire des rectangles de 1 pixel de hauteur.
Il n'y a que la bibliothèque casioplot qui ne fournit pas de telle primitive, et pour laquelle on effectue à la place une boucle d'appels à la primitive set_pixel().

13941Puisque les performances dépendent essentiellement du nombre d'appels à fill_rect(), pourquoi se contenter juste de tracer des rectangles de 1 pixel de hauteur ? ;)

Voici déjà aujourd'hui une évolution significative de la fonction draw_image(), avec désormais la gestion des zooms horizontaux et verticaux via 2 paramètres nommés zoomx et zoomy.

Pour cela nous jouons enfin sur le paramètre de hauteur de la primitive fill_rect() :
Code: Tout sélectionner
def draw_image(rle, x0, y0, w, pal, zoomx=1, zoomy=1, itransp=-1):
  i, x = 0, 0
  w *= zoomx
  x0, y0 = int(x0), int(y0)
  nvals = len(pal)
  nbits = 0
  nvals -= 1
  while(nvals):
    nvals >>= 1
    nbits += 1
  maskval = (1 << nbits) - 1
  maskcnt = (0xFF >> nbits >> 1) << nbits
  while i<len(rle):
    v = rle[i]
    mv = v & maskval
    c = (v & maskcnt) >> nbits
    if (v & 0b10000000 or nbits == 8):
      i += 1
      c |= rle[i] << (7 - nbits + (nbits == 8))
    c = (c + 1) * zoomx
    while c:
      cw = min(c, w - x)
      if mv != itransp:
        fill_rect(x0 + x, y0, cw, zoomy, pal[mv])
      c -= cw
      x = (x + cw) % w
      y0 += x == 0 and zoomy
    i += 1


En conséquence, de nouvelles possibilités d'effets spéciaux pour l'affichage de sprites dans tes projets Python ! :bj:

Nous nous proposons de suite de te montrer ce que ça donne avec l'image transparente ci-contre de 64×64 pixels.

Voici les appels draw_image() que nous allons exécuter, de quoi remplir une bonne partie de l'écran : ;)
Code: Tout sélectionner
draw_image(image, 0, 0, 64, palette, zoomx=1, zoomy=1, itransp=0)
draw_image(image, 64, 0, 64, palette, zoomx=2, zoomy=1, itransp=0)
draw_image(image, 0,64, 64, palette, zoomx=1, zoomy=2, itransp=0)
draw_image(image, 64,64, 64, palette, zoomx=2, zoomy=2, itransp=0)
draw_image(image, 192, 0, 64, palette, zoomx=2, zoomy=3, itransp=0)

Pour mesurer de plus les performances, nous engloberons le code précédent d'appels à la bibliothèque time lorsque présente :
Code: Tout sélectionner
from time import monotonic
t0 = monotonic()
...
print(monotonic() - t0)

13934Sur les TI-Nspire CX II, la bibliothèque time intégrée ne fournit pas de méthode monotonic(), mais il suffit d'utiliser la méthode ticks_ms() à la place. Avec la bibliothèque ti_draw, l'affichage prend très exactement 7,23s.
Des performances toujours aussi décevantes, absolument pas au niveau du matériel de cette machine. :mj:

13940Une solution est toutefois de convertir notre image pour la bibliothèque graphic offerte par KhiCAS, le logiciel intégré de Mathématiques et Sciences installable sur TI-Nspire CX II et TI-Nspire CX. Ici la bibliothèque time mesure des performances extraordinaires, de l'ordre de la milliseconde, rendant cette fois-ci justice au matériel. :bj:

Cela confirme en passant que le problème de performances lorsque l'on utilise la bibliothèque ti_draw officielle n'est pas de la faute de notre code.

13936Avec la bibliothèque casioplot de la Casio Graph 90+E, l'affichage prend dans les 2,26s. Mesurées au chronomètre vu que nous n'avons pas ici de bibliothèque time intégrée.
Des performances donc bien meilleures que le modèle précédent. C'est d'autant plus honorable que nous avons ici un matériel inférieur, et même pas de primitive fill_rect(). :bj:

Qu'est-ce que ce serait si Casio consentait à nous rajouter une primitive fill_rect() dans une prochaine mise à jour... ;)

13935
Le script généré pour Graph 90+E est également compatible Graph 35+E II, s'exécutant ici dans les 5,82s.
Mais cela n'affiche ici que des ombres chinoises, l'écran Graph 35+E II étant monochrome.

Et alors imagine si nous avions converti une image disposant d'un fond ni transparent ni blanc, nous n'aurions quasiment obtenu que du noir... :#roll#:

13942
Mais img2calc a également été prévu pour ça. Il te permet de générer un script plus optimal si tu choisis spécifiquement de convertir pour la Graph 35+E II. Dans ce cas tu obtiens une version monochrome bien plus agréable de ton image, de plus indexée selon une palette de seulement 2 couleurs (noir et blanc). Cela permet justement à notre compression RLE d'utiliser 1 seul bit pour coder la couleur, et donc 6 bits pour coder sur le même octet jusqu'à 1+64=65 répétitions de pixels (le 8ème bit étant utilisé pour indiquer d'inclure l'octet suivant dans le codage des répétitions). Avec toutes ces optimisations en plus d'un meilleur affichage et d'une consommation très inférieure de mémoire heap (tas), ici c'est seulement 3,50s ! :bj:

13943Sur NumWorks N0110 avec la bibliothèque kandinsky, l'affichage prend 5,632s mesurées à l'aide de la bibliothèque time.

13944Sur NumWorks N0110 aussi on peut installer KhiCAS. Bien que disposant de sa propre bibliothèque graphic, notons que KhiCAS dispose d'une compatibilité avec kandinsky et que l'on peut donc exécuter directement le même script. Ici le même affichage ne prend plus que 0,524s. :bj:

13937La HP Prime G2 et sa bibliothèque graphique hpprime affichent pour leur part en 0,109s. :bj:

Pas de bibliothèque time pour chronométrer le tracé ici, mais il suffit à la place de faire appel à la fonction TICKS() intégrée au langage HPPPL via hpprime.eval("TICKS()").

13938Enfin, la bibliothèque ti_graphics des TI-83 Premium CE Edition Python, TI-84 Plus CE-T Python Edition et TI-84 Plus CE Python se traîne lamentablement en affichant en 3mins 14,565s, une véritable catastrophe. :mj:

Mais ce n'est pas la faute de notre code, puisque c'est le même que sur tous les modèles précédents, au seul nom d'appel de la primitive graphique près.

Liens img2calc :
Lien vers le sujet sur le forum: img2calc : images Python affichables avec zoom ! (Commentaires: 7)

img2calc: convertis tes images à afficher sur micro:bit

Nouveau messagede critor » 27 Mai 2021, 10:40

13917Nous revenons aujourd'hui sur img2calc, notre service universel de conversion d'images pour calculatrices graphiques.

Depuis peu, img2calc gère la production de scripts Python incluant de quoi afficher l'image convertie sur l'écran de ta calculatrice.

Grande nouveauté aujourd'hui, tu peux maintenant convertir tes images en scripts Python permettant à ta calculatrice de les afficher sur une carte BBC Micro:bit ! :bj:

En effet la BBC Micro:bit dispose d'un afficheur muni de 5×5 LEDs rouges.

Une option disponible pour les modèles gérant cette carte, soit à ce jour les TI-Nspire CX II ainsi que les éditions Python des TI-83 Premium CE et TI-84 Plus CE.

Nous prendrons comme exemple l'image ci-contre faisant déjà 5×5 pixels en niveaux de gris.

img2calc t'offre ici la possibilité de générer ton script pour 2 modules Python différents au choix :
  • soit microbit
  • soit ti_innovator (micro:bit) pour les TI-Nspire CX II ou ti_hub (micro:bit) pour la plateforme CE
La différence est très simple. Les modules microbit sont à installer sur ta calculatrice, liens de téléchargements disponibles en fin d'article. Sans ces modules, le script généré ne fonctionnera pas.

Si par contre tu choisis ti_innovator (micro:bit) ou ti_hub (micro:bit), ici tu n'as rien à installer puisque ces modules sont directement intégrés à la calculatrice ! :bj:
L'astuce mise en œuvre est d'utiliser leur méthode send() afin de définir notre propre fonction permettant d'envoyer directement à la carte micro:bit le code Python que l'on souhaite lui faire exécuter :
Code: Tout sélectionner
def send_microbit(cmd):
  send("\x04")
  send(cmd)
  send("\x05")


L'afficheur de la micro:bit étant constitué de LEDs rouges, lors de la conversion img2calc ne prend ici en compte que les niveaux de gris et les transforme en niveaux de rouge comme illustré ci-contre.

Mais quel format adopter pour l'image au sein du script Python ?

On peut certes imaginer une boucle allumant les diodes une par une à coups d'appels display.set_pixel(x,y,brillance), la brillance étant codée de 0 à 9, ce qui nous laisse toute liberté sur le format de stockage des données de l'image.

Cette méthode a toutefois le défaut d'être lente, puisque concernant ici un afficheur externe. En effet pour 5×5=25 diodes, les délais dus au protocole de communication seront multipliés par 25. Cela donnera de plus un affichage de l'image non pas instantané mais progressif, et pas du meilleur effet, bien embêtant de plus si tu souhaites afficher plusieurs images à la suite pour donner un effet d'animation. :'(

Sachant qu'avec le projet img2calc nous visons en priorité les performances, il nous faut trouver autre chose. Et bien cela tombe bien, car la carte BBC micro:bit gère son propre format d'image :
Code: Tout sélectionner
#your image data
#5x5 10-shades of gray pixels
image = "33445:20005:21006:00006:98877"

1392913930L'image est alors directement affichable sur la micro:bit en lui faisant exécuter d'une façon ou d'une autre display.show(Image(...)) ! :bj:

Tu peux maintenant dessiner absolument tout ce que tu veux, de préférence en niveaux de gris sur 5×5 pixels, et obtenir rapidement le script l'affichant sur ta micro:bit ! :D

Tu restes libre bien sûr de fournir des images couleurs ou plus grandes, elles seront si besoin redimensionnées et passées en niveaux de gris. Mais avec ici sur la micro:bit un afficheur munis de pixels peu nombreux et assez "gros", il vaut mieux garder le contrôle de ce que ça donnera pixel par pixel, en fournissant une image au plus proche du format d'affichage.

Liens img2calc :

Modules micro:bit :
Lien vers le sujet sur le forum: img2calc: convertis tes images à afficher sur micro:bit (Commentaires: 2)

img2calc: convertis tes images à afficher sur TI-RGB Array

Nouveau messagede critor » 28 Mai 2021, 10:54

13917img2calc est notre service universel de conversion d'images pour calculatrices graphiques.

À ce jour selon les cas, il te génère soit des fichiers ou variables à appeler depuis tes programmes Basic ou scripts Python, soit directement des scripts Python intégrant l'image en question.

1392913930Dans ce dernier cas, nous te rajoutions hier la possibilité de convertir des images pour un affichage sur BBC micro:bit.

Autre grande nouveauté aujourd'hui, tu peux maintenant convertir tes images en scripts Python permettant à ta calculatrice de les afficher sur la grille TI-RGB Array ! :bj:

En effet la grille TI-RGB Array dispose de 2×8=16 diodes RGB adressables.

1213012129La grille TI-RGB Array est à connecter à ta calculatrice via l'interface TI-Innovator Hub et son port breadboard.

Une option disponible à ce jour uniquement pour les modèles ayant une gestion en Python du TI-Innovator Hub, soit les TI-Nspire CX II ainsi que les éditions Python des TI-83 Premium CE et TI-84 Plus CE.

Nous prendrons comme exemple l'image ci-contre faisant déjà 2×8 pixels.

Déjà quel format adopter pour l'image au sein du script Python ? Il nous faut tout d'abord voir les instructions dont on dispose.

Pour récupérer un objet dont les méthodes permettent de contrôler le TI-RGB Array, il te faut commencer par le code suivant :
Code: Tout sélectionner
from ti_hub import * # uniquement TI-Nspire CX II
from rgb_arr import * # uniquement TI-83PCE/84+CE

rgbarr = rgb_array()

En pratique contrairement à la BBC micro:bit, le TI-Innovator Hub n'est pas directement pilotable en Python mais dans un langage de script propriétaire. Les différents appels aux bibliothèques Python fournies par TI sur la calculatrice convertissent en fait ce qu'on leur demande en instructions pour le langage de script du TI-Innovator Hub. Par exemple, le code précédent envoie en réalité au TI-Innovator Hub l'instruction CONNECT RGB.

L'objet Python ainsi récupéré offre alors les méthodes suivantes :
  • .set(diode, rouge, vert, bleu) : allume la diode indiquée (n°0 à 15) dans la couleur RGB précisée
  • .set_all(rouge, vert, bleu) : allume les 16 diodes dans la couleur précisée
  • .all_off() : éteint les 16 diodes
  • .pattern(masque) : allume en rouge les diodes correspondant au masque binaire indiqué
Comme nous l'avions vu dans l'article précédent, ici les instructions d'affichage transitent via le port USB de la calculatrice, ce qui génère un certain délai. Afin d'obtenir un affichage d'image aussi instantané que possible et donc pouvoir espérer faire jouer des animations aussi fluides que possible, il nous faut donc minimiser le nombre d'instructions utilisées.

Intéressons-nous donc à la méthode .pattern() qui permet d'allumer plusieurs diodes à la fois. Par exemple .pattern(42) envoie la commande SET RGB PATTERN 42. Comme 42=25+23+21, cela allumera en rouge 3 diodes : les n°1, 3 et 5.

Mais si nous n'avons que du rouge, nous n'irons pas loin... Et bien justement, la dernière mise à jour 1.5 du TI-Innovator Hub a rajouté un paramètre de couleur optionnel à l'instruction PATTERN, sous la forme SET RGB PATTERN masque rouge vert bleu. En fait les bibliothèques Python de TI ne le gèrent pas encore, mais il y a quand même une astuce pour en profiter malgré tout. En effet toutes les méthodes Python acceptent un paramètre supplémentaire non spécifié au menu : un suffixe qui sera concaténé à l'instruction envoyée. Pour envoyer par exemple un SET RGB PATTERN 42 255 0 255, il nous suffit d'appeler .pattern(42, "255 0 255"). ;)

Cette méthode .pattern() aurait pu nous être très utile pour minimiser le nombre d'instructions échangées, notamment dans le contexte d'images indexées : au lieu d'une instruction pour chacune des 16 diodes, nous aurions une seule instruction par couleur de la palette. Mais hélas, nous nous rendons vite compte qu'elle ne convient pas. En effet, elle allume bien maintenant le masque de diodes dans la couleur indiquée, mais elle éteint systématiquement toutes les autres diodes. L'affichage d'une image comportant plusieurs couleurs est donc strictement impossible. :'(


Donc tant pis. En attendant que Texas Instruments nous fournisse de meilleures instructions (ou pas), nous optons pour une boucle appelant la méthode .set() pour allumer au pire chacune des 16 diodes du TI-RGB Array.

Nous choisissons ici comme déjà expliqué de compacter les données Python de l'image sous la forme d'un tableau d'octets (type byte), mais pas de les compresser, le gain d'une compression RLE étant bien faible sur un aussi petit nombre de pixels, sauf à afficher des images ne présentant pas une grande complexité.

Quant au format de ces données, nous choisissons de chaîner des quadruplets d'octets :
  • numéro de diode
  • rouge
  • vert
  • bleu
Ce qui permet entre autres de gérer des images transparentes en ne rafraîchissant pas l'état des diodes non indiquées.

1393113932Et voilà, l'image que tu as choisie s'affiche alors sur le TI-RGB Array ! :bj:

Tu peux maintenant dessiner absolument tout ce que tu veux, de préférence en 2×8 pixels, et obtenir rapidement le script l'affichant sur ton TI-RGB Array ! :D

Tu restes libre bien sûr de fournir des images plus grandes, elles seront si besoin redimensionnées. Mais avec ici sur le TI-RGB Array des pixels peu nombreux et assez "gros", il vaut mieux pour toi garder le contrôle sur ce que ça donnera pixel par pixel, en fournissant une image au plus proche du format d'affichage.

Liens img2calc :
Lien vers le sujet sur le forum: img2calc: convertis tes images à afficher sur TI-RGB Array (Commentaires: 0)

midi2calc: conversion musique → Python pour TI-Innovator Hub

Nouveau messagede critor » 31 Mai 2021, 11:38

729872897757Le TI-Innovator Hub est un périphérique pour tes calculatrices TI-83 Premium CE, TI-84 Plus CE et TI-Nspire CX.

Il est même pilotable en Python sur les derniers modèles TI-Nspire CX II, ainsi que sur les éditions Python des TI-83 Premium CE et TI-84 Plus CE.

Entre bien d'autres choses, il rajoute à ta calculatrice la capacité à produire des sons, grâce à un élément situé dans la base de son boîtier.

1395013949Aujourd'hui est encore un grand jour sur TI-Planet ; nous te lançons midi2calc, un nouveau service en ligne entièrement gratuit permettant d'ouvrir les portes d'une toute nouvelle dimension à ta calculatrice. ;)

Comme son nom l'indique ce nouveau projet que nous t'avons développé avec amour est une nouvelle fois d'un convertisseur : tu lui donnes un fichier de partition de musique au format MIDI, et il te génère automatiquement un script Python permettant à ta calculatrice de jouer la musique en question sur le TI-Innovator Hub ! :D








1) La musique : de la vibration à la partition

Go to top

Mais commençons rapidement par expliquer tout cela. Au tout début, le son est une vibration mécanique. On appelle fréquence le nombre de vibrations par seconde, que l'on exprime en Hertz (symbole Hz). Les fréquences audibles par l'oreille humaine vont en gros de 20 Hz à 20000 Hz.

Bien évidemment, les limites de fréquences audibles varient d'une personne à une autre. Donc laissons de côté ces extrêmes, et prenons comme référence une vibration intermédiaire de 440 Hz. Et bien voilà donc notre première note de musique : le la3 en notation française, ou A4 en notation anglo-allemande.

Le numéro en suffixe indique l'octave. Un octave est un intervalle de fréquences
$mathjax$\left[f_1,f_2\right[$mathjax$
, où
$mathjax$f_2=2\times f_1$mathjax$
. Ce qui nous permet déjà d'encadrer notre note de référence en passant aux octaves supérieurs (plus aigus) ou inférieurs (plus graves) :
  • la8 ou A9 ou A8 : 14080 Hz
  • la7 ou A8 ou A7 : 7040 Hz
  • la6 ou A7 ou A6 : 3520 Hz
  • la5 ou A6 ou A5 : 1760 Hz
  • la4 ou A5 ou A4 : 880 Hz
  • la3 ou A4 ou A3 : 440 Hz
  • la2 ou A3 ou A2 : 220 Hz
  • la1 ou A2 ou A1 : 110 Hz
  • la-1 ou la0 ou A1 ou A0 : 55 Hz
  • la-2 ou la-1 ou A0 ou A-1 : 27,5 Hz
  • la-3 ou la-2 ou A-1 ou A-2 : 13,75 Hz
Comme tu vois, la numérotation des octaves, c'est compliqué... Il existe diverses numérotations différentes de par le monde. Ci-dessus tu as donc :
  • jusqu'à 2 versions de la numérotation latine :
    • l'historique, qui n'a pas d'octave de numéro 0, et passe donc directement de l'octave 1 à l'octave -1
    • et une où l'octave 0 a été rajouté par soucis de logique
  • la numérotation anglo-allemande
  • la numérotation de certains instruments compatibles avec la norme MIDI
Sans une connaissance pointue du contexte dans lequel il est énoncé, un numéro d'octave est donc hautement imprécis. Nous éviterons donc soigneusement de faire appel aux numéros d'octaves dans le code qui va suivre.

Séparons chaque octave en 12 sous-intervalles de même longueur que nous appellerons demi-tons. Pour cela nous avons besoin de 11 notes de musique, que voici :
  • en notation latine : Do, Do# ou Ré♭, , Ré# ou Mi♭, Mi, Fa, Fa# ou Sol♭, Sol, Sol# ou La♭, La, Si
  • en notation anglo-saxonne : C, C# ou D♭, D, D# ou E♭, E, F, F# ou G♭, G, G# ou A♭, A, B
  • en notation germanique : C, C# ou D♭, D, D# ou E♭, E, F, F# ou G♭, G, G# ou A♭, A, H
C'est la gamme chromatique. Le rapport entre les fréquences de 2 notes consécutives dans cette gamme est alors de
$mathjax$\sqrt[12]2$mathjax$
.




2) Codage MIDI d'une partition

Go to top

Maintenant que nous avons les bases, nous pouvons passer aux fichiers MIDI. Il s'agit d'une version informatisée d'une partition de musique. Elle comprend une ou plusieurs pistes de notes, à jouer chacune par un instrument.

Chaque piste comprend donc des notes à jouer. Chaque note à jouer est décrite par plusieurs caractéristiques, dont entre autres 2 qui vont nous intéresser ici :
  • sa hauteur, valeur qui détermine sa fréquence
  • sa durée
Le format MIDI code les hauteurs de notes sur 7 bits, ce qui autorise 27=128 notes différentes :
  • La note de numéro 0 est la plus grave : selon le contexte le do-3 ou do-2 ou C-1 ou C-2.
  • La note de numéro 69 est notre fameux la3 ou A4 ou A3.
  • La note de numéro 127 est la plus aiguë : selon le contexte le sol8 ou G9 ou G8.

Ayant récupéré le numéro n d'une note MIDI à jouer, il nous est donc très facile de calculer sa fréquence :
$mathjax$440\times {\sqrt[12]2}^{n-69}$mathjax$
.




3) De la partition à la mélodie, une affaire de choix

Go to top

Les fichiers MIDI ont donc été conçus pour gérer plusieurs instruments, et comportent pour cela plusieurs pistes. Il ne sera donc pas rare de rencontrer plusieurs notes devant être jouées en même temps.
Or problème ici, nous contrôlons le TI-Innovator Hub qui ne peut se comporter que comme 1 seul instrument. Il lui est ainsi impossible de jouer plusieurs notes à la fois.

Nous t'avons justement conçu sur-mesures une interface permettant de résoudre facilement cette difficulté.

Lorsque tu auras fourni ton fichier MIDI ses différentes pistes seront listées, chacune avec sa description ainsi que son nombre de notes.

Il te suffit alors de désactiver les pistes correspondant aux instruments d'accompagnement, et de ne garder que la ou les pistes des instruments principaux. :)

Mais comment donc distinguer les pistes principales ? Une difficulté est qu'il n'y a pas de règle absolue :
  • Tu peux regarder les descriptions des pistes : le caractère principal ou accompagnant de la piste sera parfois indiqué, mais pas toujours.
  • Tu peux regarder l'ordre des pistes : la ou les pistes principales seront parfois les premières ou les dernières, mais encore une fois pas systématiquement.
  • Tu peux regarder le nombre de notes des pistes : un nombre nettement supérieur à ceux des autres pistes peut être un indice, mais il n'est absolument pas infaillible.

Mais justement, ça aussi nous l'avons prévu. Tu trouveras sous la liste des pistes un bouton de lecture, qui permet de jouer directement dans ton navigateur ta sélection actuelle de pistes, et ce avec un seul instrument histoire de te donner un aperçu aussi fiable que possible de ce que cela donnera une fois passé sur ta calculatrice.

Tu peux donc immédiatement savoir à l'oreille si tu as coché les bonnes pistes ou pas ! :bj:

Tu restes bien sûr libre de conserver plusieurs pistes, et tester l'effet que ça donne. Puisque le cas n'est donc pas à exclure il nous faut faire un choix : en cas de notes devant être jouées en même temps, nous ne conserverons que la plus aiguë sur l'intervalle de temps concerné.

Si les cas où sur un intervalle de temps une note de piste d'accompagnement est plus aiguë qu'une note de piste principale sont rares, cela pourra donner un bon effet, plus de richesse à ta mélodie.

Notons que si tu disposes de plusieurs TI-Innovator Hub, tu peux convertir les pistes séparément et tenter de les jouer simultanément. Nous n'avons toutefois pas testé si cette superposition sonore d'instruments identiques était très harmonieuse.




4) Notre codage Python d'une mélodie

Go to top

Nous souhaitons te permettre de stocker et jouer de longues mélodies Python sur ta calculatrice, et ainsi organiser de véritables concerts pour tes jeux ou projets Python.

Il nous faut minimiser la consommation de mémoire heap. Comme déjà expliqué, nous te proposons un format de données compacté sous forme de tableau d'octets (type bytes). Une note sera codée sur 2 octets :
  • 1 octet avec les bits 0 à 6 (7 bits donc) pour indiquer le numéro de note, et le bit 7 pour indiquer un silence
  • 1 octet pour indiquer la durée




5) Fonctions Python disponibles pour jouer du son sur TI-Innovator Hub

Go to top

Nous en arrivons donc enfin à la question du TI-Innovator Hub. Comment lui faire jouer un son ?

Importons déjà le module nécessaire, directement intégré sur nos calculatrices :
Code: Tout sélectionner
import sound #sur TI-83PCE/84+CE
from ti_hub import sound #sur TI-Nspire CX II


2 méthodes sont alors offertes pour jouer un son :
  • .tone(fréquence, temps), avec la fréquence qui peut aller de 0 à 8000 Hz, et le temps de 0.1 à 100s
  • .note(note, temps) très similaire, où l'on précise juste la note au lieu de la fréquence

Par exemple pour jouer notre la3 ou A4, on peut appeler au choix :
  • sound.tone(440, 1)
  • sound.note("A4", 1)
Nous allons ici utiliser sound.tone() pour plusieurs raisons :
  • le calcul de la fréquence pour sound.tone() est simple et rapide comme vu plus haut, alors que pour sound.note() il faudrait calculer à la fois la note et l'octave
  • pour éviter toute confusion, nous souhaitons éviter l'utilisation du moindre numéro d'octave
  • sound.note() ne joue que des fréquences correspondant à des notes de la gamme, alors que sound.tone() offre bien davantage de libertés pour de futures évolutions
  • avec sound.note() nous n'avons pas trouvé de notation permettant de jouer les notes altérées par un dièse ou bémol, et 5 des 12 notes de la gamme chromatique nous sont donc inaccessibles, ton oreille risquerait de ne pas apprécier les conversions de certains morceaux...
  • sound.note() ne comprend de plus qu'un intervalle de notes restreint allant du C3 au A7 soit seulement 35 notes, très insuffisant pour reproduire fidèlement les 128 notes MIDI
Notons que le TI-Innovator Hub n'est pas très harmonieux dans les fréquences extrêmement graves ou aiguës.
Mais ça aussi nous te l'avons prévu sur l'interface. :D

Une fois ta sélection de pistes effectuée, l'intervalle de notes utilisées t'est indiqué en numérotation MIDI. Tu peux alors décaler tout le morceau de musique vers le haut ou vers le bas d'autant de demi-tons que tu voudras.




6) Notre fonction Python pour jouer une mélodie

Go to top

Et voilà donc notre fonction jouant la musique, ici dans sa version TI-83 Premium CE et TI-84 Plus CE : :D
Code: Tout sélectionner
#the melody playing function
#- mus : melody data
#- durat_bytes : number of bytes encoding each note duration
def play_melody_on_innovator(mus, durat_bytes):
  r = 2 ** (1 / 12)
  t2, durat, i = monotonic(), 0, 0
  t1 = t2
  while i < len(mus):
    t1, t2 = t2, monotonic()
    deltat = max(0, (t2 - t1) / 1000 - durat)
    note = mus[i]
    i += note < 0x80
    durat = mus[i] & ((note ^ 0x80) | 0x7F)
    i += 1
    if durat_bytes > 1:
      durat |= int.from_bytes(mus[i:i + durat_bytes - 1],'little') << (8 - (note >= 0x80))
      i += durat_bytes - 1
    durat = max(1, durat) / 10
    sound.tone((note < 0x80) and 440 * r**(note - 69), durat)
    sleep(max(0, durat - deltat))

Chaque appel sound.tone(note, durée) est ici suivi d'un appel time.sleep(durée) afin d'attendre avant de jouer la note suivante.

Toutefois pour enchaîner correctement les notes de musique et tenir le rythme, il nous faut tenir compte du temps de latence dû au fait que l'appel sound.tone() est ici converti en une commande envoyée au TI-Innovator Hub par le port USB de la calculatrice, ainsi que du temps d'exécution que nécessite tout le reste du corps de la boucle.

Et bien c'est prévu, la méthode time.monotonic() ou time.ticks_ms() est utilisée pour mesurer la durée d'exécution d'une itération, prise en compte pour corriger l'appel time.sleep() de l'itération suivante. :D

Une fois ta conversion validée, tu obtiens ton script Python converti sous deux formes différentes :
  • un fichier .py téléchargeable
  • un code en coloration syntaxique que tu peux directement sélectionner et copier-coller




7) Exemples de mélodies

Go to top

Voyons tout-de-suite ce que ça donne. Pour fêter cet événement exceptionnel, commençons par un clin d'œil à nos amis nord-américains : ;)


Et nous t'avions promis de quoi jouer des mélodies ambitieuses pour tes jeux ou projets, voici de quoi te convaincre que l'objectif est atteint et que ça tient bien le rythme. Voici l'air de la chevauchée des Walkyries par Richard Wagner, 1856 : :#tritop#:




8) Liens d'accès

Go to top

midi2calc est un service en ligne entièrement gratuit, ne nécessitant de plus aucune inscription. :D

Pour accéder à midi2calc dès maintenant, c'est très simple. Tu as 2 liens directs courts :
  • https://tiplanet.org/midi2calc pour lancer l'outil de façon intégrée à l'interface de TI-Planet, soit entre autres avec le chat sous la main pour demander de l'aide ou faire des suggestions :)
  • https://tiplanet.org/midi2calc_classe dédié à un usage pédagogique en classe. Les divers éléments de TI-Planet (chat d'entraide, etc.) ne sont ici pas affichés, ne générant donc aucun bruit ou distraction lors de ta présentation.
En retour, nous aurons grand plaisir à prendre connaissance de tes projets. ;)
Lien vers le sujet sur le forum: midi2calc: conversion musique → Python pour TI-Innovator Hub (Commentaires: 4)

-
Rechercher
-
Social TI-Planet
-
Sujets à la une
Comparaisons des meilleurs prix pour acheter sa calculatrice !
Aidez la communauté à documenter les révisions matérielles en listant vos calculatrices graphiques !
Phi NumWorks jailbreak
123
-
Faire un don / Premium
Pour plus de concours, de lots, de tests, nous aider à payer le serveur et les domaines...
Faire un don
Découvrez les avantages d'un compte donateur !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partenaires et pub
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
2244 utilisateurs:
>2236 invités
>4 membres
>4 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Autres sites intéressants
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)