IPB

Bienvenue invité ( Connexion | Inscription )

> Optimiser les calculs en C
Options
Anard
posté 10 Mar 2018, 15:06
Message #1


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 659
Inscrit : 7 May 2015
Membre no 195 224



Bonjour,

Je travaille sur un µC qui doit lire du MIDI en temps réel.
Il est programmé en C et je débute un peu dans ce language. Lors de changements de tempo, j'ai besoin de faire des calculs mathématiques qui prennent beaucoup de temps au processeur (je pense que je m'y prend mal, j'ai l'impression que certaines instructions seraient à éviter).
Le fichier est écrit ainsi :
  • L'en-tête du fichier contient une valeur en nombre de "ticks" par noire
  • Au début et quand c'est nécessaire, il est indiqué un nouveau tempo en µs par noire (j'en déduis la durée d'un tick)
  • Avant chaque évènement Midi est indiqué un nombre de "ticks" à attendre


Mon programme actuel fonctionne comme ça :
Le microcontrôleur dispose d'un timer interne. Il s'incrément automatiquement tous les 64 coups d'horloge et il déclenche une action quand il atteint une limite configurable entre 1 et 255.
J'essaie donc de le calculer de telle manière à ce qu'il corresponde au plus près de la durée d'un "tick" et quand je recois un nombre de ticks à attendre, j'attends qu'il se déclenche autant de fois avant de lire la suite.
Mon calcul fonctionne, mais si le tempo change par exemple de manière progressive dans un morceau (en gros, il y a un changement de tempo avant chaque note), la lecture s'en trouve très ralentie. C'est embêtant.

Voici ce que j'utilise en cas de changement de tempo :
Code
// variable globale
    unsigned int baseDelay;
        float baseFreq;
// variables locales
    long Finstruction;
    float base, limite, calcul;

// A l'ouverture du fichier, je déduis du nombre de "ticks" par noire (une seule fois) la fréquence du timer dont j'ai besoin
    Finstruction = _XTAL_FREQ / 4000000; //MHz
    baseFreq = 256 * (long)DivisionTps; // 256 = limite max d'explosion du timer
    baseFreq = Finstruction / baseFreq; // = FmaxTimer / DivisionTps
    baseFreq /= 16;    // multiplicateur interne du timer

// Configuration lors d'un changement de Tempo

        // souvent la limite de 256 du timer ne suffira pas, donc j'utilise un multiplicateur supplémentaire
        base = ceil(Tempo * baseFreq);

        // calcul de la valeur d'Overflow (PR2)
        calcul = baseFreq * 256 / base;
        limite = round (Tempo * calcul);
        
        // config
        baseDelay = (int)base;
        PR2 = (int)limite - 1; // le timer déclenche un évènement au moment où il passe la limite PR2, pas quand il l'atteint

        // je dois aussi récupérer le Tempo en BPM :
        TempoBPM = 60000000/Tempo;

// Lorsque je reçois un délai à attendre, il est simplement calculé comme ceci :
        return (DelaiLu * baseDelay);
// puis le timer est démarré si le résultat n'est pas nul.


Pourriez-vous m'expliquer quelles sont les opérations les plus lourdes là-dedans pour essayer de faire en sorte de les supprimer ?
Merci beaucoup.

Ce message a été modifié par Anard - 10 Mar 2018, 15:38.


--------------------
"iMack" : GA-H97M-D3H, Intel i5 4460, 16Go DDR3, Asus GTX670 Intel HD4600, 2x SSD 256Go, HDD 500Go+Zraid 3x2To / Clover - macOS Mojave / Gentoo-Xfce
"Portable" : HP Pavilion DV3500, Intel core2 T6400, 4Go DDR3, NVidia GeForce 9300M, HDD 256Go / Grub2 - Gentoo-Xfce
Go to the top of the page
 
+Quote Post
 
Start new topic
Réponse(s)
ntx
posté 13 Mar 2018, 18:14
Message #2


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 490
Inscrit : 19 Aug 2004
Lieu : 92
Membre no 22 254



Un petit peu de culture.
Go to the top of the page
 
+Quote Post

Les messages de ce sujet


Reply to this topicStart new topic
1 utilisateur(s) sur ce sujet (1 invité(s) et 0 utilisateur(s) anonyme(s))
0 membre(s) :

 



Nous sommes le : 28th April 2024 - 01:47