Iskua/min muunto iskujen väl. millisekunneiksi?

Voit pyytää apua ohjelmointiongelmiin täältä.
Post Reply
DJ-Filbe
Devoted Member
Posts: 854
Joined: Sat Feb 20, 2010 3:18 pm

Iskua/min muunto iskujen väl. millisekunneiksi?

Post by DJ-Filbe » Sun Feb 28, 2010 10:35 am

Tarkoitus olisi saada ohjelma, joka toistaa käyttäjän soittamia ääniä. Pitäisi voida myös säätää soiton nopeutta.
En ole tehnyt tätä varmaan maailman parhaalla tavalla, koodi on tässä:

Code: Select all

SCREEN 800,640

c=LoadSound("EGuitar\C.wma")
cy=LoadSound("EGuitar\C#.wma")
d=LoadSound("EGuitar\D.wma")
dy=LoadSound("EGuitar\D#.wma")
e=LoadSound("EGuitar\E.wma")
f=LoadSound("EGuitar\F.wma")
fy=LoadSound("EGuitar\F#.wma")
g=LoadSound("EGuitar\G.wma")
gy=LoadSound("EGuitar\G#.wma")
a=LoadSound("EGuitar\A.wma")
ay=LoadSound("EGuitar\A#.wma")
h=LoadSound("EGuitar\H.wma")
c2=LoadSound("EGuitar\C2.wma")

tallennus=1
sn = 60
Dim soitettava(1000)
For i=1 To 1000
soitettava(i) = ""
Next i
nyt=0
ns = 0
Repeat

'  Musiikin "äänittäminen"


If KeyUp(28) Then tallennus=0
If KeyUp(29) Or KeyUp(157) Then Gosub soita

If KeyUp(30) Then PlaySound c : nyt+1 : soitettava(nyt) = 1
If KeyUp(31) Then PlaySound d : nyt+1 : soitettava(nyt) = 2
If KeyUp(32) Then PlaySound e : nyt+1 : soitettava(nyt) = 3
If KeyUp(33) Then PlaySound f : nyt+1 : soitettava(nyt) = 4
If KeyUp(34) Then PlaySound g : nyt+1 : soitettava(nyt) = 5
If KeyUp(35) Then PlaySound a : nyt+1 : soitettava(nyt) = 6
If KeyUp(36) Then PlaySound h : nyt+1 : soitettava(nyt) = 7
If KeyUp(37) Then PlaySound c2 : nyt+1 : soitettava(nyt) = 8

If KeyUp(17) Then PlaySound cy : nyt+1 : soitettava(nyt) = 9
If KeyUp(18) Then PlaySound dy : nyt+1 : soitettava(nyt) = 10
If KeyUp(20) Then PlaySound fy : nyt+1 : soitettava(nyt) = 11
If KeyUp(21) Then PlaySound gy : nyt+1 : soitettava(nyt) = 12
If KeyUp(22) Then PlaySound ay : nyt+1 : soitettava(nyt) = 13






If LeftKey() Then sn-1
If RightKey() Then sn+1

ClearText
AddText "Soittonopeus: " + sn + " iskua / min: "







DrawScreen
Forever

soita:   ' Musiikin toistaminen
ns+1
 
 If soitettava(ns) <> 0 Then 
AddText "" + soitettava(ns)
If soitettava(ns) = 1 Then PlaySound c
If soitettava(ns) = 2 Then PlaySound d
If soitettava(ns) = 3 Then PlaySound e
If soitettava(ns) = 4 Then PlaySound f
If soitettava(ns) = 5 Then PlaySound g
If soitettava(ns) = 6 Then PlaySound a
If soitettava(ns) = 7 Then PlaySound h
If soitettava(ns) = 8 Then PlaySound c2

