It is currently Mon Dec 11, 2017 11:43 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Sat Oct 01, 2005 1:44 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7312
Location: Chexbres, VD, Switzerland
Is it possible to calculate the 11-bit period only by calculation, I mean not use a table to found a period for a not, then add a constant to do vibrato/slide effects, because this isn't techically correct. I mean I should add/substract a value in function of the period itself. For example, if we remove a constant value to a period, the tune won't rise lineary, but it will rise slow, then faster. I wan't to be able to do it only by calculation, so it would rise lineary. Any ideas ? I think Just Breed does that, I dissasembled it's code once. I'll try to re-found it.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Oct 01, 2005 3:30 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
No practical way really. Converting from period to tone involves hefty division... and even after you get the tone you'd still have to scale it and convert it back to a period value.

As for doing pitch bends/vibrattos, a simple yet effective way would be to add/subtract the period right shift a bunch to itself. Something like:

period += period >> 3; // to bend downwards
period -= period >> 4; //to bend upwards

It might take some tinkering but the concept should work. This way as the periods get smaller... so does the value you add/subtract. Which does a decent job of evening out the rate of the bends.

In my example there I subtract a smaller number than I add... which you'll probably need to do in practice... since:

period -= period >> 1; // will go 1 full octave up
period += period >> 1; // will only go about 2/5th an octave down

so like I said, it'll take some tinkering


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 02, 2005 12:46 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7312
Location: Chexbres, VD, Switzerland
Yeah, so that the add/substract amount is relative to the period itself.
However, this isn't very pratical to use, scince you have to read the older period. I mean have a main pitch value, then several add/substract relative value to the pitch, regardless of the pitch itself. This value would be composition of the bend pitch and vibratoes, and possibly detune value, etc....
So that would be pratical to use from the main sound code, even if it may need some complicated calculation.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 02, 2005 10:05 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7312
Location: Chexbres, VD, Switzerland
Here you are the crazy code I found in Just Breed.
I understant pretty much the begining, but the end becomes very crazy. It uses the MMC5 multiplier once, but scince it multiplies by $40, it would be pretty simple to write a similar code for a normal mapper. I just didn't understand the actual algorithm behind that.
Note that you enter with $4e=octave, and output with $4a = low 8 bits of period, $4b = high 3 bits of period. You enter with note in A, that is between $0 and $b (between C and B of the upper octave, for each semitune respectively).

Code:
GetPitch   tay         ;Y=Note; X=Channel
      lda SndFineTuneBufferL,x
      clc
      adc SndPitchSlideBufferL,x
      sta $4a
      lda SndFineTuneBufferH,x
      adc SndPitchSlideBuffer,x
      sta $4b         ;Setup fine tune (detune+pitch slide index)
      lda VibratoPitchValue,x
      sec
      sbc #$80
      bmi _vibNeg
      clc
      adc $4a
      sta $4a      ;Add vibrato index to fine tune
      lda #$0
      adc $4b
      jmp _vibPos
;--------------------
_vibNeg      clc
      adc $4a
      sta $4a      ;Same as above, but decrease MSB if overflow instead of increase it
      lda $4b
      sbc #$0
_vibPos      sta $4b
      bmi $a8c8   ;Main detune calculated. Is that thing negative ?
      lda $4a
      asl a
      rol $4b
      asl a
      rol $4b      ;Bit 6 and 7 of LSB goes in LSB (?)
      lsr a
      lsr a
      sta $4a
      jmp lbl_c8e5
;--------------------
lbl_a8c8:   lda $4a
      asl a
      rol $4b      ;Same as above
      asl a
      rol $4b
      lda $4a
      and #$3f   ;Check if the LSB is zero (apart of bit 6 and 7)
      beq lbl_a8da
      inc $4b      ;If not, set the bits 6 and 7, and increase MSB
      ora #$c0
lbl_a8da:   sta $4a
      bpl lbl_a8e5   ;The N flag is set by the lda $4a above or the inc $4b above, cant say much here
      clc
      adc #$40   ;Would that clear bit 6 and 7 ??
      sta $4a   
      dec $4b      ;$4b equals main detune (note) and $4a fine detune

