Thursday, February 28, 2008

portamento ...

Retour pas mal d'année en arrière ? Alors que j'essaie d'ajouter les portamento (variation continue de la fréquence d'une des notes) à la bibliothèque ntxm, je me heurte aux même(s) difficulté(s) que lorsque je développais mon player S3M pour mes jeux DOS/Assembleur...

  • Pas évident de structurer les données des channels pour que les effets s'expriment proprement. Là, par exemple, je ne saurais probablement pas gérer la valeur 00 pour les portamento (qui permet de réutiliser la dernière valeur non-nulle).
  • Pas évident non plus de savoir quel est l'effet exact ... d'un effet. autre exemple: mon "portamento up" a une mémoire trop "longue" : au fur et à mesure que le morceau est rejoué, le portamento emmène la note de plus en plus haut au lieu de rejouer toujours do--ré--mi.
edit: au moins, j'ai réussi à avoir des "portamento" qui marchent à la bonne vitesse:
  1. le 'pas' défini par le format XM est "1/256ème d'octave par tick"
  2. la fonction BendNote(note,finetune) de ntxmlib considère qu'il y a 128 niveaux de "finetune" entre deux notes successives (p.ex. C et C#)
  3. le player exécute l'effet "portamento" uniquement sur un "tick". Le nombre de tick par ligne est défini par l'effet "set speed" du morceau. La durée de chaque tick (en millisecondes) est calculée à partir du tempo (en bpm). En clair, si je double le nombre de tick par ligne, le morceau semble défiler plus lentement, mais la même commande "portamento" me conduira deux fois plus loin dans les notes.
oh, just to let you know : portamento up is fixed. I need to reorganize a couple of things in the player to better capture (and manipulate) the "state of a playing sample" (since Sample is simply a static structure that represent "a sample in the module's sound repository"): atm. the new note won't clear the current "drift" of the previous slide (and thus it'll keep on sliding higher and higher).
// our finetune is 12 times finer than the XM 'octave interval'
effstate.actual_finetune[channel]+=param*12;
Instrument *inst = song->instruments[state.channel_instrument[channel]];
inst->bendNote(state.channel_note[channel]+(effstate.actual_finetune[channel]>>7),
state.channel_note[channel],
effstate.actual_finetune[channel]&0x7f,
channel);
break;

No comments: