Hlavní navigace

Pohled pod kapotu JVM – přehrávání hudby s využitím knihovny SDLJava

29. 4. 2014
Doba čtení: 36 minut

Sdílet

V dnešní části seriálu o JVM i o jazyku Java se budeme zabývat poměrně rozsáhlou problematikou hudebních souborů i přehrávání hudby. Díky existenci třídy SDLMixer v knihovně SDLJava se však celý problém z hlediska programátora do značné míry zjednodušuje, jak si ostatně ukážeme na několika příkladech.

Obsah

1. Pohled pod kapotu JVM – přehrávání hudby s využitím knihovny SDLJava

2. Velikost bufferů a formát samplů

3. Formáty hudebních souborů

4. Hudební formát MIDI

5. Demonstrační příklad SDLTest62 – přehrání skladby uložené ve formátu MIDI

6. Zvukový formát Ogg Vorbis

7. Demonstrační příklad SDLTest63 – přehrání skladby uložené ve formátu Ogg Vorbis

8. Hudební formát Amiga MOD

9. Demonstrační příklad SDLTest64 – přehrání skladby uložené ve formátu MOD

10. Demonstrační příklad SDLTest65 – jednoduchý hudební přehrávač

11. Repositář se zdrojovými kódy všech čtyř dnešních demonstračních příkladů

12. Odkazy na Internetu

1. Pohled pod kapotu JVM – přehrávání hudby s využitím knihovny SDLJava

V předchozí části tohoto seriálu jsme se ve stručnosti seznámili s možnostmi, které programátorům knihovna SDLJava nabízí v oblasti přehrávání zvuků i hudby a při mixování jednotlivých zvukových zdrojů. Celý zvukový subsystém knihovny SDLJava je z hlediska programátora implementován v balíčcích sdljava.audiosdljava.mixer, přičemž se v současné verzi knihovny SDLJava naprostá většina použitelných metod a funkcí nachází ve třídách dostupných v balíčku sdljava.mixer, zejména ve třídě sdljava.mixer.SDLMixer. S využitím této třídy je možné jednoduše přehrávat hudbu či zvuky, nastavovat hlasitost jednotlivých zvukových kanálů, automaticky zajistit postupné snížení hlasitosti, aplikovat další zvukové filtry na přehrávaný zvuk atd. Možnosti nabízené touto třídou jsou skutečně velké, ovšem samotné rozhraní (dostupné metody a atributy) zůstává velmi jednoduché, o čemž se ostatně přesvědčíme v navazujících kapitolách.

Inicializace zvukového subsystému v knihovně SDLJava se provádí ve dvou krocích. Nejprve je nutné zvukový subsystém povolit při volání metody SDLMain.init(), a to například následujícím způsobem:

SDLMain.init(SDLMain.SDL_INIT_AUDIO);

Ve skutečnosti však většina aplikací vyžaduje současné použití většího množství subsystémů nabízených knihovnou SDLJava. Řešení je velmi jednoduché – postačí vhodným způsobem sloučit konstanty reprezentující jednotlivé subsystémy, a to buď bitovým operátorem OR nebo prostým součtem konstant:

SDLMain.init(SDLMain.SDL_INIT_VIDEO | SDLMain.SDL_INIT_AUDIO);

Následně se přes metodu SDLMixer.openAudio(frequency, format, channels, chunksize) provede konfigurace zvukového subsystému. Význam jednotlivých hodnot předávaných této metodě si vysvětlíme v navazující kapitole.

2. Velikost bufferů a formát samplů

Prvním parametrem metody SDLMixer.openAudio() je vzorkovací frekvence použitá při mixování i přehrávání. Naprostá většina zvukových čipů v současných počítačích by měla zvládat „CD-kvalitu“ a tedy i vzorkovací frekvenci 44100 samplů za sekundu.

Při inicializaci zvukového subsystému je taktéž nutné zvolit formát zvukových vzorků (samplů), který je interně používán při mixování jednotlivých zvukových kanálů i při mixování hudby. V současné verzi knihovny SDLJava je možné si vybrat mezi osmibitovými vzorky či vzorky šestnáctibitovými, které samozřejmě produkují zvuk s vyšší dynamikou (teoreticky až 96dB) oproti osmibitovým vzorkům (až 48dB). Volit lze taktéž formát jednotlivých samplů – se znaménkem (signed) či bez znaménka (unsigned) a u šestnáctibitových vzorků i uspořádání bajtů v šestnáctibitovém slovu. V následující tabulce jsou vypsány všechny podporované formáty zvukových vzorků (samplů):

# Konstanta Bitů/vzorek Formát
1 SDLMixer.AUDIO_S8 8 se znaménkem
2 SDLMixer.AUDIO_U8 8 bez znaménka
3 SDLMixer.AUDIO_S16 16 se znaménkem, little endian, nativní pořadí bajtů
4 SDLMixer.AUDIO_U16 16 se znaménkem, big endian, nativní pořadí bajtů
5 SDLMixer.AUDIO_S16LSB 16 se znaménkem, little endian
6 SDLMixer.AUDIO_S16MSB 16 se znaménkem, big endian
7 SDLMixer.AUDIO_S16SYS 16 se znaménkem, nativní (podle použitého CPU)
8 SDLMixer.AUDIO_U16LSB 16 bez znaménka, little endian
9 SDLMixer.AUDIO_U16MSB 16 bez znaménka, big endian
10 SDLMixer.AUDIO_U16SYS 16 bez znaménka, nativní (podle použitého CPU)

Poznámka: v knihovně SDL 2.0 jsou podporovány i další formáty vzorků, ovšem knihovna SDLJava je postavena na SDL 1.2, takže tyto další formáty zde nelze využít.

Ve třetím parametru se uvádí počet výstupních kanálů, tj. například 1 pro mono výstup a 2 pro stereo výstup. Důležitý je poslední parametr, v němž se udává velikost bufferu použitého zvukovým subsystémem. Příliš malá velikost bufferu může vést ke slyšitelným cvakáním při přehrávání, příliš velké buffery na druhou stranu neumožňují měnit přehrávané zvuky tak rychle, jak si to může vyžádat například programovaná hra. My v demonstračních příkladech používáme hodnotu 4096, která je vhodná především při přehrávání hudby – tento buffer je dostatečně velký na to, aby ani na pomalejších počítačích nedocházelo k poruchám při přehrávání.

3. Formáty hudebních souborů

Knihovna SDLJava podporuje při přehrávání hudby poměrně velké množství různých hudebních a zvukových formátů, které jsou vypsány v následující tabulce:

# Typ (koncovka souboru) Popis
1 .wav zvukové vzorky uložené ve formátu WAVE/RIFF
2 .voc zvukové vzorky uložené ve formátu VOC
3 .mod Amiga moduly a odvozené formáty (viz též osmou kapitolu)
4 .xm Amiga moduly a odvozené formáty (viz též osmou kapitolu)
5 .s3m Amiga moduly a odvozené formáty (viz též osmou kapitolu)
6 .669, Amiga moduly a odvozené formáty (viz též osmou kapitolu)
7 .it Amiga moduly a odvozené formáty (viz též osmou kapitolu)
8 .midi Hudební formát MIDI, viz též čtvrtou kapitolu
9 .ogg Zvukový/hudební formát Ogg Vorbis

