Tuesday, March 25, 2008

-funroll-sample-loops

Bon, j'avais un peu mis le développement de libntxm en berne ces derniers jours, notamment par ce que je ne comprenais pas ce qui faisait sonner faux tous mes chiptunes. je soupçonnais quelque-chose du côté des ajustements de notes (vous savez,le truc calibré à 8636Hz pour un DO, et qu'il faut ajuster à la main quand on importe un nouveau son dans un mod), mais non. C'est 0xtob qui a mis le doigt dessus : la DS gère les loops en hardware, mais uniquement quand la longueur des loops est un multiple de 4 ...

Aucun soucis si on a un son "ordinaire" que l'on essaie de faire tourner en boucle (au pire, il y aura des petites déformations dans le son). Mais s'il s'agit d'une onde pour un chiptune (souvent faite à la main, et dont la taille a tout juste la longueur d'onde du son), c'est tout différent. Retirez-lui un ou deux samples, et vous vous retrouvez avec une autre longueur d'onde (et donc une autre note de référence). Bref, c'est l'horreur.
Heureusement, la solution est plus simple que le problème: répéter (au plus 4 fois) la boucle de sorte que sa longueur devienne un multiple de 4 (si ça c'est pas bête et sot :P)

Well, coding on libntxm has been a bit slowed down these last days, maybe because i couldn't figure out why all those chiptunes i've got sounded de-tuned. My guess was that i missed something in the "instrument fine-tuning" mechanism, but Oxtob pointed out that there was actually something going wrong with loops.
You typically use looped in two cases. Case 1 is that you want something like a "strings" instrument that can keep playing (the same) as long as you let it flow. These are the loops the DS prefers to play. Case 2 is that you're doing a chiptune and hand-crafted a waveform that you want to loop to create your bare sample. In that case the loop is typically very small (as small as 32 bytes for some musicians), and this is where DS sound hardware gets in your way.

What happens is that the DS hardware wants loops to have lengths expressed in 32 bits quantities (yep, even with 8 and 16-bit samples :P ), but hand-crafted loops may not conform to this requirement. And given that the loop length is the wavelength (which define the note's height), a single byte skipped by the hardware may doom your module's playback.
Hopefully enough, the cure is simpler than the illness here. You need a multiple-of-four amount of samples in your loop and you have an odd (or just even) amount ? well, just copy-paste the loop as many times as it takes to have 4xN samples. Period. Since loops are small, it doens't hurt.

Voilà. J'attends les nouveaux .xm de Pierrick, et je vais aller ranger un peu parce que mon beau-père vient m'aider à travailler dans la salle de bain cet après-midi ... le plus dur, ça va être de débrancher la DS de la chaine Hi-Fi qui est occupée à me rejouer la musique du niveau 1 de SMB3 en boucle depuis 10 minutes ^_^

Get it on sourceforge : code and binary (runme)

Wednesday, March 19, 2008

Negative Space

Amis possesseurs d'une DS, réjouissez-vous: le grand Mia est de retour! Avec un petit concept de jeu puzzle tout simple: "Negative Space", où l'on doit aider deux blobs à rejoindre leurs drapeaux respectifs. Nos blobs rampent et font de petits bonds, mais surtout, votre stylet peut "creuser" des galeries. Attention, par contre: pour le blob blanc, un trait noir est une galerie, alors que pour le blob noir, c'est un mur. Et vice-versa.

Vous suivez ? non ? bah, refaites-vous un Touch Me (i'm famous), alors. C'est que ce genre de jeu n'est probablement pas fait pour vous. Sinon, cliquez bien vite l'image pour être téléporté sur le blog de Mia où vous pourrez télécharger le homebrew et tester ça.

Nice to see Mia bringing one of the ideas proposed in 'the 300 mechanics' to life. Nice to see it open-source and to see how straight-to-the-point the coding had been. Here is Negative Space. Two opposite blobs must reach their corresponding flags. They will never meet each-other, because what is 'empty' for one of them is concrete for the other, and vice versa.

The DS twist to the formula is that you're allowed some 'ink' to change the level layout in each of the dozen screens the game feature to make the impossible possible.

edit: oh, bien-sûr, tout l'intérêt du jeu vient du fait que vous n'aurez droit qu'à un certain nombre de traits, et de longueur limitée pour résoudre chaque tableau.

Moi, j'ai jeté un petit coup d'oeil au code source, en plus, et là je tire mon chapeau à Mia (et à Mollusk), parce que même pour un petit jeu "tout simple", faire aussi simple, ça reste un art. (Bon, j'ai une certaine tendance au gigantisme codesque, je l'avoue, mais ça ne m'empèche pas d'apprécier le tiny-coding).

Court donc (une douzaine de tableaux), minimaliste certainement, mais agréable. Une sorte de "jeu jetable", sauf qu'à mon avis, vous ne le jeterez pas.

edit: tout ça sur un concept de squidi.net, qui a encore 79 autres concepts de jeu à 'revendre', et qui vise les 300 d'ici la fin de l'année ...

Thursday, March 13, 2008

Codez un Worms en Basic

Un article assez sympa dans le webzine "QB Express" s'attaque à la réalisation d'un worm-like en Basic (eh oui. Il y a encore des utilisateurs de BASIC de nos jours ^_^). Je ne vais pas tout traduire, mais il y a quelques points intéressant que j'aimerais partager:

  • la map est ici définie pixel par pixel avec un seul byte par pixel qui permet à la fois de choisir la texture à appliquer (0=ciel, 1=terre, 2=métal) et la réaction du terrain aux explosions (0=rien, 1=destructible, 2=indestructible).
  • en plus de l'animation d'une explosion, on aura un "masque" qui indique quelle destruction apporter au terrain. En général, on veut un beau cercle, ceci dit. un trou en forme de nuage, ça fait moins sérieux. Pour appliquer une explosion, il suffira de parcourir à la fois le masque et le terrain, genre if (explosion(i,j)=1 and map(i,j)=1) then map(i,j)=0.
  • lors du déplacement d'un Worm, ce n'est pas un pixel qui est testé, mais tous les nouveaux pixels qui seront occupés par le ver. (c'est à dire les pixels rouges sur l'image)
Et à y repenser (et à re-regarder les tiles de Fury of the Furries), je me dis que c'est sans doute comme ça que mon bon bieux furry fonctionnait. le moindre pixel de décor était "solide" (même le bout d'une feuille). Il y aurait donc du boulot si on voulait porter le jeu sur une console comme la DS (rien d'infaisable, mais du boulot quand-même).

Tuesday, March 11, 2008

It surely ~vibes~!

Well, after three days working on my paper for that PRESTO workshop and visiting the "batibouw" (kitchen, showers, solar boilers ...) i was hardly needing a coding intermission. So after a nice cooking-time this evening, i picked up DS, laptop and headphones and gave vibratos a try... The hardest time was to get rid of a bug that prevented some instruments to get played, and i may not have found the exact multipliers, but dudes, let me tell you one thing: it surely ~vibes~ here.

There is only support for sine waveform atm (which is the most used anyway), and it looks like i'll have a hard time adding support for the "volume-column effects", which many trackers have been using instead of ProTracker combo effects.

Salut les poteaux. Bon, après trois jours sur mon article pour PRESTO et la visite du salon "Batibouw", j'avais vraiment besoin de souffler un peu... Alors j'ai repris mon player XM et j'ai ajouté le support du vibrato, pour rigoler. Bon, je n'ai peut-être pas encore les bons règlages sur la vitesse et l'amplitude des vagues, mais je peux vous garantir une chose,: ça ~vibre~ bien.

Oh, au passage, vous remarquerez que j'ai repris les petits smileys faits en collaboration avec Junkboy pour illustrer cette rubrique. J'espère que vous aimez ^_^

edit: Hmm. I might have found what's going wrong with all the effects. ProTracker effects (and i guess, their XM derivatives) are only supposed to be executed on non-row ticks. At least, that's the case for volume slide and portamento to note, and that explains many if (tick==0) return; in libmikmod's code. This is not the way libntxm works atm, so i may need to check out previous stuff in HandleTickEffects() ...

Offending Key

Un petit ssh de plus, et je me retrouve de nouveau avec le message pénible:

Warning: the RSA host key for 'ladybug' differs  
from the key for the IP address '139.165.222.35'
Offending key for IP in /home/sylvainulg/.ssh/known_hosts:32
Are you sure you want to continue connecting (yes/no)?
Eeeh oui: on a réinstallé quelques machines dans le labo, leurs identité ont changé, et plus rien ne va ... Et pour simplifier les choses, contrairement à mes "bonnes vieilles SuSE", ubuntu ne stocke *rien* en clair dans le fichier "known_host". Avant, j'aurais ouvert le fichier avec jed/emacs, recherché l'adresse IP en question et supprimé la ligne, mais là ...

Seule technique valable pratiquée jusqu'ici: supprimer complètement le fichier (mais alors toutes les machines sont de nouveau inconnues, etc.) Eh bien, il y a mieux, bien sûr. Pas d'idée, allez, je vous le refait
Warning: the RSA host key for 'ladybug' differs 
from the key for the IP address '139.165.222.35'
Offending key for IP in /home/sylvainulg/.ssh/known_hosts:32
Are you sure you want to continue connecting (yes/no)?
Bin oui. Un numéro de ligne. Reste à retirer juste cette ligne là avec votre éditeur texte favori, et rou(il)lez jeunesse! Oh, au passage, hors des partitions NFS, le .known_host ... okay ? okay.

Thursday, March 06, 2008

tuuiiiii tiiiuuuuu

Hey dudes, i have some good news! My fairy's got a steady job!

Oh, well ... You want another kind of good news ? well, i managed to get "portamento to note" effect played correctly by libntxm ;) It's been a bit more complex than "portamento up" and "portamento down" because the player wasn't ready for notes that aren't played immediately. Especially, 0xtob's technique of fading a new note a couple of milliseconds before the new row wasn't aware that "effect_porta_note" means "don't fade, for i'm not going to re-play the note".

I also wonder what it should sound like when one issue a Gxx command (porta-to-note. I'm used to S3M/IT effects names, sorry) with an instrument different from the current one. Atm, the new instrument information would be discarded (afaik) and the portamento would go on with the current instrument. Click the smiley to see what's new in the code ^_^.

Bonne nouvelles, les amis: ma fée s'est trouvé un boulot quotidien !
Comment ça "c'est pas les nouvelles qu'on attendait" ?? Vous voulez des nouvelles du player XM ? Bin j'vais vous en donner, moi, des nouvelles du player XM. J'ai un effet "portamento-to-note" qui marche. Et puisque c'est comme ça, je fais pas de release, tiens! NA! Ca vous apprendra!

(ps: non, en fait, je ne fais pas de release parce que j'aurai un article à terminer pour mercredi prochain, et qu'il devra faire 6 pages et pas une douzaine comme je le pensais... donc au dodo parce que demain, on se lève tôt, mais vous pouvez cliquer sur le smiley pour regarder ce qui a changé dans le code ^_^).

Tuesday, March 04, 2008

Les joies des mod'players

Schism Tracker (linux) editing 'beek-beercan-pyramid.xm' chiptune, my current test module for portamentos and arpeggiosAah ... les joies de la programmation de modplayers. Je crois que tout bien réfléchi, c'est le type d'application qui est le plus obscur à debugger. Ca doit provenir de son côté "temps-réel", à moins que ce ne soit le fait que tous ces blocs de codes s'enchaînent pour finalement donner *un* résultat tout mixé que seul votre oreille (si elle est bien dressée) peut identifier comme correct ou incorrect.

Après avoir introduit une petite interface de débugging toute simple dans le player de libntxm, de haute lutte, j'ai frayé mon chemin jusqu'au bug par-delà les appels de fonctions pour reprendre le son que j'avais perdu.

(euh. je m'égare). Bref. Un simple "inst = pattern[pat][chan][row]" placé un peu trop tôt dans le mod et c'est la quasi-totalité des effets (existants et ajoutés) qui se sont mis à foirer. Heureusement, je suis mieux armé qu'il y a 10 ans avec la soundblaster. J'ai le CVS pour me rappeler ce que j'ai changé, par exemple.

Mais j'adore ça ^_^

petite release sources avec la nouvelle structure "Channel".
edit: Tiens, je devrais penser à ajouter un widget pour activer/désactiver des pistes pendant que l'on écoute le module. Ca aiderait ...