2009. január 11., vasárnap

Open-IG

Örömmel jelenthetem, hogy elszántam magam az Imperium Galactica játékának Java-ra történő portolására. A projektet a Google Code-nál hostoltatom és a http://code.google.com/p/open-ig/ címen érhető el. Jelenleg még nem tartalmaz túl sok mindent, csak egy lejátszót, amivel meg lehet tekinteni az IG ANI fájljait (mellékesen megjegyzem, hogy 1 hétig csak azon agyaltunk TCH kollégával, hogy megfejtsük a koránt sem egyszerű tömörítését).

2009. január 5., hétfő

Zene Java-ban

Bár triviálisnak tűnhet, mégsem olyan könnyű kideríteni a neten található anyagokból, hogyan is kell saját készítésű hangot, teszem azt a 440Hz-es A hangot. A javax.sound API leírása nem rossz, de pont a lényegből nem mutat példát. Hát lássuk, mégis hogy kell:
// szükséges importok
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;

// a hang frekvenciája
float freq = 440;
// a mintavételi frekvencia, vagyis 1 másodpercnyi
// hanganyaghoz szükséges hangminták száma
int samplerate = 22050;
// a hang erőssége
int amp = 64;
// 1 másodpercnyi puffer
byte[] buffer = new byte[samplerate];
// a szinuszfüggvény kvantálása
for (int i = 0; i < buffer.length; i++) {
buffer[i] = (byte)(amp * Math.sin(2 * Math.PI * freq / buffer.length * i));
}
// a lejátszási audió formátum: 22050 Hz, 8 bites, mono (előjeles, little-endian)
AudioFormat af = new AudioFormat(samplerate, 8, 1, true, false);
// adatvonal leírása
DataLine.Info dli = new DataLine.Info(SourceDataLine.class, af);
// van-e ilyen kimenő adatvonalunk
if (!AudioSystem.isLineSupported(dli)) {
// nincs
throw new Exception("Line not supported");
}
// adatvonal lekérdezése
SourceDataLine sdl = (SourceDataLine)AudioSystem.getLine(dli);
// kimenő adatvonal megnyitása az előbbi formátummal
sdl.open(af);
// lejátszás megkezdése
sdl.start();
// a hangadatok kiírása, blokkolódik, amíg a a lejátszás
// meg nem történt
sdl.write(buffer);
// lejátszás megállítása
sdl.stop();
// a hangpufferben hátramaradt adatok eltávolítása
sdl.drain();
// a kimenő vonal végleges bezárása
sdl.close();

Ilyen egyszerű, mintha fájlba írnánk.