If soitettava(ns) = 9 Then PlaySound cy
If soitettava(ns) = 10 Then PlaySound dy
If soitettava(ns) = 11 Then PlaySound fy
If soitettava(ns) = 12 Then PlaySound gy
If soitettava(ns) = 13 Then PlaySound ay
Wait 17*sn ' Odotetaan, kunnes seuraavan nuotin saa soittaa. Lasketaan soittonopeudesta.
Gosub soita
EndIf


Return

Ongelma on siis se, että tuohon wait :n jälkeen pitäisi saada millisekunnit, jotka ovat nuottien soiton välissä. Mikä matemaattinen kaava tähän sopii kun tuo 17*sn :n merkitys kääntyy tietenkin negatiiviseksi: mitä isompi arvo, sitä isompi väli ja soi hitaammin....

EDIT:

Onko kaava mahdollisesti: 1 / Isk.PerMin * 60 ?


User avatar
otto90x
Advanced Member
Posts: 349
Joined: Mon Aug 27, 2007 9:00 pm
Location: Lapinjärvi, Finland
Contact:

Re: Iskua/min muunto iskujen väl. millisekunneiksi?

Post by otto90x » Sun Feb 28, 2010 11:57 am

No jos iskuja on minuutissa x, niin sekunnissa niitä on x/60. Kun sekunnin millisekunnit jaetaan tasan iskuille niin saadaan 1000/(x/60), joka on siis aika joka pitää odottaa iskujen välillä. Kannattaa kuitenkin muistaa että, komentojen suorittaminen tietokoneessa vie aikaa ja tästä syystä iskut voivat rasituksessa tulla myöhempään kuin tarkoituksellista. Siispä kannattaa ottaa ylös aikoja milloin on viimeksi soitettu ja vähentää tuo odotusajasta. Tämä ei tietenkään eliminoi sitä ongelmaa että nopealla tahdilla ja suurella rasituksella ei kone voi pysyä tämmöisellä keinolla perässä, koska muihin toimintoihin kuluu enemmän aikaa kuin mitä iskujen välinen aika on, tällöin pitäisi ennakoida ja soittaa useampi nuotti kerrallaan ja sitten vasta antaa tietokoneen suorittaa muita toimintoja. Tälläinen on CoolBasicin tasoisella kielellä aika vaikeaa, jollei mahdotonta joten kannattaa muistaa että vaikka kuinka hienoja keinoja käyttäisi niin ei välttämättä päästä haluttuun tulokseen.

Muutin koodiasi hieman sellaiseen suuntaan johon itse menisin. Ohjelma etsii nyt nuottien äänitiedostot automaattisesti. Keymap taulukossa voi antaa jokaiselle näppäimelle komennon jolloin näppäintä muuttaessa koko koodia ei tarvitse korjata, ainoastaan uudet komennot pitää koodiin lisätä. Tietysti tuon taulukon voisi lukea tiedostosta jolloin näppäimien komentoja voisi vaihtaa kääntämättä ohjelmaa uudelleen. Soittotaulukko sisältää vain ääniä, jolloin soittaessa ei enää tarvitse tietää mikä nuotti on kyseessä.

Code: Select all

SCREEN 800,640


Type note
    Field name$
    Field snd
End Type

c$=CurrentDir()

ChDir(c$+"\EGuitar")

StartSearch
    Repeat
        f$=FindFile()
        
        If Lower(Right(file$,4))=".wma"
            n.note=New(note)
            n\name=Mid(f$,Len(CurrentDir())+1)
            n\name=Left(n\name,Len(n\name)-4)
            n\snd=LoadSound(f$)
        EndIf 
        
    Until f$=""
EndSearch 

ChDir c$

Dim keymap(255) As String

Keymap(30)="C"
Keymap(31)="D"
Keymap(32)="E"
Keymap(33)="F"
Keymap(34)="G"
Keymap(35)="A"
Keymap(36)="H"
Keymap(37)="C2"
Keymap(17)="C#"
Keymap(18)="D#"
Keymap(20)="F#"
Keymap(21)="G#"
Keymap(22)="A#"
Keymap(28)="REC"
Keymap(29)="PLAY"
Keymap(157)="PLAY"