V případě ručně provedené konfigurace je možná i podpora formátu .mp3 a FLAC, to již však vyžaduje instalaci příslušných nativních knihoven, které však nemusí být vždy dostupné.

Pro úspěšné spuštění dnešních čtyř demonstračních příkladů je nutné mít v pracovním adresáři uloženu čtveřici hudebních souborů (formát MIDI, Ogg Vorbis a Amiga MOD), které je možné získat s využitím následující trojice skriptů (soubory je samozřejmě možné z uvedených URL stáhnout i přes prohlížeč WWW). Většinu skladeb pravděpodobně čtenáři budou znát.

Stažení dvojice souborů Für_Elise.midDuke Nukem 3D – Grabbag (Theme from Duke Nukem 3D).mid:

wget http://upload.wikimedia.org/wikipedia/commons/d/da/Für_Elise.mid
wget "http://www.midiarchive.co.uk/files/Games/Duke%20Nukem%203D/Duke%20Nukem%203D%20-%20Grabbag%20(Theme%20from%20Duke%20Nukem%203D).mid"

Stažení souboru Toccata_et_Fugue_BWV565.ogg:

wget http://upload.wikimedia.org/wikipedia/commons/b/be/Toccata_et_Fugue_BWV565.ogg

Stažení souboru aquarius.mod:

wget -O mod.zip http://modarchive.org/data/downloads.php?moduleid=96202#aquarius.mod
unzip mod.zip

4. Hudební formát MIDI

Knihovna SDLJava umožňuje mj. přehrávat hudbu uloženou ve formátu MIDI, přesněji řečeno ve formátu specifikovaném ve standardu General MIDI neboli zkráceně GM. Ve stručnosti se dá říci, že General MIDI v některých oblastech upřesňuje (a zpřísňuje) původní normu MIDI. Například všechna zařízení, která se označují jako GM-compatible, musí dokázat současně přehrát minimálně 24 tónů, tj. mají čtyřiadvacetihlasou polyfonii, přičemž minimálně 16 tónů je melodických spolu s osmi bicími. Tato zařízení také musí podporovat všech šestnáct hudebních kanálů, přičemž kanál číslo 10 je rezervován pro bicí nástroje. Taktéž jsou v této normě přesně určena čísla hudebních nástrojů, která se nastavují pomocí zprávy Program Change. U GM-compatible zařízení je tedy jisté, že nástroj číslo jedna bude vždy hrát jako klavír atd.

Ve standardu General MIDI je kromě dalších požadavků specifikován i formát souborů označovaných zkratkou SMF, neboli Standard MIDI File. Jedná se o binární soubory, které mají většinou příponu .mid; u některých rozšířených verzí se však koncovka může lišit. Tyto soubory se díky své poměrně jednoduché struktuře, úspornému záznamu hudby a otevřenosti formátu hojně rozšířily, a to jak mezi hudebníky (mnohé klávesy například obsahují disketovou jednotku nebo USB rozhraní, ze kterých je možné SMF soubory přehrávat), tak i mezi majiteli osobních počítačů. V souborech typu SMF může být uložena buď jedna hudební stopa, nebo – v případě použití většího množství hudebních nástrojů – větší množství stop.

Hudba přitom není uložena ve formě digitalizovaného a popř. komprimovaného zvuku, jak je tomu například v případě formátu WAVE (RIFF), Ogg Vorbis či MP3, ale jako posloupnost takzvaných událostí (events), což jsou ve svém principu takzvané MIDI zprávy doplněné o časovou značku tak, aby bylo možné přesně zaznamenat i začátek a konec přehrávání určitého tónu nebo celého akordu. Vzhledem k tomu, že každá událost je uložená pouze v několika bajtech, bývají soubory SMF/MIDI velmi malé – celá několikaminutová skladba se může zapsat do souboru majícího velikost jen několik málo kilobajtů.

Ve standardu jsou popsány tři typy (subformáty) souborů SMF, které jsou označovány jako Type-0, Type-1 a Type-2. V minulosti se velmi často používal typ 0, jehož interní struktura je nejjednodušší (obsahuje totiž jen jednu hudební stopu), ovšem například záznam vícehlasé hudby musí být řešen pomocí triku. Dnes se můžeme často setkat s typem 1, jehož přednost spočívá v možnosti použití většího množství hudebních stop (1 až 65535), přičemž události pro každý hudební nástroj jsou uloženy v samostatné stopě. Typ 2 se prozatím příliš nerozšířil. Z tohoto důvodu bude další popis zaměřen především na subformáty Type-0 a Type-1. Před podrobnějším popisem interní struktury souborů SMF si připomeňme, že v General MIDI jsou přesně stanovena čísla pro jednotlivé typy hudebních nástrojů (viz zpráva typu Program Change) a desátý kanál je vyhrazen pro bicí (perkusní) nástroje, u nichž se většinou nezaznamenává výška jimi generovaného zvuku (přehrávaná nota).

Vlastní zvuky hudebních nástrojů v souborech SMF uloženy nejsou, což představuje poměrně velký rozdíl oproti formátům typu MOD (Amiga Module) či XM, v nichž jsou uloženy jak hudební stopy, tak i samply nástrojů či jiných zvuků (u SMF se o přehrávání stará samotné cílové hudební zařízení, které musí zvuky všech nástrojů přehrát – jak praví norma – „s dostatečnou kvalitou“). Následuje výpis jednotlivých skupin hudebních nástrojů tak, jak jsou popsány v General MIDI (tato čísla ostatně najdete i na mnoha „klávesách“):

Číslo programu/nástroje Skupina nástrojů
01 – 08 klavíry
09 – 16 laděné bicí
17 – 24 varhany
25 – 32 kytary
33 – 40 basové zvuky
41 – 48 smyčce
49 – 56 ansáblové zvuky
57 – 64 žestě
65 – 72 plátkové
73 – 80 píšťaly
81 – 88 elektronické sólové zvuky
89 – 96 elektronické doprovodné zvuky
97 – 104 elektronické zvukové efekty
105 – 112 etnické
113 – 120 perkusní
121 – 128 zvukové efekty

Soubory SMF na svém začátku obsahují hlavičku, po které následují data jednotlivých hudebních stop s ukončovací značkou. Každá část souboru (hlavička, stopa) začíná čtyřmi bajty, které lze chápat jako čtyři ASCII znaky textu (v tomto ohledu se SMF přibližuje například populárnímu grafickému formátu PNG, v němž jednotlivé chunky taktéž začínají čtveřicí ASCII znaků). Ostatní data jsou většinou uložena v binární podobě, přičemž hodnoty, které se kvůli svému maximálnímu rozsahu nevejdou do jednoho bajtu, jsou uloženy systémem nižší bajt–vyšší bajt (totéž platí i v případě, že je hodnota uložena na čtyřech bajtech). Hlavička obsahuje základní informace o souboru SMF, především jeho typ (viz předchozí odstavce), počet hudebních stop a základní rychlost přehrávání. Délka hlavičky je u standardních souborů rovna čtrnácti bajtům s následujícím významem:

