IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Calcul scientifique Python Discussion :

Dessiner un clavier d'instrument [Python 2.X]


Sujet :

Calcul scientifique Python

  1. #1
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut Dessiner un clavier d'instrument
    Hello,

    J'ai un problème d'algorithme dans le dessin d'un clavier d'instrument, genre piano ou synthé. Si on regarde le haut du clavier, les touches noires et les touches blanches devraient avoir strictement la même largeur pour des raisons évidentes de contraintes de fabrication. Mais, sur le dessin que j'ai codé, les touches blanches mi et fa (3ème et quatrième à partir de la gauche) ont la bonne largeur cumulée pour les 2 ensemble, mais elles n'ont pas individuellement la même largeur, ça se voit bien sur l'image. Le problème réapparaît sur chaque octave.

    Au niveau purement algorithmique, un clavier est composé de plusieurs octaves dont le schéma se répète. Chaque octave est composé de 12 notes, 7 blanches et 5 noires. Le problème vient bien sûr du fait qu'il n'y a pas le même nombre de notes noires et blanches, il n'y a pas de noire entre le mi et le fa ni entre le si et le do. Pour résumer, sur le haut j'ai divisé en 12 intervalles (noires + blanches) par octave et en par 7 (blanches) sur le bas.

    Je constate que si la séparation verticale mi-fa est fausse, la séparation si-do (le deuxième endroit où il n'y a pas de note noire) a l'air bon. Ma première idée était de décaler légèrement les touches blanches vers la gauche pour équilibrer l'écart mi-fa, mais du coup on déséquilibre l'écart si-do qui lui semble correct... Une idée???

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    import sys
    import os
    if sys.version_info[0] < 3:
        import Tkinter as gui
    else:
        import tkinter as gui
     
    WHITE = True
    BLACK = not WHITE
    NOTE_TYPE = [WHITE, BLACK,WHITE, BLACK,WHITE, WHITE, BLACK,WHITE, BLACK,WHITE, BLACK,WHITE]
    NB_NOTE_PER_STAVE = 12
    NB_STAVES = 6.0
    NB_WHITE_PER_STAVE = 7.0
    NB_BLACK_PER_STAVE = 5.0
    WIDTH_FOR_1_STAVE = 500.0
    WHITE_WIDTH = WIDTH_FOR_1_STAVE / NB_WHITE_PER_STAVE
    BLACK_WIDTH = WIDTH_FOR_1_STAVE / (NB_WHITE_PER_STAVE + NB_BLACK_PER_STAVE)
    WHITE_HEIGHT = 400.0
    BLACK_HEIGHT = 250.0
    NB_NOTES = 3 * NB_NOTE_PER_STAVE + 1
     
    def addBlack(canvas, x1, y1, x2, y2, color="#000000", **kwds):
        if "fill" in kwds.keys():
            del(kwds["fill"])
        canvas.create_rectangle(x1, y1, x2, y2, fill=color, **kwds)
     
    def addWhite(canvas, x1, y1, x2, y2, **kwds):
        kwds["fill"] = "#ffffff"
        kwds["outline"] = "#000000"
        canvas.create_polygon(x1, y1, x1, y2, x2, y2, x2, y1, **kwds)
     
    if __name__ == "__main__":
     
        win = gui.Tk()
        win.title("Musical Keyboard")
        canvas = gui.Canvas(win, width=BLACK_WIDTH * (NB_NOTES + 1) + 10, height=WHITE_HEIGHT + 10, bg="green")
        canvas.grid()
     
        x = 0.0
        for note_index in range(NB_NOTES):
            flt_index = float(note_index)
            if NOTE_TYPE[note_index % NB_NOTE_PER_STAVE] == WHITE:
                x1 = x
                x +=  WHITE_WIDTH
                x2 = x
                y1 = 0.0
                y2 = WHITE_HEIGHT
                addWhite(canvas, x1, y1, x2, y2)
     
        for note_index in range(NB_NOTES):
            flt_index = float(note_index)
            if NOTE_TYPE[note_index % NB_NOTE_PER_STAVE] == BLACK:
                x1 = flt_index * BLACK_WIDTH
                x2 = x1 + BLACK_WIDTH
                y1 = 0.0
                y2 = BLACK_HEIGHT
                addBlack(canvas, x1, y1, x2, y2, "#000000")
     
        win.mainloop()

  2. #2
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    La nuit portant conseil, j'ai résolu le problème. La note fa est la 4ème note blanche et la 6ème note chromatique de la gamme. Sa tranche gauche doit donc être au niveau des notes blanches:

    largeur_octave / 7 * 3

    Tandis qu'au niveau du haut (chromatique):

    largeur_octave / 12 * 5

    On est bien d'accord que ces deux valeurs - Bien que très proches - ne sont pas égales. Je pense avoir tout réglé dans l'image générée par le script ci dessous

    https://app.box.com/s/zclvh6wmv5clrl1otpcv5amw3mktoxz0

    Dites moi si vous voyez que les touches blanches n'ont pas tout à fait la même largeur. Le script:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    import sys
    import os
    if sys.version_info[0] < 3:
        import Tkinter as gui
    else:
        import tkinter as gui
     
    WHITE = True
    BLACK = not WHITE
    NOTE_TYPE = [WHITE, BLACK,WHITE, BLACK,WHITE, WHITE, BLACK,WHITE, BLACK,WHITE, BLACK,WHITE]
    NB_NOTE_PER_STAVE = 12
    NB_STAVES = 6.0
    NB_WHITE_PER_STAVE = 7.0
    NB_BLACK_PER_STAVE = 5.0
    WIDTH_FOR_1_STAVE = 580.0
    WHITE_WIDTH = WIDTH_FOR_1_STAVE / float(NB_WHITE_PER_STAVE)
    BLACK_WIDTH = WIDTH_FOR_1_STAVE / float(NB_NOTE_PER_STAVE)
    FIRST_WHITE_WIDTH = BLACK_WIDTH * (5.0 / 3.0)
    SECOND_WHITE_WIDTH = BLACK_WIDTH * (7.0 /4.0)
    WHITE_HEIGHT = 400.0
    BLACK_HEIGHT = 250.0
    NB_NOTES = 3 * NB_NOTE_PER_STAVE + 1
     
    def drawBlack(canvas, x1, y1, x2, y2, color="#000000", **kwds):
        if "fill" in kwds.keys():
            del(kwds["fill"])
        canvas.create_rectangle(x1, y1, x2, y2, fill=color, **kwds)
     
    def drawWhite(canvas, x1, y1, x2, y2, **kwds):
        kwds["fill"] = "#ffffff"
        kwds["outline"] = "#000000"
        canvas.create_polygon(x1, y1, x1, y2, x2, y2, x2, y1, **kwds)
     
    if __name__ == "__main__":
     
        win = gui.Tk()
        win.title("Musical Keyboard")
        canvas = gui.Canvas(win, width=BLACK_WIDTH * (NB_NOTES + 1) + 10, height=WHITE_HEIGHT + 10, bg="green")
        canvas.grid()
     
        x = 0.0
        for note_index in range(NB_NOTES):
            flt_index = float(note_index)
            if NOTE_TYPE[note_index % NB_NOTE_PER_STAVE] == WHITE:
                x1 = x
                if (note_index % NB_NOTE_PER_STAVE) < 5:
                    # width for C D E is stave / 12 * 5 / 3 
                    x +=  FIRST_WHITE_WIDTH
                else:
                    # width for F G A B is stave / 12 * 7 / 4 
                    x +=  SECOND_WHITE_WIDTH
                x2 = x
                y1 = 0.0
                y2 = WHITE_HEIGHT
                drawWhite(canvas, x1, y1, x2, y2)
     
        for note_index in range(NB_NOTES):
            flt_index = float(note_index)
            if NOTE_TYPE[note_index % NB_NOTE_PER_STAVE] == BLACK:
                x1 = flt_index * BLACK_WIDTH
                x2 = x1 + BLACK_WIDTH
                y1 = 0.0
                y2 = BLACK_HEIGHT
                drawBlack(canvas, x1, y1, x2, y2, "#000000")
     
        win.mainloop()
    Le but était un dessin de clavier à l'envers avec les 12 notes chromatiques rigoureusement égales, pour pouvoir jouer quelques mélodie avec un ruban résistif, qui lui est bien linéaire.

    https://app.box.com/s/cus8rr06ckybgxyudq0x52n8ikjhqle7


    A+

    Pfeuh

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Transformer un PC en synthétiseur : le clavier devient un instrument de musique
    Par bernonl dans le forum Programmation pour enfants
    Réponses: 4
    Dernier message: 01/04/2018, 14h35
  2. Réponses: 9
    Dernier message: 04/02/2016, 20h21
  3. Commander au clavier un dessin dans un canevas
    Par cal23 dans le forum Tkinter
    Réponses: 10
    Dernier message: 19/01/2015, 20h37
  4. Dessiner un clavier
    Par alex3_57 dans le forum wxWidgets
    Réponses: 0
    Dernier message: 30/03/2010, 22h35
  5. Réponses: 3
    Dernier message: 12/06/2002, 19h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo