musique 1-bit

Pour annoncer une rencontre du troisième type entre individus présentant des caractéristiques communes.

Modérateurs : Papy.G, fneck, Carl

Avatar de l’utilisateur
utz
Messages : 36
Inscription : 12 juil. 2016 14:10
Localisation : Amsterdam
Contact :

Re: Concours de musique 1-bit

Message par utz »

yo_fr a écrit :Pour info sous VBHector je suis à 44100*4 hz (soit 176400hz) pour la génération du son. Le quartz étant à 5Mhz cela fait (environ) 28 cycles d'horloge par échantillon. Une instruction mini en Z80 c'est 4 cycles en moyenne disons 10 => toutes les 3 instructions Z80 je crée un échantillon. Pour moi c'est très fin. Ce doit aussi tenir de ça la qualité de son par rapport à Mess.
Ceci est une approche raisonnable. En fait, elle est à peine meilleure. Mais voici pourquoi elle échouera.
discretion-error.png
discretion-error.png (1.13 Kio) Consulté 9270 fois
Supposons que nous ayons un pièce de code qui va changer l'état de sortie tous les 34 cycles (comme le nouveau port de l'octode le fait, en fait). En réalité, le résultat sera inaudible (147056 Hz). Maintenant, on prends un sample chaque 28 cycles. Maintenant, nous avons une oscillation à 22000 Hz! Ce n'est toujours pas audible, mais comme tu peut interpoler de l'image, l'erreur se poursuivre, jusqu'à ce qu'il atteigne finalement le spectre audible.

Je ne sais pas quelle est la meilleure solution pour cela. Mais je sais que l'émulateur FUSE pour Spectrum fait un assez bon travail (mais pas parfait), alors peut-être tu veut envie de regarder le code source de cela.
__sam__
Messages : 7909
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: Concours de musique 1-bit

Message par __sam__ »

En fait il ne faut pas faire d'échantillonage direct du bit tous les x ms car il y a un phénomène de repliement de spectre. L'idéal est d'intégrer la valeur du bit.

Cela revient, pour l'émul, à compter le nombre de cycles d'horloge où le bit est à 1 et à 0. A chaque échantillon devant être envoyé à la carte audio (à 22khz par exemple), on fait le rapport nb_cycles_a_1 / (nb_cycles_a_0 + nb_cycles_a_1), ce qui donne une valeur entre 0 et 1 que l'on multiplie par 255 pour avoir la valeur à envoyer à la carte son. On réinitialise alors les compteurs à 0, et on les laisses s'incrémenter jusqu'à la sortie d'une nouvelle valeur à la carte son. (optim: plutot qu'avoir deux compteur son peut se contenter de relever le compteur de cycle d'horloge à chaque changement du bit de sortie et lui soustraire la valeur qu'il avait au changement précédent.)

C'est ce que fait DCMoto je crois.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Daniel
Messages : 17286
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: Concours de musique 1-bit

Message par Daniel »

Dans dcmoto, le signal tout ou rien du buzzer est intégré sur la période d'échantillonnage. L'échantillon envoyé à la carte son n'est pas la valeur 0 ou 1, mais la valeur intégrée.

Par exemple, si la période d'échantillonnage est 28 cycles et que le buzzer est passé de 0 à 1 au 18e cycle, le signal a été à 0 pendant 18 cycles et à 1 pendant 10 cycles. L'échantillon envoyé ne sera pas 1, mais 1 * 10 / 28.

Le calcul de l'intégrale se fait avec un compteur remis à zéro après chaque envoi d'échantillon. Après chaque instruction, on ajoute au compteur le nombre de cycles de l'instruction si le buzzer est à 1. Sinon, le compteur n'est pas modifié. A la fin de la période de 28 cycles, le compteur contient une valeur de 0 à 28.

Il y a encore un autre problème : dans l'axe des temps, l'envoi de l'échantillon ne tombe généralement pas à la fin d'une instruction, mais le plus souvent au milieu. Il y a donc un infime décalage. Pour en tenir compte, dcmoto fait de la diffusion d'erreur : le nombre de cycles de l'écart est mémorisé pour en tenir compte dans le calcul de l'échantillon suivant.
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
yo_fr
Messages : 1336
Inscription : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: Concours de musique 1-bit

Message par yo_fr »

Certes, mais c'est une instruction processeur qui change la valeur du buzzer. La dernière approximation est vraiment utile ?

par exemple, dans le cas d'Hector, c'est l'instruction

LD (0x01800),A

qui fait basculer le buzzer.
Cette instruction fait 13 cycles. C'est au dernier (ou avant dernier, je ne sais pas!) cycle que le buzzer est effectivement mis à jour. Cet écart est de toutes façon constant (à condition d'utiliser toujours des instructions similaires).

De plus j'ai mis en place des filtres numériques post traitement. Cela atténue ces problèmes non ?