Offset Délka (bajty) Význam
00 4 ASCII text ‚MThd‘ – MIDI header
04 4 délka zbytku hlavičky, pro standardní soubory je zde hodnota 6
08 2 typ (subformát) SMF souboru – 0000=Type-0, 0001=Type-1
10 2 počet stop, 1 až 65535 (pro subformát 1)
12 2 rychlost přehrávání hudby (počet tiků na přehrání čtvrťové noty; čím vyšší hodnota, tím rychleji se hudba přehrává)

Následuje ukázka formátu hlavičky skutečného (dosti známého) souboru DukeNukem_Level1.mid uloženého ve formátu SMF:

Offset Obsah (hexa) Význam
00 4d 54 68 64 ASCII text ‚MThd‘ – MIDI header
04 00 00 00 06 délka zbytku hlavičky je rovna šesti bajtům
08 00 01 typ souboru = Type-1
10 00 0d počet stop je roven třinácti
12 00 90 rychlost přehrávání hudby je nastavena na 0×90 (0×80 odpovídá čtvrtinové notě)

Ihned po hlavičce souboru SMF následují hudební data, tj. informace o jednotlivých hudebních stopách, přičemž každá hudební stopa začíná čtveřicí bajtů s hodnotami 0×4D, 0×54, 0×72 a 0×6B, což odpovídá ASCII znakům „MTrk“ – MIDI track. Jak jsme si již řekli v úvodních odstavcích, je hudba zaznamenána ve formě takzvaných událostí (events), přičemž každá událost odpovídá MIDI zprávě doplněné o časovou značku. Nejjednodušší události mají délku čtyři bajty, přičemž v prvním bajtu je zaznamenána časová značka, po níž následuje klasická tříbajtová MIDI zpráva. Pokud například budeme chtít postupně přehrát tři noty C, DE, postačuje použít tři události odpovídající zprávám Note On, za nimiž budou následovat tři zprávy Note Off – viz následující fragment obsahu SMF souboru:

Bajty v souboru Událost Význam
00 90 3C 60 Note On Začne se přehrávat nota C, rychlost náběhu je rovna 0×60
7F 90 3E 60 Note On Začne se přehrávat nota D, rychlost náběhu je rovna 0×60
7F 90 40 60 Note On Začne se přehrávat nota E, rychlost náběhu je rovna 0×60
7F 80 3C 00 Note Off Konec přehrávání noty C
00 80 3E 00 Note Off Konec přehrávání noty D
00 80 40 00 Note Off Konec přehrávání noty E

Každá událost začíná časovou značkou. Nejedná se o absolutně zapsaný čas, ale o časový rozdíl mezi okamžikem poslední události a události, která právě začíná probíhat (počet tiků trvání jedné čtvrťové noty je uložen v hlavičce). Například pokud potřebujeme přehrávat tóny v pravidelném rytmu, tj. jednotlivé noty mají zaznít po 00, 10, 20, 30, 40 a 50 časových jednotkách, budou mít časové značky hodnoty 00, 10, 10, 10, 10, 10, protože 10–0=10, 20–10=10, 30–20=10 atd. Hodnota 00 značí nulovou pauzu, tj. dvě nebo více událostí mohou proběhnout přesně v tom samém časovém okamžiku. V případě, že je časový rozdíl reprezentován hodnotu menší než 0×7f (127 dekadicky), je situace velmi jednoduchá – časová značka má délku jednoho bajtu, který je zapsán jako první bajt dané události.

Ovšem ve skutečnosti je někdy nutné zadávat i mnohem delší časové rozdíly. Ty se ukládají do většího počtu bajtů (počet bajtů je proměnlivý od jednoho do čtyř), přičemž všechny bajty kromě posledního mají hodnotu větší než 0×7f (127 dekadicky), protože je u nich uměle nastaven nejvyšší bit a pouze do posledního bajtu je zapsána hodnota menší než 0×7f. Maximální čas, který lze tímto způsobem reprezentovat, lze uložit jako sekvenci bajtů 0×ff 0×ff 0×ff 0×7f. Při překódování na hexadecimální číslo dojdeme k hodnotě 0×0fffffff (nesmíme zapomenout na to, že se v souborech SMF nejdříve ukládá bajt s nejnižší váhou), což v desítkové číselné soustavě odpovídá 228=268435456. Příklad záznamu některých hodnot časových značek:

Ukládaná hodnota (desítkově) Sekvence bajtů (hex)
1 01
127 7f
128 81 00
129 81 01
255 81 7f
256 82 00

Literatura zabývající se problematikou MIDI a General MIDI:

  1. Arnell, Billy. „McScope: System.“ Music, Computers, and Software,
    April 1988: 58–60. Conger, Jim. C Programming for MIDI.
    Redwood City: M & T Books, 1988.
  2. Cooper, Jim. „Mind Over MIDI: Information Sources and System-exclusive Data Formats.“,
    Keyboard October, 1986: 110–111.
  3. Enders, Bernd and Wolfgang Klemme. MIDI and Sound Book for the Atari ST.
    Redwood City: M & T Books, 1989.
  4. Matzkin, Jonathan. „A MIDI Musical Offering.“
    PC Magazine 29 Nov. 1988: 229+.
  5. Peters, Constantine. „Reading up on MIDI for the Novice and the Pro.“
    PC Magazine 29 Nov. 1988: 258.
  6. Basic MIDI, Paul White,
    Sanctuary Publishing Ltd, London 1999.
    ISBN 1 86074 262 9
  7. A Beginner's Guide to MIDI,
    R A Penfold, Babani Publishing Ltd,
    London 1993. ISBN 0 85934 331 6
  8. MIDI for Organists,
    C E Pykett

5. Demonstrační příklad SDLTest62 – přehrání skladby uložené ve formátu MIDI

Jak je patrné z popisu formátů souborů SMF/Midi, kterým jsme se zabývali v předchozí kapitole, musí být interní struktura přehrávače těchto souborů poměrně komplikovaná a navíc musí mít přehrávač k dispozici zvuky všech podporovaných hudebních nástrojů, ať již v podobě jednotlivých samplů či v knihovně parametrů předávaných například audio čipu s podporou FM syntézy (sound bank). Pokud se však podíváme do zdrojového kódu dnešního prvního demonstračního příkladu pojmenovaného SDLTest62, uvidíme, je při použití knihovny SDLJava je řešení velice jednoduché a krátké – pouze nám postačí inicializovat zvukový subsystém, nastavit velikost bufferů a formát samplů a posléze je již možné přehrát hudbu a testovat ukončení přehrávání následující sekvencí příkazů:

// nacteni hudby z externiho souboru
MixMusic music = SDLMixer.loadMUS(MUSIC_FILE);
 
// prehrani hudby
SDLMixer.playMusic(music, -1);
 
// musime pockat na ukonceni prehravani
while (SDLMixer.playingMusic()) {
    SDLTimer.delay(100);
}

Podívejme se nyní na úplný zdrojový kód dnešního prvního demonstračního příkladu:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.SDLTimer;
 
import sdljava.mixer.SDLMixer;
import sdljava.mixer.MixMusic;
 
 
 