Dim soitettava(1000)
hetki=1

Repeat

    For i=1 To 255
        cmd$=Keymap(i)
        If cmd$<>"" Then 
            If KeyHit(i) Then 
                If cmd$="PLAY" Then 
                    Gosub soita
                    tallennus=0
                ElseIf  cmd$="REC" Then 
                    tallennus=Not tallennus
                    hetki=1
                    soitettava(0)=0
                Else 
                    If tallennus Then 
                        For n.note=Each note
                            If n\name=cmd$ And n\snd Then 
                                PlaySound n\snd
                                soitettava(hetki) = n\snd
                                soitettava(0)=hetki
                                hetki=hetki+1
                            EndIf 
                        Next n
                    EndIf 
                EndIf 
            EndIf 
        EndIf 
    Next i 
    
    If LeftKey() Then bpm-1
    If RightKey() Then bpm+1

    If tallennus Then Text 0,0,"TALLENTAA - PAINA ENTER LOPETTAAKSESI"
    Text 0,20,"Soittonopeus: " + bpm + " iskua / min: "
DrawScreen
Forever

soita:   ' Musiikin toistaminen
    
    waittime=Int(1000.0/(Float(bpm)/60.0))
    
    starttime=Timer()
    ClearKeys
    hetki=1
    While KeyHit(29)=0 And KeyHit(157)=0 And hetki<=soitettava(0)
        
        If soitettava(hetki) Then 
            soittoaika=Timer()
            PlaySound soitettava(hetki) 
        EndIf 
        
        Text 0,0,"SOITTAA - PAINA CTRL LOPETTAAKSESI"
        Text 0,20,"Soittonopeus: " + bpm + " iskua / min: "
        
        DrawScreen
        aikaakulunutjo=(Timer()-soittoaika)
        If aikaakulunutjo<waittime Then Wait waittime-aikaakulunutjo
        
        hetki=hetki+1
    Wend
    ClearKeys
Return
Otto Martikainen a.k.a. MetalRain, otto90x, kAATOSade.
Runoblogi, vuodatusta ja sekoiluja.

DJ-Filbe
Devoted Member
Posts: 854
Joined: Sat Feb 20, 2010 3:18 pm

Re: Iskua/min muunto iskujen väl. millisekunneiksi?

Post by DJ-Filbe » Thu Mar 04, 2010 11:39 am

Sain jo kaavan. Jos iskua/min muuttuja pitää muuntaa nuottien välille tulevaksi Wait - komennoksi, saamme 60000 jaettuna iskut_Per_Min
koska 60 bps = 1 sekunti nuottien välissä eli 1000 ms, eli 60000 / 60 = 1000ms
ja sitten 120 bps = 0,5 sekuntia nuottien välissä, saadaan 60000 / 120 = 500ms

eli näin!

User avatar
MaGetzUb
Guru
Posts: 1715
Joined: Sun Sep 09, 2007 12:35 pm
Location: Alavus

Re: Iskua/min muunto iskujen väl. millisekunneiksi?

Post by MaGetzUb » Thu Mar 04, 2010 12:50 pm

Jotain tämmööstä kannattaa kokeella:

Code: Select all

Iskut = 120
While KeyHit(1)=0
    Tempo = 60000/Iskut
    Iskut = Iskut + UpKey() - DownKey()

    Iskut = Max(40,Min(Iskut,999))
    
    Color cbwhite
    Text 0,0,"Iskuja: "+Iskut+" / Min"
    
    If Timer() > aika + Tempo Then 
        Text 0,15,"Määää"
        PlaySound "media/sheep.wav"
        aika = Timer()
    EndIf
    

        
    DrawScreen 
Wend
Solar Eclipse
Meneillä olevat Projektit:
We're in a simulation, and God is trying to debug us.

Post Reply