Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: PHP: Pianosoinnut

Sivun loppuun

Antti Laaksonen [07.07.2004 23:12:32]

#

Tässä skriptissä on kolme toimintoa:

Skripti toiminnassa: http://koti.mbnet.fi/pllk/muut/piano/piano.php

Skripti tuntee tavallisimmat soinnut, ja niitä voi lisätä helposti itse muuttamalla skriptin alussa olevia taulukkoja.

<?php
/*
Pianosointujen näyttö, haku ja soitto, tekijä Antti Laaksonen

Tämä skripti näyttää valitun soinnun pianon koskettimilla.
Toinen mahdollisuus on ilmoittaa soinnussa olevat sävelet,
jolloin skripti kertoo niiden sointujen nimet, joissa
valitut sävelet ovat. Skripti pystyy myös soittamaan minkä
tahansa sävelyhdistelmän muodostamalla MIDI-tiedoston.

*/

// sävelten nimet oikeassa järjestyksessä
$savelet = array("C", "Cis/Des", "D", "Dis/Es", "E", "F",
                 "Fis/Ges", "G", "Gis/As", "A", "Ais/B", "H");
// sointujen nimet
$soinnut = array("", "+", "6", "7", "maj7", "m",
                 "m6", "m7", "sus4", "dim");
// sointujen sävelet, kantasäveltä ei ole mukana
$soinnut_s = array(array(4, 7), array(4, 8), array(4, 7, 9),
                   array(4, 7, 10), array(4, 7, 11), array(3, 7),
                   array(3, 7, 9), array(3, 7, 10), array(5, 7),
                   array(3, 6, 9));
// näytettävät oktaavit
$oktaavit = 2;

// tulostaa sivulle pianon koskettimet
function koskettimet($painetut, $oktaavit) {
    // koskettimien värit oktaavissa (0 = valkoinen, 1 = musta)
    $varit = array(0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0);

    echo "<table cellpadding=\"0\" cellspacing=\"0\" border>";
    echo "<tr valign=\"bottom\">";

    // piirretään koskettimet alalaidan valintaruutuineen
    $k = 0;
    for ($i = 0; $i < $oktaavit; $i++) {
        for ($j = 0; $j < 12; $j++) {
            $vari = $varit[$k % 12] ? "m" : "v";
            $painettu = in_array($k, $painetut) ? "checked" : "";
            echo "<td><img src=\"p_{$vari}.png\" width=\"20\"
                  height=\"50\">";
            echo "<center><input type=\"checkbox\" name=\"k{$k}\"
                  $painettu></center></td>";
            $k++;
        }
    }

    echo "</tr></table>";
}

// tulostaa sivulle valituista sävelistä muodostuvat soinnut
function soinnut($painetut, $savelet, $soinnut, $soinnut_s) {
    // laitetaan valitussa soinnussa olevat sävelet
    // taulukkoon, jakojäännöksen avulla samassa oktaavissa
    for ($i = 0; $i < count($painetut); $i++) {
        $oikea[$painetut[$i] %= 12] = 1;
    }
    // käydään läpi kaikki soinnut kaikissa sävellajeissa, ja
    // pistetään talteen valitun soinnun kanssa samat
    for ($i = 0; $i < 12; $i++) {
        for ($j = 0; $j < count($soinnut_s); $j++) {
            $kokeilu = array($i => 1);
            for ($k = 0; $k < count($soinnut_s[$j]); $k++) {
                $kokeilu[($soinnut_s[$j][$k] + $i) % 12] = 1;
            }
            if ($oikea == $kokeilu) {
                $loydetyt[] = $savelet[$i] . $soinnut[$j];
            }
        }
    }
    // tulostetaan löytyneet soinnut sivulle
    if (isset($loydetyt)) {
        echo "<p>Löytyneet soinnut: ";
        echo $loydetyt[0];
        for ($i = 1; $i < count($loydetyt); $i++) {
            echo ", {$loydetyt[$i]}";
        }
        echo "</p>";
    } else {
        echo "<p>Sointuja ei löytynyt!</p>";
    }
}

// muodostaa MIDI-tiedoston valitusta soinnusta
function midi($painetut) {
    // ohjataan selainta käsittelemään sivu oikein
    header("Content-Type: audio/midi\n\n");
    header("Content-Disposition: attachment; filename=sointu.mid");

    $pituus = count($painetut);

    if ($pituus == 0) {
        exit;
    }

    // määritetään MIDI-tiedoston aloitus
    $data = array(77, 84, 104, 100, 0, 0, 0, 6, 0, 1, 0, 2, 0, 192, 77,
                  84, 114, 107, 0, 0, 0, 10, 0, 255, 1, 2, 65, 76, 0, 255,
                  47, 0, 77, 84, 114, 107, 0, 0, 0, 18 + 8 * $pituus, 0,
                  255, 33, 1, 0, 0, 176, 7, 127, 0, 176, 10, 64, 0);

    // lisätään tiedostoon oikeat sävelet
    for ($i = 0; $i < $pituus; $i++) {
        $data[] = 144;
        $data[] = 60 + $painetut[$i];
        $data[] = 110;
        $data[] = ($i == $pituus - 1) ? 133 : 0;
    }
    $data[] = 80;
    for ($i = 0; $i < $pituus; $i++) {
        $data[] = 144;
        $data[] = 60 + $painetut[$i];
        $data[] = 0;
        $data[] = 0;
    }
    $data[] = 255;
    $data[] = 47;
    $data[] = 0;

    // tulostetaan kaikki tiedoston merkit sivulle
    for ($i = 0; $i < count($data); $i++) {
        echo chr($data[$i]);
    }

    exit;
}