/**
 * Sedesaty druhy demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Prehrani hudebniho souboru MIDI s vyuzitim audio subsystmu knihovny SDLJava.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest62 {
 
    /**
     * Jmeno souboru obsahujiciho hudbu.
     */
    private static final String MUSIC_FILE = "Für_Elise.mid";
 
    /**
     * Prehrani hudby.
     */
    public static void playMusic() throws SDLException, InterruptedException {
        // nastaveni vlastnosti zvukoveho subsystemu i vybranych zvukovych kanalu
        SDLMixer.openAudio(44100, SDLMixer.AUDIO_S16, 1, 1024);
        SDLMixer.volumeMusic(100);
 
        // nacteni hudby z externiho souboru
        MixMusic music = SDLMixer.loadMUS(MUSIC_FILE);
 
        // prehrani hudby
        SDLMixer.playMusic(music, -1);
 
        // musime pockat na ukonceni prehravani
        while (SDLMixer.playingMusic()) {
            SDLTimer.delay(100);
        }
    }
 
    /**
     * Spusteni sedesateho druheho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace knihovny SDLJava
            SDLMain.init(SDLMain.SDL_INIT_AUDIO);
 
            // prehrani hudby
            playMusic();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            SDLMain.quit();
        }
    }
 
}

Skript pro překlad tohoto demonstračního příkladu na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest62.java

Dávkový soubor pro překlad tohoto demonstračního příkladu na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest62.java

Skript pro spuštění na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
java -cp .:$SDL_JAVA_LIBS/sdljava.jar -Djava.library.path=$SDL_JAVA_LIBS SDLTest62

Dávkový soubor pro spuštění na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
java -cp .;%SDL_JAVA_LIBS%\sdljava.jar -Djava.library.path=%SDL_JAVA_LIBS% SDLTest62

6. Zvukový formát Ogg Vorbis

Dalším zvukovým (a současně i hudebním) formátem podporovaným knihovnou SDLJava je Vorbis. Jedná se o ztrátový zvukový formát, který (minimálně v open source světě) postupně nahrazuje formát MP3, jenž je pro některé aplikace nevhodný (například pro mluvené slovo či pro přenos po kanálu s větší pravděpodobností vzniku chyb). Předností formátu Vorbis je mj. i licence BSD, pod níž je referenční implementace uvolněna (s MP3 mohou být z tohoto pohledu problémy, viz například http://www.chillingeffects­.org/patent/notice.cgi?No­ticeID=464). Zvukový formát Vorbis se většinou nepoužívá samostatně, ale ve spojení s kontejnerem Ogg; právě kvůli tomu se setkáme s označením Ogg Vorbis (nebo též pouze Ogg podle koncovky souborů, což je však nepřesné, neboť Ogg je skutečně pouze kontejnerem, který obaluje datové bloky různých typů – ztrátové i neztrátové audio, ztrátové i neztrátové video i text či titulky).

7. Demonstrační příklad SDLTest63 – přehrání skladby uložené ve formátu Ogg Vorbis

V demonstračním příkladu nazvaném SDLTest63 je ukázáno, že přehrání hudební skladby uložené ve formátu Ogg Vorbis je stejně snadné jako přehrání skladby uložené ve formátu (General)MIDI. Liší se pouze jméno souboru se skladbou; o všechny další operace, které již v tomto případě jsou velmi komplikované, se automaticky postará zvukový subsystém knihovny SDLJava a nativní knihovny, které jsou z SDLJava volány. Povšimněte si, že samplovací frekvence a formát vzorků specifikovaný při inicializaci zvukového subsystému nemusí odpovídat a mnohdy taktéž neodpovídá formátu použitém přímo v souborech typu Ogg Vorbis:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.SDLTimer;
 
import sdljava.mixer.SDLMixer;
import sdljava.mixer.MixMusic;
 
 
 
/**
 * Sedesaty treti demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Prehrani hudebniho souboru Ogg Vorbis s vyuzitim audio subsystmu knihovny SDLJava.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest63 {
 
    /**
     * Jmeno souboru obsahujiciho hudbu.
     */
    private static final String MUSIC_FILE = "Toccata_et_Fugue_BWV565.ogg";
 
    /**
     * Prehrani hudby.
     */
    public static void playMusic() throws SDLException, InterruptedException {
        // nastaveni vlastnosti zvukoveho subsystemu i vybranych zvukovych kanalu
        SDLMixer.openAudio(44100, SDLMixer.AUDIO_S16, 1, 1024);
        SDLMixer.volumeMusic(100);
 
        // nacteni hudby z externiho souboru
        MixMusic music = SDLMixer.loadMUS(MUSIC_FILE);
 
        // prehrani hudby
        SDLMixer.playMusic(music, -1);
 
        // musime pockat na ukonceni prehravani
        while (SDLMixer.playingMusic()) {
            SDLTimer.delay(100);
        }
    }
 
    /**
     * Spusteni sedesateho tretiho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace knihovny SDLJava
            SDLMain.init(SDLMain.SDL_INIT_AUDIO);
 
            // prehrani hudby
            playMusic();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            SDLMain.quit();
        }
    }
 
}

Skript pro překlad tohoto demonstračního příkladu na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest63.java

Dávkový soubor pro překlad tohoto demonstračního příkladu na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest63.java

Skript pro spuštění na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
java -cp .:$SDL_JAVA_LIBS/sdljava.jar -Djava.library.path=$SDL_JAVA_LIBS SDLTest63

Dávkový soubor pro spuštění na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
java -cp .;%SDL_JAVA_LIBS%\sdljava.jar -Djava.library.path=%SDL_JAVA_LIBS% SDLTest63

8. Hudební formát Amiga MOD

Dalším hudebním formátem, s nímž může knihovna SDLJava pracovat, jsou takzvané moduly, které byly vyvinuty na slavných osobních mikropočítačích Amiga. Tyto počítače totiž obsahovaly zvukový čip Paula, jenž dokázal v základním nastavení pracovat se čtyřmi zvukovými kanály, u nichž bylo možné měnit frekvenci přehrávání osmibitových samplů. Poměrně záhy po rozšíření počítačů Amiga vznikly aplikace nazvané trackery, které této vlastnosti Pauly důsledně využívaly. Pomocí trackerů bylo (či spíše doposud je) možné vytvořit hudbu složenou ze samplů, které se přehrávají s různou frekvencí na základě údajů uložených ve čtyřech hudebních stopách – jedná se vlastně o obdobu notové osnovy, ovšem zapisovanou ve formě tabulky s 64 řádky a původně čtyřmi sloupci (každý sloupec odpovídá jednomu hudebnímu kanálu).

V každém řádku je možné do sloupce zapsat notu a oktávu (tj. výšku či frekvenci přehrávaného tónu), číslo nástroje (tomu odpovídá zvolený sampl, přesněji více samplů může v některých trackerech být přiřazeno jednomu nástroji v závislosti na výšce tónu), hlasitost a příznak, zda se má současně provést i nějaký zvukový efekt. Tabulka s výše popsanými 64 řádky se nazývá pattern, přičemž celá hudební skladba může být složena z libovolného množství patternů.

Soubory, do kterých se skladby vytvořené pomocí trackerů ukládají, se nazývají moduly. Původní moduly se čtyřmi stopami, patternem dlouhým 64 řádků a osmibitovými samply (mohlo jich být maximálně 31) byly vytvářeny programem ProTracker – jím vytvářené soubory mají příponu .mod a i dnes se s nimi můžeme poměrně často setkat (v našich končinách byl populární například modul mrazik.mod). Formát modulů je poměrně jednoduchý – v souboru jsou uloženy jak jednotlivé samply hudebních nástrojů (u původních modulů v nekomprimované podobě), tak i jména samplů, jednotlivé patterny (tabulky) a další důležité informace, například rychlost posunu mezi řádky patternu (tato rychlost odpovídá tempu skladby a lze ji během přehrávání měnit, čehož se často využívalo).

Společně s dalším rozšiřováním možností trackerů se postupně měnil a rozšiřoval i formát souborů, i když jejich základní struktura zůstala zachována. Především se zvyšoval počet zvukových kanálů z původních čtyř přes osm kanálů (Octalyzer) až na 32 kanálů ve formátu podporovaném ScreamTrackerem (soubory s příponou .stm a .s3m). Některé formáty také dokázaly ukládat samply hudebních nástrojů v komprimované podobě, používat šestnáctibitové samply, samply se smyčkou (loop) atd. Již zmíněný ScreamTracker (vytvořený mimo jiné známou demo skupinou Future Crew) dokonce dokázal do samplované hudby přimíchat hudbu generovanou pomocí FM syntézy (syntéza zvuku s využitím frekvenční a fázové modulace podporovaná některými zvukovými čipy). FastTracker II (od konkurenční skupiny Triton) naproti tomu podporoval „obousměrnou“ smyčku, kdy se sampl po dosažení konce smyčky střídavě přehrával v přímém směru a posléze odzadu apod.

Hudební moduly se staly jak mezi autory hudby, tak i mezi posluchači velice populární, především díky poměrně velké kvalitě přehrávané hudby a rozumné velikosti souborů – většina skladeb se bez problémů dala nahrát na jedinou disketu (880 kB v případě Amigy) a později stáhnout z Internetu i s využitím pomalého modemu. Vzhledem ke stále velké popularitě modulů a jejich relativně jednoduchému formátu (navíc nezatíženému patenty) není divu, že pro velkou část dnešních multimediálních přehrávačů existují pluginy, které dokážou alespoň ty nejrozšířenější typy modulů (.mod, .stm, .s3m) přehrát. Jedná se jak o přehrávače pro Linux (XMMS, Audacious), tak i pro Microsoft Windows (WinAmp). Kromě toho je možné použít i specializované přehrávače, například multiplatformní MikMod for Java (odvozený od původního MikModu napsaného v ANSI C). Není tedy divu, že podpora pro moduly je dostupná i v knihovně SDL a přeneseně i v knihovně SDLJava.

9. Demonstrační příklad SDLTest64 – přehrání skladby uložené ve formátu MOD

Přehrání hudebních souborů uložených ve formátu Amiga MOD je stejně jednoduché, jako v případě již zmíněných formátů MIDI a Ogg Vorbis. Samotné zahájení přehrávání je shodné, liší se jen funkce setMusicPosition() pro změnu pozice v přehrávaném souboru (rewind). U souborů typu MOD je této funkci předáno číslo odpovídající patternu (viz též předchozí kapitola), zatímco například u souborů Ogg Vorbis předávaná hodnota odpovídá počtu sekund (či jejich desetin) počítaných od začátku přehrávání. Podívejme se nyní na zdrojový kód demonstračního příkladu pojmenovaného SDLTest64, který načte a posléze přehraje hudební soubor aquarius.mod, jenž lze nalézt na adrese http://modarchive.org/data/dow­nloads.php?moduleid=96202#a­quarius.mod:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.SDLTimer;
 
import sdljava.mixer.SDLMixer;
import sdljava.mixer.MixMusic;
 
 
 
/**
 * Sedesaty ctvrty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Prehrani hudebniho souboru MOD s vyuzitim audio subsystmu knihovny SDLJava.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest64 {
 
    /**
     * Jmeno souboru obsahujiciho hudbu.
     */
    private static final String MUSIC_FILE = "aquarius.mod";
 
    /**
     * Prehrani hudby.
     */
    public static void playMusic() throws SDLException, InterruptedException {
        // nastaveni vlastnosti zvukoveho subsystemu i vybranych zvukovych kanalu
        SDLMixer.openAudio(44100, SDLMixer.AUDIO_S16, 1, 1024);
        SDLMixer.volumeMusic(100);
 
        // nacteni hudby z externiho souboru
        MixMusic music = SDLMixer.loadMUS(MUSIC_FILE);
 
        // prehrani hudby
        SDLMixer.playMusic(music, -1);
 
        // musime pockat na ukonceni prehravani
        while (SDLMixer.playingMusic()) {
            SDLTimer.delay(100);
        }
    }
 
    /**
     * Spusteni sedesateho ctvrteho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace knihovny SDLJava
            SDLMain.init(SDLMain.SDL_INIT_AUDIO);
 
            // prehrani hudby
            playMusic();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            SDLMain.quit();
        }
    }
 
}

Skript pro překlad tohoto demonstračního příkladu na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest64.java

Dávkový soubor pro překlad tohoto demonstračního příkladu na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest64.java

Skript pro spuštění na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
java -cp .:$SDL_JAVA_LIBS/sdljava.jar -Djava.library.path=$SDL_JAVA_LIBS SDLTest64

Dávkový soubor pro spuštění na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
java -cp .;%SDL_JAVA_LIBS%\sdljava.jar -Djava.library.path=%SDL_JAVA_LIBS% SDLTest64

10. Demonstrační příklad SDLTest65 – jednoduchý hudební přehrávač

Poslední demonstrační příklad pojmenovaný SDLTest65 je ze všech čtyř dnešních příkladů nejdelší. Jedná se totiž o jednoduchý hudební přehrávač ovládaný z klávesnice, který kromě přehrávání hudby dokáže měnit hlasitost (klávesy + a -), zastavit a spustit hudbu (klávesa C, převzato z legendárního WinAMPu) a aplikovat efekty fade in a fade out (klávesy I a O). Při stisku klávesy Q nebo Esc program nejdříve ztišší hudbu a následně se korektně ukončí. Aby bylo možné používat klávesnici, musí aplikace vytvořit okno, které následně získá fokus. I uzavření okna vede ke korektnímu ukončení aplikace (opět s efektem fade out). Podívejme se nyní na celý zdrojový kód tohoto demonstračního příkladu:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.SDLTimer;
 
import sdljava.event.SDLEvent;
import sdljava.event.SDLKeyboardEvent;
import sdljava.event.SDLKey;
import sdljava.event.SDLQuitEvent;
 
import sdljava.mixer.SDLMixer;
import sdljava.mixer.MixMusic;
 
import sdljava.video.SDLSurface;
import sdljava.video.SDLVideo;
import sdljava.video.SDLRect;
 
import sdljava.x.swig.SDLPressedState;
 
 
 
/**
 * Sedesaty paty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Primitivni hudebni prehravac.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest65 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 320;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 240;
 
    /**
     * Bitova hloubka vybraneho grafickeho rezimu.
     * (0 znamena automaticky vyber, ovsem lze samozrejme pouzit
     * i hodnoty 8, 16, 24 ci 32, podle vlastnosti graficke karty)
     */
    private static final int GFX_BPP = 0;
 
    /**
     * Jmeno souboru obsahujiciho hudbu.
     */
    private static final String MUSIC_FILE = "aquarius.mod";
 
    /**
     * Objekt reprezentujici prehravanou hudbu.
     */
    private static MixMusic music = null;
 
    /**
     * Hlasitost hudby.
     */
    private static int musicVolume = 100;
 
    /**
     * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani.
     */
    private static SDLSurface initVideo() throws SDLException {
        final long flags = SDLVideo.SDL_DOUBLEBUF;
        return SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags);
    }
 
    /**
     * Zahajeni prehrani hudby.
     */
    public static void startPlayingMusic() throws SDLException, InterruptedException {
        // nastaveni vlastnosti zvukoveho subsystemu i vybranych zvukovych kanalu
        SDLMixer.openAudio(44100, SDLMixer.AUDIO_S16, 1, 1024);
        SDLMixer.volumeMusic(musicVolume);
 
        // nacteni hudby z externiho souboru
        music = SDLMixer.loadMUS(MUSIC_FILE);
 
        // prehrani hudby
        SDLMixer.playMusic(music, -1);
    }
 
    /**
     * Efekt fade out s cekanim na ukonceni efektu.
     */
    private static void fadeOutAndWait() throws SDLException, InterruptedException {
        SDLMixer.fadeOutMusic(1000);
        SDLTimer.delay(1200);
    }
 
    /**
     * Smycka pro zpracovani udalosti.
     */
    private static void eventLoop() throws SDLException, InterruptedException {
        while (true) {
            // precist udalost z fronty
            SDLEvent event = SDLEvent.waitEvent();
 
            // vyskok ze smycky pro zpracovani udalosti pri vyskytu
            // udalosti typu SDLQuitEvent
            if (event instanceof SDLQuitEvent) {
                fadeOutAndWait();
                SDLMixer.haltMusic();
                return;
            }
 
            // stisk ci pusteni klavesy
            if (event instanceof SDLKeyboardEvent) {
                // pretypovani
                final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event;
 
                // symbol/kod klavesy
                final int symbol = keyEvent.getSym();
 
                if (keyEvent.getState() == SDLPressedState.PRESSED) {
                    switch (symbol) {
                        case SDLKey.SDLK_ESCAPE: // klavesa ESC ukonci program
                            fadeOutAndWait();
                            SDLMixer.haltMusic();
                            return;
                        case SDLKey.SDLK_i:      // efekt fade in
                            SDLMixer.fadeInMusic(music, 1, 1000);
                            break;
                        case SDLKey.SDLK_o:      // efekt fade out
                            SDLMixer.fadeOutMusic(1000);
                            break;
                        case SDLKey.SDLK_PLUS:   // zvyseni hlasitosti
                        case SDLKey.SDLK_KP_PLUS:
                            musicVolume += 10;
                            SDLMixer.volumeMusic(musicVolume);
                            break;
                        case SDLKey.SDLK_MINUS:  // snizeni hlasitosti
                        case SDLKey.SDLK_KP_MINUS:
                            musicVolume -= 10;
                            SDLMixer.volumeMusic(musicVolume);
                            break;
                        case SDLKey.SDLK_c:      // pause/unpause
                            if (SDLMixer.pausedMusic()) {
                                SDLMixer.resumeMusic();
                            }
                            else {
                                SDLMixer.pauseMusic();
                            }
                            break;
                        default:
                            break;
                    }
                }
            }
        }
    }
 
    /**
     * Vykresleni sceny na obrazovku ci do okna aplikace.
     * 
     * @param screen
     *            framebuffer
     */
    private static void drawOnScreen(SDLSurface screen) throws SDLException {
        // nutno volat i v pripade, ze neni pouzit double buffering
        screen.updateRect();
        screen.flip();
    }
 
    /**
     * Spusteni sedesateho pateho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace knihovny SDLJava
            SDLMain.init(SDLMain.SDL_INIT_VIDEO | SDLMain.SDL_INIT_AUDIO);
 
            // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani
            final SDLSurface screen = initVideo();
 
            // spusteni prehrani hudby
            startPlayingMusic();
 
            // smycka pro zpracovani udalosti
            eventLoop();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
    }
 
}

Skript pro překlad tohoto demonstračního příkladu na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest65.java

Dávkový soubor pro překlad tohoto demonstračního příkladu na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest65.java

Skript pro spuštění na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
java -cp .:$SDL_JAVA_LIBS/sdljava.jar -Djava.library.path=$SDL_JAVA_LIBS SDLTest65

Dávkový soubor pro spuštění na Windows:

root_podpora

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
java -cp .;%SDL_JAVA_LIBS%\sdljava.jar -Djava.library.path=%SDL_JAVA_LIBS% SDLTest65

11. Repositář se zdrojovými kódy všech čtyř dnešních demonstračních příkladů

Všechny čtyři dnes popsané demonstrační příklady byly společně s podpůrnými skripty určenými pro jejich překlad a následné spuštění uloženy do Mercurial repositáře dostupného na adrese http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/. Podobně jako tomu bylo i v předchozích několika dílech tohoto seriálu, i ke dnešním příkladům jsou přiloženy skripty využitelné pro jejich překlad a spuštění. Navíc byly přidány i skripty využitelné ve Windows:

# Zdrojový soubor/skript Umístění souboru v repositáři
1 SDLTest62.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest62/SDLTest62.ja­va
2 SDLTest62_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest62/SDLTest62_com­pile.sh
3 SDLTest62_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest62/SDLTest62_com­pile_sys.sh
4 SDLTest62_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest62/SDLTest62_run­.sh
5 SDLTest62_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest62/SDLTest62_run_sys­.sh
6 SDLTest62_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest62/SDLTest62_com­pile.bat
7 SDLTest62_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest62/SDLTest62_run­.bat
     
8 SDLTest63.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest63/SDLTest63.ja­va
9 SDLTest63_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest63/SDLTest63_com­pile.sh
10 SDLTest63_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest63/SDLTest63_com­pile_sys.sh
11 SDLTest63_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest63/SDLTest63_run­.sh
12 SDLTest63_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest63/SDLTest63_run_sys­.sh
13 SDLTest63_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest63/SDLTest63_com­pile.bat
14 SDLTest63_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest63/SDLTest63_run­.bat
     
15 SDLTest64.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest64/SDLTest64.ja­va
16 SDLTest64_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest64/SDLTest64_com­pile.sh
17 SDLTest64_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest64/SDLTest64_com­pile_sys.sh
18 SDLTest64_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest64/SDLTest64_run­.sh
19 SDLTest64_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest64/SDLTest64_run_sys­.sh
20 SDLTest64_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest64/SDLTest64_com­pile.bat
21 SDLTest64_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest64/SDLTest64_run­.bat
     
22 SDLTest65.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest65/SDLTest65.ja­va
23 SDLTest65_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest65/SDLTest65_com­pile.sh
24 SDLTest65_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest65/SDLTest65_com­pile_sys.sh
25 SDLTest65_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest65/SDLTest65_run­.sh
26 SDLTest65_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest65/SDLTest65_run_sys­.sh
27 SDLTest65_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest65/SDLTest65_com­pile.bat
28 SDLTest65_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d6723b3c49bd/sdlja­va/SDLTest65/SDLTest65_run­.bat

Nesmíme zapomenout ani na trojici skriptů sloužících pro získání hudebních souborů ve formátech MIDI, Ogg Vorbis i Amiga MOD:

12. Odkazy na Internetu

  1. Musical Instrument Digital Interface,
    http://en.wikipedia.org/wi­ki/Musical_Instrument_Digi­tal_Interface
  2. A MIDI Pedalboard Encode,
    http://www.pykett.org.uk/a_mi­di_pedalboard_encoder.htm
  3. MIDI Note Number, Frequency Table,
    http://tonalsoft.com/pub/news/pitch-bend.aspx
  4. Note names, MIDI numbers and frequencies,
    http://www.phys.unsw.edu.au­/jw/notes.html
  5. The MIDI Specification,
    http://www.gweep.net/~pre­fect/eng/reference/protocol/mi­dispec.html
  6. Essentials of the MIDI protocol,
    http://ccrma.stanford.edu/~cra­ig/articles/linuxmidi/mis­c/essenmidi.html
  7. General MIDI,
    http://en.wikipedia.org/wi­ki/General_MIDI
  8. Obecné MIDI (General MIDI),
    http://www-kiv.zcu.cz/~herout/html_sbo/mi­di/5.html
  9. Custom Chips: Paula
    http://www.amiga-hardware.com/showhardware­.cgi?HARDID=1460
  10. Big Book of Amiga Hardware
    http://www.amiga-resistance.info/bboahfaq/
  11. Amiga Hardware Database
    http://amiga.resource.cx/
  12. ExoticA
    http://www.exotica.org.uk/wi­ki/Main_Page
  13. The absolute basics of Amiga audio
    http://www.sufo.estates.co­.uk/amiga/amimus.html
  14. Wikipedia: Tracker
    http://en.wikipedia.org/wiki/Tracker
  15. Wikipedia: Trackers
    http://en.wikipedia.org/wiki/Trackers
  16. Ultimate Soundtracker
    http://en.wikipedia.org/wi­ki/Ultimate_Soundtracker
  17. Protracker
    http://en.wikipedia.org/wi­ki/ProTracker
  18. Impulse Tracker
    http://en.wikipedia.org/wi­ki/Impulse_Tracker
  19. Scream Tracker
    http://en.wikipedia.org/wi­ki/ScreamTracker
  20. MikMod for Java
    http://jmikmod.berlios.de/
  21. List of audio trackers
    http://en.wikipedia.org/wi­ki/List_of_audio_trackers
  22. Wikipedia: Module File
    http://en.wikipedia.org/wi­ki/Module_file
  23. Wikipedia: Chiptune
    http://en.wikipedia.org/wiki/Chiptune
  24. SDL_mixer 2.0
    http://www.libsdl.org/pro­jects/SDL_mixer/
  25. SDLJava: package sdljava.ttf
    http://sdljava.sourceforge­.net/docs/api/sdljava/ttf/pac­kage-summary.html#package_description
  26. SDLJava: class sdljava.ttf.SDLTTF
    http://sdljava.sourceforge­.net/docs/api/sdljava/ttf/SDLTTF­.html
  27. SDLJava: class sdljava.ttf.SDLTrueTypeFont
    http://sdljava.sourceforge­.net/docs/api/sdljava/ttf/SDLTru­eTypeFont.html
  28. SDL_ttf Documentation
    http://www.libsdl.org/pro­jects/SDL_ttf/docs/
  29. SDL_ttf 2.0 (není prozatím součástí SDLJava)
    http://www.libsdl.org/pro­jects/SDL_ttf/
  30. SDL_ttf doc
    http://www.libsdl.org/pro­jects/SDL_ttf/docs/SDL_ttf_fra­me.html
  31. SDL 1.2 Documentation: SDL_Surface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlsurface.html
  32. SDL 1.2 Documentation: SDL_PixelFormat
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlpixelformat.html
  33. SDL 1.2 Documentation: SDL_LockSurface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdllocksurface.html
  34. SDL 1.2 Documentation: SDL_UnlockSurface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlunlocksurface.html
  35. SDL 1.2 Documentation: SDL_LoadBMP
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlloadbmp.html
  36. SDL 1.2 Documentation: SDL_SaveBMP
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlsavebmp.html
  37. SDL 1.2 Documentation: SDL_BlitSurface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlblitsurface.html
  38. SDL 1.2 Documentation: SDL_VideoInfo
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlvideoinfo.html
  39. SDL 1.2 Documentation: SDL_GetVideoInfo
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlgetvideoinfo.html
  40. glDrawArrays
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawArrays­.xml
  41. glDrawElements
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawElemen­ts.xml
  42. glDrawArraysInstanced
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawArraysIn­stanced.xml
  43. glDrawElementsInstanced
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawElemen­tsInstanced.xml
  44. Root.cz: Seriál Grafická knihovna OpenGL
    http://www.root.cz/serialy/graficka-knihovna-opengl/
  45. Root.cz: Seriál Tvorba přenositelných grafických aplikací využívajících knihovnu GLUT
    http://www.root.cz/serialy/tvorba-prenositelnych-grafickych-aplikaci-vyuzivajicich-knihovnu-glut/
  46. Best Practices for Working with Vertex Data
    https://developer.apple.com/li­brary/ios/documentation/3ddra­wing/conceptual/opengles_pro­grammingguide/Techniquesfor­WorkingwithVertexData/Techni­quesforWorkingwithVertexDa­ta.html
  47. Class BufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/i­mage/BufferStrategy.html
  48. Class Graphics
    http://docs.oracle.com/ja­vase/1.5.0/docs/api/java/aw­t/Graphics.html
  49. Double Buffering and Page Flipping
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/doublebuf.html
  50. BufferStrategy and BufferCapabilities
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/bufferstrategy.html
  51. Java:Tutorials:Double Buffering
    http://content.gpwiki.org/in­dex.php/Java:Tutorials:Dou­ble_Buffering
  52. Double buffer in standard Java AWT
    http://www.codeproject.com/Ar­ticles/2136/Double-buffer-in-standard-Java-AWT
  53. Java 2D: Hardware Accelerating – Part 1 – Volatile Images
    http://www.javalobby.org/fo­rums/thread.jspa?threadID=16840&tstar­t=0
  54. Java 2D: Hardware Accelerating – Part 2 – Buffer Strategies
    http://www.javalobby.org/ja­va/forums/t16867.html
  55. How does paintComponent work?
    http://stackoverflow.com/qu­estions/15544549/how-does-paintcomponent-work
  56. A Swing Architecture Overview
    http://www.oracle.com/technet­work/java/architecture-142923.html
  57. Class javax.swing.JComponent
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html
  58. Class java.awt.Component
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.html
  59. Class java.awt.Component.BltBufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.BltBufferStrategy.html
  60. Class java.awt.Component.FlipBufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.FlipBufferStrategy­.html
  61. Metoda java.awt.Component.isDoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.html#isDoubleBuffe­red()
  62. Metoda javax.swing.JComponent.is­DoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html#isDouble­Buffered()
  63. Metoda javax.swing.JComponent.set­DoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html#setDouble­Buffered(boolean)
  64. Javadoc – třída GraphicsDevice
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsDevice.html
  65. Javadoc – třída GraphicsEnvironment
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsEnvironment.html
  66. Javadoc – třída GraphicsConfiguration
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsConfiguration.html
  67. Javadoc – třída DisplayMode
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Dis­playMode.html
  68. Lesson: Full-Screen Exclusive Mode API
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/
  69. Full-Screen Exclusive Mode
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/exclusivemode.html
  70. Display Mode
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/displaymode.html
  71. Using the Full-Screen Exclusive Mode API in Java
    http://www.developer.com/ja­va/other/article.php/3609776/U­sing-the-Full-Screen-Exclusive-Mode-API-in-Java.htm
  72. Java quick guide: JVM Instruction Set (tabulka všech instrukcí JVM)
    http://www.mobilefish.com/tu­torials/java/java_quickgu­ide_jvm_instruction_set.html
  73. The JVM Instruction Set
    http://mpdeboer.home.xs4a­ll.nl/scriptie/node14.html
  74. MultiMedia eXtensions
    http://softpixel.com/~cwrig­ht/programming/simd/mmx.phpi
  75. SSE (Streaming SIMD Extentions)
    http://www.songho.ca/misc/sse/sse­.html
  76. Timothy A. Chagnon: SSE and SSE2
    http://www.cs.drexel.edu/~tc365/mpi-wht/sse.pdf
  77. Intel corporation: Extending the Worldr's Most Popular Processor Architecture
    http://download.intel.com/techno­logy/architecture/new-instructions-paper.pdf
  78. SIMD architectures:
    http://arstechnica.com/ol­d/content/2000/03/simd.ar­s/
  79. GC safe-point (or safepoint) and safe-region
    http://xiao-feng.blogspot.cz/2008/01/gc-safe-point-and-safe-region.html
  80. Safepoints in HotSpot JVM
    http://blog.ragozin.info/2012/10/sa­fepoints-in-hotspot-jvm.html
  81. Java theory and practice: Synchronization optimizations in Mustang
    http://www.ibm.com/develo­perworks/java/library/j-jtp10185/
  82. How to build hsdis
    http://hg.openjdk.java.net/jdk7/hot­spot/hotspot/file/tip/src/sha­re/tools/hsdis/README
  83. Java SE 6 Performance White Paper
    http://www.oracle.com/technet­work/java/6-performance-137236.html
  84. Lukas Stadler's Blog
    http://classparser.blogspot­.cz/2010/03/hsdis-i386dll.html
  85. How to build hsdis-amd64.dll and hsdis-i386.dll on Windows
    http://dropzone.nfshost.com/hsdis.htm
  86. PrintAssembly
    https://wikis.oracle.com/dis­play/HotSpotInternals/Prin­tAssembly
  87. The Java Virtual Machine Specification: 3.14. Synchronization
    http://docs.oracle.com/ja­vase/specs/jvms/se7/html/jvms-3.html#jvms-3.14
  88. The Java Virtual Machine Specification: 8.3.1.4. volatile Fields
    http://docs.oracle.com/ja­vase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4
  89. The Java Virtual Machine Specification: 17.4. Memory Model
    http://docs.oracle.com/ja­vase/specs/jls/se7/html/jls-17.html#jls-17.4
  90. The Java Virtual Machine Specification: 17.7. Non-atomic Treatment of double and long
    http://docs.oracle.com/ja­vase/specs/jls/se7/html/jls-17.html#jls-17.7
  91. Open Source ByteCode Libraries in Java
    http://java-source.net/open-source/bytecode-libraries
  92. ASM Home page
    http://asm.ow2.org/
  93. Seznam nástrojů využívajících projekt ASM
    http://asm.ow2.org/users.html
  94. ObjectWeb ASM (Wikipedia)
    http://en.wikipedia.org/wi­ki/ObjectWeb_ASM
  95. Java Bytecode BCEL vs ASM
    http://james.onegoodcooki­e.com/2005/10/26/java-bytecode-bcel-vs-asm/
  96. BCEL Home page
    http://commons.apache.org/bcel/
  97. Byte Code Engineering Library (před verzí 5.0)
    http://bcel.sourceforge.net/
  98. Byte Code Engineering Library (verze >= 5.0)
    http://commons.apache.org/pro­per/commons-bcel/
  99. BCEL Manual
    http://commons.apache.org/bcel/ma­nual.html
  100. Byte Code Engineering Library (Wikipedia)
    http://en.wikipedia.org/wiki/BCEL
  101. BCEL Tutorial
    http://www.smfsupport.com/sup­port/java/bcel-tutorial!/
  102. Bytecode Engineering
    http://book.chinaunix.net/spe­cial/ebook/Core_Java2_Volu­me2AF/0131118269/ch13lev1sec6­.html
  103. Bytecode Outline plugin for Eclipse (screenshoty + info)
    http://asm.ow2.org/eclipse/index.html
  104. Javassist
    http://www.jboss.org/javassist/
  105. Byteman
    http://www.jboss.org/byteman
  106. Java programming dynamics, Part 7: Bytecode engineering with BCEL
    http://www.ibm.com/develo­perworks/java/library/j-dyn0414/
  107. The JavaTM Virtual Machine Specification, Second Edition
    http://java.sun.com/docs/bo­oks/jvms/second_edition/html/VMSpec­TOC.doc.html
  108. The class File Format
    http://java.sun.com/docs/bo­oks/jvms/second_edition/html/Clas­sFile.doc.html
  109. javap – The Java Class File Disassembler
    http://docs.oracle.com/ja­vase/1.4.2/docs/tooldocs/win­dows/javap.html
  110. javap-java-1.6.0-openjdk(1) – Linux man page
    http://linux.die.net/man/1/javap-java-1.6.0-openjdk
  111. Using javap
    http://www.idevelopment.in­fo/data/Programming/java/mis­cellaneous_java/Using_javap­.html
  112. Examine class files with the javap command
    http://www.techrepublic.com/ar­ticle/examine-class-files-with-the-javap-command/5815354
  113. aspectj (Eclipse)
    http://www.eclipse.org/aspectj/
  114. Aspect-oriented programming (Wikipedia)
    http://en.wikipedia.org/wi­ki/Aspect_oriented_program­ming
  115. AspectJ (Wikipedia)
    http://en.wikipedia.org/wiki/AspectJ
  116. EMMA: a free Java code coverage tool
    http://emma.sourceforge.net/
  117. Cobertura
    http://cobertura.sourceforge.net/
  118. jclasslib bytecode viewer
    http://www.ej-technologies.com/products/jclas­slib/overview.html

Byl pro vás článek přínosný?