pitch slide
BlitzMax Forums/BlitzMax Beginners Area/pitch slide| 
 | ||
| For x#=11025 To 8000 Step -1 Print x# Print 11025/x# SetChannelRate(chan,11025.0/x#) m=MilliSecs() While MilliSecs()<(m+100) Wend Next just dont do it! Am I missing somthing or is pitch sliding with max not possible? | 
| 
 | ||
| You need a much bigger step to hear it change: 
sound = LoadSound ("beep.ogg", 1)
Print sound
chan = PlaySound (sound)
For x#=22050 To 8000 Step -500
Print x# 
Print 11025/x# 
SetChannelRate(chan,x#/11025.0) 
m=MilliSecs() 
While MilliSecs()<(m+100) 
Wend 
Next 
(I have to admit I'd much prefer if the second parameter was plain old frequency myself.) | 
| 
 | ||
| frequency would be very nice the change *Can* be hears but seems v.choppy now how am i gonna write a tracker... btw x#/11025 or 11025/x# in your example >:) | 
| 
 | ||
| maybe it's choppy because it changes in too BIG a step, or not often enough? Maybe wait for m+50 and halve the step? | 
| 
 | ||
| Well, that large step was just to demonstrate the change... just lessen the step! | 
| 
 | ||
| no its still *really* choppy.... 
sound = LoadSound ("tada.wav", True)
Print "sound="+sound  ' prints nothing not even   sound=  
chan = PlaySound (sound)
For x#=22000 To 44000 ' very tiny steps
'	Print x#/22000
	SetChannelRate(chan,x#/22000)  ' only seems to work in large steps 
	m=MilliSecs() 
	While MilliSecs()<(m+2) ' a small delay
	Wend 
Next 
 | 
| 
 | ||
| Yup, I'll fix it first thing next week. | 
| 
 | ||
| thanks... | 
| 
 | ||
| While you're at it skid, could you implement a SetFreq() command as well?  And if you're feeling generous, a SetPeriod() command would be great for oldskool tracker writers... Nothing people can't do themselves, but to quote someone else 'I bought BlitzMax so I don't have to program' =] | 
| 
 | ||
| In case anybody is interested, the Magic Number for a period/frequency conversion is 7093789.2 for a PAL machine and 7159090.5 for an NTSC machine.  Thus : 7093789.2/(period*2)=frequency 7093789.2/frequency/2=periodAnd www.wotsit.org is a fantastic place for format documentation. | 
| 
 | ||
| and this is how to load and print out the contents of the first pattern of a .xm module 
' initial release of .xm library
base=LoadBank("corona.xm")
Print "total size"+BankSize(base)
modname:String=getstring(base,17,36)
Print "name:"+modname
tracker:String=getstring(base,38,57)
Print "made with:"+tracker
hs=PeekByte(base,60)+PeekByte(base,61)*256+PeekByte(base,62)*65536+PeekByte(base,63)*16777216
Print "header size:"+hs
hs:+60 ' gives end of header
slen=getword(base,64)
Print "song length:"+slen
restart=getword(base,66)
Print "song restart:"+restart
chans=getword(base,68)
Print "channels:"+chans
pats=getword(base,70)
Print "pattern:"+pats
instrm=getword(base,72)
Print "instruments:"+instrm
flags=getword(base,74)
Print "flags:"+flags
Local s:String
If flags & 1 Then s="Linear " Else s="Amiga "
Print s+"freq table"
tempo=getword(base,76)
Print "tempo:"+tempo
bmp=getword(base,78)
Print "bmp:"+bmp
patheadlen=PeekByte(base,hs)+PeekByte(base,hs+1)*256+PeekByte(base,hs+2)*65536+PeekByte(base,hs+3)*16777216
Print "pattern head length:"+patheadlen
rows=getword(base,hs+5)
Print "rows:"+rows
patsize=getword(base,hs+7)
Print "pattern data size:"+patsize
patbase=hs+9
Print "pattern data start:"+patbase
line:String=""
For l=1 To rows
	For i=1 To chans
	line:+readnote(base,patbase)+" :: "
	Next
Print line
line=""
next
I'd be delighted if some one would add to this as part of a comunity project. oops forgot this ' Period = 10*12*16*4 - Note*16*4 - FineTune/2; ' Frequency = 8363*2^((6*12*16*4 - Period) / (12*16*4)); ' honest guv Function readnote:String(where,from Var) Global notestr:String[]=["C-","C#","D-","D#","E-","F-","F#","G-","G#","A-","A#","B-"] Local s:String,c:Byte,n:Byte s="" c=PeekByte(where,from) from:+1 If(c&128) Then If(c&1) Then n=PeekByte(where,from)-1 s:+ " N"+notestr[(n Mod 12)]+Byte(n/12) from:+1 Else s:+ " " EndIf If(c&2) Then s:+ " I"+Right(Hex(PeekByte(where,from)),2) from:+1 Else s:+ " " EndIf If(c&4) Then s:+ " V"+Right(Hex(PeekByte(where,from)-16),2) from:+1 Else s:+ " " EndIf If(c&8) Then s:+ " E"+Right(Hex(PeekByte(where,from)),2) from:+1 Else s:+ " " EndIf If(c&16) Then s:+ " D"+Right(Hex(PeekByte(where,from)),2) from:+1 Else s:+ " " EndIf Else s:+ " N"+notestr[(c Mod 12)-1]+Byte(c/12) s:+ " I"+Right(Hex(PeekByte(where,from)),2) from:+1 s:+ " V"+Right(Hex(PeekByte(where,from)-16),2) from:+1 s:+ " E"+Right(Hex(PeekByte(where,from)),2) from:+1 s:+ " D"+Right(Hex(PeekByte(where,from)),2) from:+1 EndIf Return s EndFunction Function getword:Int(where,start) Return PeekByte(where,start)+PeekByte(where,start+1)*256 End Function Function getstring:String(where,start,last) Local s:String="" For Local x=start To last If PeekByte(where,x)<>0 Then s:+Chr(PeekByte(where,x)) 'Print s Next Return s End Function | 
| 
 | ||
| 7093789.2/(period*2)=frequency 7093789.2/frequency/2=period That's interesting, but PCs don't fall into PAL/NTSC categories. I wonder how the number's calculated? | 
| 
 | ||
| 7159090 is twice...ntsc clock value, @ 0.279365ms 28,867 samples/second is also the maximum sampling rate for PAL systems. Thus, for PAL systems, a value of at least 123 ticks/sample must be written into the period register. CLOCK VALUES NTSC PAL UNITS Clock Constant 3579545 3546895 ticks per second Clock Interval 0.279365 0.281937 microseconds per interval see http://www.amigarealm.com/computing/knowledge/hardref/ch5.htm page 137 | 
| 
 | ||
|  I wonder how the number's calculated?  Most players settle for the NTSC number I think. I guess the fairest method on PC is to just use the average of those two numbers =] There is only one or two 'finetune' values differance between PAL and NTSC, so I guess the average would be no more than 1 finetune value, unless there're really long samples being played (impossible on old .mod format anyway) the differance is negligable. |