It is currently Wed Sep 19, 2018 11:30 am

 All times are UTC - 7 hours

 Page 1 of 1 [ 5 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: Obtaining 11-bit pitch period only by calculationPosted: Sat Oct 01, 2005 1:44 pm

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7517
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

 Post subject: Posted: Sat Oct 01, 2005 3:30 pm

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1849
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

 Post subject: Posted: Sun Oct 02, 2005 12:46 am

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7517
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

 Post subject: Posted: Sun Oct 02, 2005 10:05 am

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7517
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
sta \$4a
lda SndFineTuneBufferH,x
sta \$4b         ;Setup fine tune (detune+pitch slide index)
lda VibratoPitchValue,x
sec
sbc #\$80
bmi _vibNeg
clc
sta \$4a      ;Add vibrato index to fine tune
lda #\$0
jmp _vibPos
;--------------------
_vibNeg      clc
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
lbl_a91e:   sta \$4a      ;Result is detune in bits 0-5 and note in bits 6-7
lda \$5206
sta \$4b      ;High bits of the note are here
jmp lbl_c937
;--------------------
lbl_a92a:   clc
sta \$4a
lda \$5206
sbc #\$0      ;??
lbl_a935:   sta \$4b

lda \$4a
clc
sta \$4a
lda \$4b      ;Add main pitch to the pointer \$c9ab
sta \$4b      ;\$c9ab+\$23a=
ldy #\$0
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

 Post subject: Posted: Sun Oct 09, 2005 1:10 am

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7517
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

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 5 posts ]

 All times are UTC - 7 hours

#### Who is online

Users browsing this forum: lidnariq and 6 guests

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

Search for:
 Jump to:  Select a forum ------------------ NES / Famicom    NESdev    NESemdev    NES Graphics    NES Music    Homebrew Projects       2018 NESdev Competition       2017 NESdev Competition       2016 NESdev Competition       2014 NESdev Competition       2011 NESdev Competition    Newbie Help Center    NES Hardware and Flash Equipment       Reproduction    NESdev International       FCdev       NESdev China       NESdev Middle East Other    General Stuff    Membler Industries    Other Retro Dev       SNESdev       GBDev    Test Forum Site Issues    phpBB Issues    Web Issues    nesdevWiki