[EDIT] Il est vrai que les enregistrements effectués ont été fait SANS filtre. Je viens d'essayer avec, le sifflement metallique est complètement parti même avec un filtre à 22khz...
Avatar de l’utilisateur
utz
Messages : 36
Inscription : 12 juil. 2016 14:10
Localisation : Amsterdam
Contact :

Re: Concours de musique 1-bit

Message par utz »

JJ, je me rends compte que je tu ai probablement mal compris en ce qui concerne l'émulation sonore. Alors s'il te plaît ne pas tenir compte de mon commentaire précédent.

Par ailleurs, il est préférable d'appliquer des filtres en pré-traitement, ça veut dire avant le down-sampling.

Quoi qu'il en soit, comme je l'ai dit plus tôt, il est tout à fait possible que je simplement fait une erreur avec les timings.

Daniel, Samuel, Ceci est une discussion très intéressante. Cependant, j'ai du mal avec la compréhension, à cause de mon mauvais français. Pourriez-vous s'il vous plaît expliquer un peu plus ou écrire des mots plus faciles ce que vous avez dit?
Daniel
Messages : 17286
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: Concours de musique 1-bit

Message par Daniel »

yo_fr a écrit :Certes, mais c'est une instruction processeur qui change la valeur du buzzer. La dernière approximation est vraiment utile ?
Oui, bien sûr, c'est une instruction qui change la valeur du buzzer. Ce que je voulais faire comprendre, c'est que le calcul d'un échantillon ne peut se faire qu'entre deux instructions, et ce n'est pas forcément à ce moment précis que l'échantillon doit être envoyé. Le décalage entre les deux évènements (le calcul et l'envoi) fausse (très légèrement) la valeur théorique de l'échantillon, car elle est intégrée sur une période légèrement différente de la période théorique.

En mémorisant l'écart, on peut en tenir compte à la fin de la période suivante pour essayer de rattraper. C'est de la diffusion d'erreur. La différence est assez subtile, et pour une musique normale on ne discerne rien à l'oreille. Par contre cette correction améliore nettement le son en PWM car les périodes sont beaucoup plus courtes, et l'erreur relative est donc plus importante.
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
yo_fr
Messages : 1336
Inscription : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: Concours de musique 1-bit

Message par yo_fr »

Dans VBHector, je ne fais pas de down-sampling.

Je crée au fil de l'eau un buffer à 176400Hz et c'est directement ceci que j'envoi a DirectX qui joue le sample à 176400Hz.
__sam__
Messages : 7909
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: Concours de musique 1-bit

Message par __sam__ »

@utz, l'idée est celle ci (en simplifiant): il faut compter le temps que passe l'émulateur avec le buzzer à 1 entre 2 envoi à la carte son du pc, c'est à dire tous les 45µs si la carte son tourne à 22khz. Par exemple, si on trouve que le buzzer est à 1 pendant 30% des 45µs, l'émulateur envoie une valeur de 30% le volume max (donc 77 pour 255).

En fait au lieu de compter en µs, on peut aussi simplement compter en cycles cpu-émulé, c'est pareil, car ce qui compte c'est le ratio du temps passé avec le buzzer à 1.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Avatar de l’utilisateur
yo_fr
Messages : 1336
Inscription : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: Concours de musique 1-bit

Message par yo_fr »

Sauf que pour être précis il faut faire le ratio avec le nombre de cycle processeur (pour le total) et pas une valeur fixe.
Par exemple je suis à 28,344671201814058956916099773243 cycles pour 1 échantillon sonore.
La dernière instruction était une instruction "lourde" et à la fin je suis à 36 cycles réalisés ( et, par exemple, on a fait 10 cycles avec le buzzer à 1). Il faut donc faire le ratio Vmax * 10 / 36.

(Sachant que l'échantillon suivant se fera à 20,689342403628117913832199546485 où là on calculera un autre ratio...

J'ai tout bon ?

(ok, j'aurais pu prendre moins de chiffres après la virgules... :? mais c'est pour le fun ! : :wink: )
Avatar de l’utilisateur
yo_fr
Messages : 1336
Inscription : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: Concours de musique 1-bit

Message par yo_fr »

J'ai essayé sous Mess mes fichiers K7 et j'ai vu qu'en supprimant l'octet à 0 après le code FD, les fichiers K7 fonctionnent correctement!

Mess doit donc effectivement charger différemment les fichiers K7 et WAV (Le Wav sans analyse préalable), eesayé sous Messui en 0.175.

JJ
Xavier

Re: Concours de musique 1-bit

Message par Xavier »

Salut,
@JJ : je viens juste de relire le fil, et ...
A ta question: "Xavier, ton Token permet-il de charger du binaire ou que du texte dans du basic ? "
Non, pas pour le "HectorToken", car le binaire n'est pas inclus dans le fichier basic, contrairement aux fichiers pour ZX81.
Il est donc utile de créer deux types de fichiers [BAS] et [BIN].
L'exercice est simple, car je l'ai fait sur CPCtoken, mais mes connaissances dans le Hector se limitent au Basic.
Mais, tu as deux type d'implantation sous forme de fichiers, le chargement K7 ou le chargement d'image mémoire.
Sur CPC, on donne l'offset (org) de la routine asm, et le tocken va créer le fichier avec une entête binaire avec la taille et l'adresse offset de la routine.

Cela ce note:
## FILE #1
[ASM ORG(&hC000) HEX:\
1F,20,3D,1E,20,76,76,1A ]

## FILE #2
[ASM ORG(hC100) HEX:\
1F,20,3D,1E,20,76,76,1A ]
Donc, cela ce traite en "Bloc" binaire, avec création d'un fichier à chaque ASM ORG....

Pour l'implantation direct en mémoire, en chargeant un fichier "memory snap" (SNA) et Z80 sur le xur...
Il suffit 'simplement' de prendre une image du mémoire au démarrage de la machines, et d'y ajouter les "bouts" de codes (basic) et ASM... directement, aux offsets voulues.
Mais dans ce cas, il te faudra patcher manuellement les informations des variables Basic mises à jour par le chargement d'un fichier, à savoir, la taille du programme basic, le ramtop (ASM), l'adresse de début basic, et toutes ces petites variables qui peuvent planter le chargement du fichier image mémoire dans l'émulateur avec un LIST ou un RUN !
Cette méthode est aussi applicable à une injection directe de ta partie binaire Basic, directement dans ton émulateur.
Donc, si tu veux un exemple, tu trouvera les codes dans le zip de CPCtoken...
Pour les variables système, tu fais une comparaison binaire d'une mémoire vide, et d'une mémoire après chargement sur K7/D7.
La méthode n'est pas plus compliquée qu'un chargement sur K7, mais il te faut peaufiner ces variables pour retomber sur tes pattes, à chaque insertion et modification de mémoire... pour le basic, mais aussi pour l'ASM, qui peut manger le bloc basic déjà entré.
C'est pour cela que ta méthode de stimulation de touches est plus fiable, mais beaucoup plus lente...
Sur le Spectrum et le ZX81, il était impossible de traiter cette méthode, mais sur hector, il n'y a pas de touches étages.
Voilà pour la réponse.
Avatar de l’utilisateur
yo_fr
Messages : 1336
Inscription : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: Concours de musique 1-bit

Message par yo_fr »

OK, merci.
J'avais entre temps regardé Hector Token en détail et effectivement il est bien pour pour prendre du texte et en créer un fichier K7 pour le basic (3 et 3X).

Depuis j'ai créé un utilitaire supplémentaire à VBHector (qui sera bientôt disponible) pour créer des fichiers cassettes, tout comme utz qui a créé un code c pour cela aussi.

Sous VBhector, l'utilitaire permet de choisir le type de bloc et d'aider à la mise en place des données souhaitées :
bin2k7.JPG
bin2k7.JPG (51.48 Kio) Consulté 9173 fois
bin2k7.JPG
bin2k7.JPG (51.48 Kio) Consulté 9173 fois
et avec le bouton d'aide on peut choisir les bloc les plus courants :
bin2k73.JPG
bin2k73.JPG (41.24 Kio) Consulté 9173 fois
(les choix pré-documentent les champs qui seront insérés dans le fichier K7.)


Tout ça pour la prochaine version !!
(quel teaser !)


Mais merci quand même pour ta réponse !
JJ
Avatar de l’utilisateur
farvardin
Messages : 436
Inscription : 27 déc. 2014 16:07
Contact :

Re: Concours de musique 1-bit

Message par farvardin »

Reprise de la musique de Game of Thrones sur TI83+ avec Houston Tracker II : https://www.youtube.com/watch?v=XziNo-OjQag
Avatar de l’utilisateur
farvardin
Messages : 436
Inscription : 27 déc. 2014 16:07
Contact :

Re: musique 1-bit

Message par farvardin »

puisqu'on parle ici de musique 1-bit, Shiru (un développeur russe talentueux, qui créée des moteurs de musique 1-bit sur zx spectrum), vient de porter certaines de ses routines sous Arduino, ça en parle ici :


http://randomflux.info/1bit/viewtopic.php?id=121
http://randomflux.info/1bit/viewtopic.php?id=122
http://randomflux.info/1bit/viewtopic.php?id=125

(il y a 3 routines, octode, phaser1 et qchan)

C'est facile à utiliser, il y a juste à flasher un arduino, connecter un haut parleur (un petit hp de buzzer de pc fera l'affaire) sur les bornes 7 et GND et ça roule.

Un exemple : http://picosong.com/GFmm/ (en vrai ça rend mieux, j'ai un peu raté l'enregistrement)
__sam__
Messages : 7909
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: musique 1-bit

Message par __sam__ »

farvardin a écrit :Un exemple : http://picosong.com/GFmm/ (en vrai ça rend mieux, j'ai un peu raté l'enregistrement)
C'est pas si raté que ça. Sais tu à quelle vitesse il module le bit ? car le son me semble très très "lisse". On entend pas du tout la porteuse.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Répondre