Vélocité d'attaque dans GarageBand : mais comment font-ils?

Bonjour,


 


J'aimerais reproduire sur mes synthés iOS le contrôle de vélocité d'attaque des pianos de GarageBand. Je précise que j'ai un iPad Air, sans le touch 3D.  (touch.force = 0.0 tout le temps)


 


J'ai lu ailleurs que l'accéléromètre était utilisé : mes essais n'ont rien donné. Les valeurs sont trop proches les unes des autres pour que ce soit ça. (horloge à  0.1 seconde, valeurs affichées lors du touch began)


 


L'idée est : plus on joue vite ou fort la note, plus elle sonne fort. Auriez-vous une piste par exemple? 


 


Merci par avance.


Réponses

  • HerveHerve Membre
    août 2016 modifié #2

    Ah, on cale là , hein? Moi aussi, j'avoue...


     


    J'ai trouvé cette vidéo :



     


    Je n'ai pas encore compris comment il transforme les infos de l'accéléromètre (x/y/z) en calcul de la vitesse d'attaque. A moins qu'il utilise une autre donnée?


     


    Il y a ce lien aussi, mais j'ai du mal à  comprendre également :


    http://www.patentlyapple.com/patently-apple/2012/03/patent-flash-the-tech-behind-apples-garageband-app-for-ipad.html


     


    ou celui-ci :


    http://appleinsider.com/articles/13/10/03/apple-investigating-advanced-velocity-sensitive-touch-input-methods


  • Ou encore ceci : (le brevet de Apple, carrément!) :


     


    http://www.freepatentsonline.com/20130257807.pdf

  • Si j'ai bien compris la vidéo, il récupère les micros mouvements du device quand on tape fort dessus et en déduis la vitesse d'attaque.


    Il moyennise pour avoir une plus belle courbe. Il est précisé que si le iPad est sur une table, ça risque de ne pas marcher.


     


    Colas


  • PS : comme ça, si j'étais Apple, je ferais des centaines ou milliers de Touches avec différentes intensités (et surtout à  différents endroits du Screen), je garderais les mesures de l'accéléromètre, etc. et avec un réseau de neurones j'obtiendrais la formules magique.


     


    Bref, je ne sais pas si c'est réaliste pour toi de vouloir obtenir la même fonction. Mais j'espère que je me trompe ;-)


  • J'ai fait une petite appli pour tester les réactions de l'accéléromètre et du "gyromètre" au toucher (des points qui bougent en fonction des valeurs). Effectivement, comme suggéré dans le brevet Apple, c'est surtout la valeur z de l'accéléromètre qui bouge, mais en ce qui concerne le "gyromètre", il semble que cela soit davantage la valeur x!


     


    J'essaie demain l'idée suivante : avec un timer, je rentre ces deux valeurs dans un tableau dont je calcule la moyenne (l'idée étant que l'on n'est pas à  jouer tout le temps de son clavier), puis au moment du touchesBegan, je calcule le rapport valeur à  ce moment là  et la moyenne, la valeur absolue me donne la vélocité. Il faudrait d'après le brevet utiliser les deux (accéléromètre et "gyromètre" : que mesure t-il d'ailleurs exactement?).


     


    Les gars de Apple ont manifestement lissé le résultat avec une jolie fonction qui me rappelle les courbes d'hystérésis du temps des magnétophones à  bande. En connaitriez-vous la fonction mathématique? (voir le brevet plus haut, courbe reprise dans une des deux pages mises en lien).


     


    Bref, on avance!


  • Hervé, si tu veux faire les choses encore mieux, tu devrais faire dépendre tes valeurs moyenne de l'endroit où le touch a lieu.


  • Pour la courbe que tu cherches, regarde du côté de x |---> Arctan(x) ;-) 


  • HerveHerve Membre
    août 2016 modifié #9

    Merci Colas de t'intéresser au problème. Mes premiers tests ce matin sont un progrès, mais le résultat est encore aléatoire. Cela marche souvent, mais pas toujours. Je n'ai pas essayer encore avec du son, mais avec des NSLog et la couleur de la UIVIew.


     


    Je n'utilise pour l'instant que la valeur z de l'accéléromètre. Du fait de la latence pour que cette valeur au moment de l'impact soit celle traitée, j'ai dû employer deux BOOL, ce qui me semble être du bricolage. Je pense qu'il y a mieux.


    Voici mon code :



    - (void)drawRect:(CGRect)rect {
    // Drawing code, la vélocité modifie la clarté du pad.
    [[UIColor colorWithHue:0.144 saturation:0.5 brightness:velocityResult alpha:1.0]set];
    [[UIBezierPath bezierPathWithRect:self.bounds] fill];
    }


    - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)theEvent{

    ilATape = YES; // un des deux BOOL utilisé pour que la bonne variable de l'accéléromètre soit prise en compte.

    }


    - (void) prendValeur:(NSTimer *)tm{ // timer à  0.1 seconde

    acceleroZTab[pointeur] = self.manager.accelerometerData.acceleration.z; // Le tableau stockant les valeurs en vu d'en établir une moyenne


    if (attendUnPeu == YES){ // Second BOOL, ainsi le timer a le temps de faire enregistrer la bonne valeur
    [self calculeVelocity:acceleroZTab[pointeur]];
    attendUnPeu = NO;
    }

    if (ilATape == YES){
    attendUnPeu = YES;
    ilATape = NO;
    }

    pointeur += 1;
    if (pointeur > 9) pointeur = 0;
    }

    - (void) calculeVelocity: (float) entry{

    float sommeAccZ = 0.0;
    for (int i = 0; i < 10; i++){
    sommeAccZ += acceleroZTab[i];
    }
    sommeAccZ /= 10.0; // Moyenne de la dernière 1/10 seconde

    float rapportAcc = entry - sommeAccZ; // la différence a été préférée au rapport
    if (rapportAcc < 0.0) rapportAcc *= (-1.0); // valeur absolue

    NSLog(@pointeur = %d, result : acc = %f (somme = %f, rapport = %f),pointeur, entry, sommeAccZ, rapportAcc);

    velocityResult = tanhf(rapportAcc * 100.0); // Préférée à  tangente, mais j'aimerais utiliser aussi les valeurs de -3 à  0 de la fonction. Pas de solution encore.

    NSLog(@vel = %f, velocityResult);

    [self setNeedsDisplay]; // Couleur du pad modifiée suite à  la vélocité d'attaque
    }

    Si cela vous inspire, vous êtes les bienvenus!


  • En ce qui concerne l'endroit où le touch a lieu, c'est comme cela que je faisais jusqu'à  présent (en haut de la touche > fort, en bas > doux), mais le "truc Garage band" est tellement bien que je veux le même!!


  • colas_colas_ Membre
    août 2016 modifié #11

    Non, ce n'est pas ça que je dis !


    Ce que je dis c'est la relation "Force d'appui => différentes valeurs de l'accéléromètre" ne sera pas la même selon l'endroit où le Touch a lieu.


     


    Par exemple, si l'accéléromètre est au centre de ton iPad et que tu appuies sur une touche au centre de l'iPad, tu auras un ∆z très grand et des ∆x et ∆y nuls.


    Mais, si tu tapes très fort sur une touche sur le bord de ton iPad, peut-être que que le ∆z ne sera pas si grand mais tu auras des ∆x et ∆y conséquents !


     


    PS : je n'y connais rien en Machine Learning, réseau de neurones, mais ça serait marrant de sortir une formule comme ça.


  • Ah oui, en effet, le clavier est toujours en bas de l'écran. Je n'y avais pas pensé. Merci! 


     


    Effectivement un petit test avec mon appli "Test" montre que la valeur y, dans ce cas, est sensible à  la vélocité au centre, et la valeur x sur les côtés (du clavier). Idem pour le gyromètre d'ailleurs.


     


    Je reprends ça demain.


    Merci encore.


Connectez-vous ou Inscrivez-vous pour répondre.