$painetut = array();

// laitetaan soinnun sävelet taulukkoon soinnun
// nimen tai valittujen sävelien perusteella
if (isset($l1)) {
    $painetut = $soinnut_s[$sointu];
    $painetut[] = 0;
    for ($i = 0; $i < count($painetut); $i++) {
        $painetut[$i] += $savel;
    }
} else {
    for ($i = 0; $i < $oktaavit * 12; $i++) {
        $nimi = "k{$i}";
        if (isset($$nimi)) {
            $painetut[] = $i;
        }
    }
}

// muodostetaan MIDI-tiedosto, jos niin on valittu
if (isset($l3)) {
    midi($painetut);
}

echo "<html><head><title>Sointuapu</title></head><body>";

echo "<h2>Sointuapu</h2>";

echo "<form action=\"piano.php\" method=\"post\">";

// tulostetaan koskettimet
koskettimet($painetut, $oktaavit);

// tulostetaan sävelet sisältävä alasvetovalikko
echo "<p><select name=\"savel\">";
for ($i = 0; $i < count($savelet); $i++) {
    $valittu = ($i == $savel) ? " selected" : "";
    echo "<option value=\"{$i}\"{$valittu}>{$savelet[$i]}";
}
echo "</select> ";

// tulostetaan soinnut sisältävä alasvetovalikko
echo "<select name=\"sointu\">";
for ($i = 0; $i < count($soinnut); $i++) {
    $valittu = ($i == $sointu) ? " selected" : "";
    echo "<option value=\"{$i}\"{$valittu}>{$soinnut[$i]}";
}
echo "</select> ";

echo "<input type=\"submit\" name=\"l1\" value=\"Näytä\"> ";

echo "<input type=\"submit\" name=\"l2\" value=\"Etsi\"> ";

echo "<input type=\"submit\" name=\"l3\" value=\"Soita\"></p>";

echo "</form>";

// tulostetaan säveliin sopivat soinnut, jos niin on valittu
if (isset($l2)) {
    soinnut($painetut, $savelet, $soinnut, $soinnut_s);
}

echo "</body></html>";

?>

Tempfile [07.07.2004 23:33:25]

#

Erittäin hieno, itselläkin on pyörinyt mielessä kaikkien epätavallisempien asioiden teko PHP:llä, tuntuu olevan muotia nykyisin.

Olga [07.07.2004 23:35:25]

#

Vetää sanattomaksi. Aivan loistava idea ja mahtava toteutus. Kerrankin jotain todella omaperäistä ja hyödyllistä. En nyt hämmästykseltäni jaksa perehtyä koodiin, mutta tuo esimerkkisivu kyllä säväytti valtavasti.

Upeaa Antti! :)

Metabolix [08.07.2004 00:19:51]

#

Olisi mielestäni hienompi, jos mustien koskettimien CheckBoxit olisivat kosketinten päällä, jos reunat eivät paista siitä liikaa..? Jos niiden taustan saisi mustaksi ja rastin valkoiseksi? (en usko, mutta kysympähän vaan.) En oikein pidä merkinnästä valkoisten kosketinten välissä (6-säveliset soinnut kun joutuu oikeasti soittamaan niin)

jrantala [08.07.2004 08:30:13]

#

Kieltämättä aika näppärä :)

Heikki [08.07.2004 12:02:41]

#

Kaikkeen se PHP venyykin! Hyvää jälkeä...

nomic [08.07.2004 13:14:36]

#

mä mitää ymmärrä php:sta mutta loistava on!
tästä sainkin idean että voisi kokeilla vääntää ite vb:llä jotain pientä yksinkertaista trackeria :)

sooda [08.07.2004 14:31:31]

#

Enpäs olisi uskonut että php:lläkin tollaisen voi tehdä.

TH [08.07.2004 18:33:06]

#

Todella hieno! :)

Nyntti [09.07.2004 03:50:08]

#

kaunista. soinnutkin pitävät paikkansa, pisteitä tulee dimeistä ja susseista jotka ovat varmasti tehneet hommasta hankalamman =)

setä [09.07.2004 09:09:15]

#

On tosiaan hieno PHP-sovellus. Pitäiskö ton soittaa suoraan. Mulla joka soittokerralla ilmaantuu erikseen ruutu jota klikkaamalla ladataan miditiedosto ja sen jälkeen vasta tulee ääni.

Meitsi [09.07.2004 12:11:13]

#

Ei toimi. Mediaplayer&RealOne valittaa että tiedosto on viallinen.
EDIT: alko toimii

Puhveli [09.07.2004 13:48:30]

#

kuudessadaskuudeskymmeneskuudes vinkki :)

Spuntte [10.07.2004 12:33:25]

#

Erittäin hieno ja selkeä systeemi

tono [10.07.2004 13:21:55]

#

mistä ton midi tiedoston saa

Mv [11.07.2004 21:42:41]

#

Todella tyylikäs ja ammattitaitoinen. Tulee jo mieleen http://www.looknohands.com/

thuge94 [18.06.2005 20:31:48]

#

Siis erittäin mahtava, kertakaikkian loistava, paitsi että midit eivät ole kelvollisia. Niin WinAmp, Windows mediaplayer kuin realplayerkaan eivät midejä toista.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta