Musique (2)

Parmi les améliorations nécessaires, il y avait la possibilité de choisir sa musique ou son jingle selon les circonstances, et la gestion simultanée des deux voix.

Pour notre premier problème, nous allons utiliser l’adressage indirect en lieu et place de l’adressage absolu.
Il nous faut un pointeur pour la piste à jouer, pour les instruments et pour la table de tempo :

PtrTrack0      ds 2   ; pointeur vers la piste 0
PtrInstr0      ds 2   ; pointeur vers les instruments 0
PtrTempo0      ds 2   ; pointeur vers le Tempo 0

Pour lancer une piste en particulier, utilisons une sous-routine pour initialiser  ces pointeurs :

InitBipbip   
   lda #0
   STA Snd_Counter0
   STA Snd_Pos0
   ldx #7
InitBipbipLoop
   lda PtrBipbip-1,x
   sta PtrTrack0-1,x
   dex 
   bne InitBipbipLoop
   RTS   
; -------------- data musique ------------------   
PtrBipbip
   .byte #<TrackBipbip0,#>TrackBipbip0
   .byte #<InstrBipbip0,#>InstrBipbip0
   .byte #<TempoBipbip, #>TempoBipbip

Comme souvent, on pourra adapter cette routine selon qu’on souhaite épargner quelques octets de code ou quelques cycles machine. Vous noterez la syntaxe spéciale < et > pour référencer l’octet de poids faible et de poids fort d’une adresse.

Et enfin, les références absolues de type

    lda Track0,x

deviennent en référence indirecte

   lda (PtrTrack0),y

Vous noterez que le 6507 ne gérant pas la référence indirecte indexée par x, nous devons maintenant utiliser y comme index.

Pour le deuxième problème, la gestion simultanée des deux voix, il est nécessaire de dégager les portions de code communes. Nous indexerons les registres avec x (0 = voix 1, 1 = voix 2).
La syntaxe  lda (PrtTrack0,x),y  n’existant malheureusement pas, pour conserver la nature commune des routines, nous sommes obligés de passer par une case mémoire temporaire pour les informations désignées par les pointeurs.

Je vous livre de façon brute le résultat des mes cogitations :

Les cases mémoire et pointeurs

Snd_Pos0       ds 1   ; position dans la piste (FF = not running)
Snd_Pos1       ds 1   ; position dans la piste (FF = not running)
Snd_Counter0   ds 1   ; compteur de frames
Snd_Counter1   ds 1   ; compteur de frames
PtrTrack0      ds 2   ; pointeur vers la piste 0
PtrInstr0      ds 2   ; pointeur vers les instruments 0
PtrTempo0      ds 2   ; pointeur vers le Tempo 0
PtrTrack1      ds 2   ; pointeur vers la piste 1
PtrInstr1      ds 2   ; pointeur vers les instruments 1
PtrTempo1      ds 2   ; pointeur vers le Tempo 1
TmpNote        ds 1
TmpInstr       ds 1

Après mure réflexion, par souci de facilité, j’ai décidé que le tempo serait commun aux deux voix. Le pointeur PtrTempo1 n’est donc pas utilisé.

DoSound      ; ----------- piste 0
   ldy Snd_Pos0
   cpy #$FF ; piste terminée ?
   beq DoSound_next
   
DoSound0   
   lda Snd_Counter0 ; compteur de frame si 0 = nouvelle note
   beq DoSound0NewNote
   
   ; poursuite note en cours
   ldx #0
   jsr SustainNote
   jmp DoSound_next
   
DoSound0NewNote   
   ldx #0
   lda (PtrInstr0),y
   cmp #$FF  ; fin de piste ?
   bne DoSound0T1
   jsr StopSound
   jmp DoSound_next
   
DoSound0T1
   cmp #$FE  ; boucle ?
   bne DoSound0T2
   lda #0  ; compteur de piste au début
   sta Snd_Pos0
   tay
   jmp DoSound0