lbl_a8e5:   tya
      clc      ;Y = Note
      adc $4b      ;Check if the detune could go one octave below
      bpl lbl_a8fa
      dec $4e      ;If so decrease octave
      clc
      adc #$c      ;And correct the note in A
      bpl lbl_a90c   ;Check if the detune is strong enough to get below a second octave
      dec $4e
      clc
      adc #$c      ;If so correct it
      jmp lbl_c90c
;--------------------
lbl_a8fa:   cmp #$c
      bcc lbl_a90c   ;Check if the detune could go one octave above
      inc $4e
      sec
      sbc #$c
      cmp #$c
      bcc lbl_a90c   ;Check for a second octave up
      inc $4e
      sec
      sbc #$c      ;Now A equals the correct note with the correct octave
lbl_a90c:   sta $5206
      sta $4f
      lda #$40   ;Multiply note by $40
      sta $5205
      lda $4a
      bmi $a92a   ;Check for the note before it's octave correction (?)
      clc
      adc $5205
lbl_a91e:   sta $4a      ;Result is detune in bits 0-5 and note in bits 6-7
      lda $5206
      adc #$0
      sta $4b      ;High bits of the note are here
      jmp lbl_c937
;--------------------
lbl_a92a:   clc
      adc $5205   ;??
      sta $4a
      lda $5206
      sbc #$0      ;??
lbl_a935:   sta $4b

      lda $4a
      clc
      adc #$ab
      sta $4a
      lda $4b      ;Add main pitch to the pointer $c9ab
      adc #$c9
      sta $4b      ;$c9ab+$23a=
      ldy #$0
      ldy ($4a),y   ;Load low tune
      sta $4a
      ldy $4f
      lda $c99f,y   ;Load high tune in function of the note
lbl_a94f:   sta $4b
lbl_a951:   lda $c993,y
      beq lbl_a95c   ;?
      lda $4a
      bpl lbl_a95c
      dec $4b      ;Decrease low pitch if high pitch is negative
lbl_a95c:   lda $4b
      ldy $4e
      beq lbl_a989   ;If octave is zero, the thing is completed
      bmi $a98a
      cpy #$5
      bcs lbl_a973   ;Go elsewhere if octave above 5 (for very high notes)
lbl_a968:   lsr a
      ror $4a      ;Divide the period by 2 for each octave
      dey
      bne lbl_a968
      sta $4b
      jmp lbl_c989   ;Done !!
;--------------------
lbl_a973:   sty $50      ;Octave higher than 5 (probably used for sound effects)
      lda #$8
      sec
      sbc $50      ;8-Octave = a number between 1 and 3
      tay
      lda $4a
lbl_a97d:   asl a
      rol $4b      ;This will multiply the period by 2 for each octave
      dey      ;In other word, the highest notes become the lowest (?)
      bne lbl_a97d
      lda $4b
      sty $4b      ;0 overrides the high pitch
      sta $4a      ;And the low pitch overrides the high pitch
lbl_a989:   rts
;--------------------
lbl_a98a:   asl $4a      ;If octave is negative, multiply period by 2
      rol $4b
      lda #$0      ;And re-set octave to zero
      sta $4e
      rts

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 09, 2005 1:10 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7312
Location: Chexbres, VD, Switzerland
Here you are, the exact formla is :
freq = CPUFreq/Period+1
freq(note)=2^(LowestCFreq*(FineTune+128*MainPitch)/128*12)*2^Octave
so :
Code:
Period=CPUFreq/(2^LowestCFreq*(FineTune+128*MainPitch)/128*12))-1

Where FineTune is between 0 and 127, Main Pitch is 0 for C, 1 for C#, etc... up to 11 for B
I think that this can be done with a Table, but man, it would be large, even for one single octave. Is there any way this enormous calculation could be simplificated accurately ?
Also, the minus 1 at the end is pretty confusing. Usually I just shifted the period to change octave, but the 1 additional cycle seems to make it not 100% accurate.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group