DoSound0T2
   sta TmpInstr
   lda (PtrTrack0),y
   sta TmpNote
   jsr NewNote
   
DoSound_next   ; ---------- piste 1   
   ldy Snd_Pos1
   cpy #$FF ; piste terminée ?
   beq DoSound_next2

DoSound1
   lda Snd_Counter1 ; compteur de frame si 0 = nouvelle note
   beq DoSound1NewNote
   
   ; poursuite note en cours
   ldx #1
   jsr SustainNote
   rts
   ;jmp DoSound_next2
   
DoSound1NewNote   
   ldx #1
   lda (PtrInstr1),y
   cmp #$FF  ; fin de piste ?
   bne DoSound1T1
   jsr StopSound
   rts
   ;jmp DoSound_next2
   
DoSound1T1
   cmp #$FE  ; boucle ?
   bne DoSound1T2
   lda #0  ; compteur de piste au début
   sta Snd_Pos1
   tay
   jmp DoSound1

DoSound1T2
   sta TmpInstr
   lda (PtrTrack1),y
   sta TmpNote
   jsr NewNote
   
DoSound_next2
   rts

NewNote ; nouvelle note
   ; instrument
   lda TmpInstr
   sta AUDC0,x  ; forme d'onde

   ; nouvelle note
   lda TmpNote
   tay ;2 on sauve A dans Y
   lsr ;2 on décale A de 3 bits vers
   lsr ;2 la droite pour obtenir les 
   lsr ;2 5 bits de fréquence
   sta AUDF0,x  ; "fréquence"
   tya ;2  on récupère A
   and #%00000111 ; et on ne conserve que les 3 bits de droite (durée)
   tay
   
   lda #15    ; volume à fond 
   sta AUDV0,x  ; 

   lda (PtrTempo0),y   ; nombre d'images à compter pour la  
   sta Snd_Counter0,x ; durée de la note
   
   inc Snd_Pos0,x     ; position suivante
   dec Snd_Counter0,x ; on décompte une image
   rts 

StopSound    ; fin de piste
   sta Snd_Pos0,x ; $FF dans le compteur
   lda #0       ; et on éteint tout
   sta AUDF0,x
   sta AUDV0,x
   rts
   
SustainNote
   dec Snd_Counter0,x ; on décompte une image
   rts 

Plus tard, dans SustainNote, nous pourrons intervenir sur la note dans sa durée (fading, pseudo-accord…).

Et enfin, les données « musicales »

; -------------- data musique ------------------   
PtrBipbip
   .byte #<TrackBipbip0,#>TrackBipbip0
   .byte #<InstrBipbip0,#>InstrBipbip0
   .byte #<TempoBipbip, #>TempoBipbip
   .byte #<TrackBipbip1,#>TrackBipbip1
   .byte #<InstrBipbip1,#>InstrBipbip1
   .byte #<TempoBipbip, #>TempoBipbip

TempoBipbip 
   .byte #7 ; 1/8s en ntsc valeur double croche
   .byte #14 ; 1/4s en ntsc valeur simple croche
   .byte #28 ; 1/2s en ntsc valeur noire
   .byte #56 ; 1s en ntsc valeur blanche
   .byte #112 ; 2s en ntsc valeur ronde
             
TrackBipbip0
   .byte #%11100010
   .byte #%11000010
   .byte #%10000010
   .byte #%00000100
   .byte #%00000000 ; boucle
   
InstrBipbip0
   .byte #4
   .byte #4
   .byte #4
   .byte #4
   .byte #$FE ; boucle

TrackBipbip1
   .byte #%11100000
   .byte #%00000000
   .byte #0
   
InstrBipbip1
   .byte #4
   .byte #4
   .byte #$FE ; boucle

Vous pouvez télécharger ce fichier source prêt à compiler ici : https://dl.dropboxusercontent.com/u/56947388/Cambouis/bipbip2.asm
(click-droit/enregistrer la cible sous)

Publicités

4 responses to “Musique (2)

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :