Implement SDL2_mixer and use that for audio

This commit is contained in:
Furkan Mudanyali 2021-12-20 00:52:25 +03:00
parent ca974cc260
commit 090d3fd66c
5 changed files with 97 additions and 81 deletions

View File

@ -1,77 +1,69 @@
package com.fmudanyali; package com.fmudanyali;
import javax.sound.sampled.Clip; import com.sun.jna.Native;
import javax.sound.sampled.UnsupportedAudioFileException; import com.sun.jna.Pointer;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import java.util.LinkedList; import org.libsdl.api.rwops.SDL_RWops;
import java.util.Queue;
import java.io.File; import static org.libsdl.api.rwops.SdlRWops.SDL_RWFromFile;
import java.io.IOException;
public class Audio { public class Audio {
private static Queue<String> audioQueue = new LinkedList<String>(); // Using SDL2_Mixer for native functions
private static Clip clip; static {
Native.register("SDL2_mixer");
public static void init() throws Exception{
clip = AudioSystem.getClip();
Thread thread = new Thread(){
public void run(){
String current = new String();
while(!Main.exit){
if(audioQueue.isEmpty()){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
if(audioQueue.size() == 1){
clip.loop(Clip.LOOP_CONTINUOUSLY);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
clip.loop(0);
}
if(current != audioQueue.peek()){
current = audioQueue.peek();
try {
addAudio(current);
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
}
if(clip.getMicrosecondLength() == clip.getMicrosecondPosition() && audioQueue.size() > 1){
audioQueue.remove();
}
}
}
}
};
thread.start();
} }
public static void playAudio(String file) throws Exception{ // Constants
File f = new File(FileLoader.getFilePath(file)); public static final int AUDIO_U8 = 0x0008;
AudioInputStream audioIn = AudioSystem.getAudioInputStream(f.toURI().toURL()); public static final int AUDIO_S8 = 0x8008;
clip.open(audioIn); public static final int AUDIO_U16LSB = 0x0010;
clip.start(); public static final int AUDIO_S16LSB = 0x8010;
} public static final int AUDIO_U16MSB = 0x1010;
public static final int AUDIO_S16MSB = 0x9010;
public static final int AUDIO_U16 = AUDIO_U16LSB;
public static final int AUDIO_S16 = AUDIO_S16LSB;
public static final int AUDIO_S32LSB = 0x8020;
public static final int AUDIO_S32MSB = 0x9020;
public static final int AUDIO_S32 = AUDIO_S32LSB;
public static final int AUDIO_F32LSB = 0x8120;
public static final int AUDIO_F32MSB = 0x9120;
public static final int AUDIO_F32 = AUDIO_F32LSB;
private static void addAudio(String file) throws Exception{ public static final int MIX_DEFAULT_FREQUENCY = 44100;
File f = new File(FileLoader.getFilePath(file)); public static final int MIX_DEFAULT_FORMAT = AUDIO_S16;
AudioInputStream audioIn = AudioSystem.getAudioInputStream(f.toURI().toURL()); public static final int MIX_DEFAULT_CHANNELS = 2;
clip.close(); public static final int MIX_MAX_VOLUME = 128;
clip.open(audioIn); public static final int MIX_CHANNEL_POST = -2;
}
public static void queueAudio(String file){ // Native functions
audioQueue.add(file); public static native Pointer Mix_Linked_Version();
public static native int Mix_Init(int flags);
public static native void Mix_Quit();
public static native int Mix_OpenAudio(int frequency, int format, int channels, int chunksize);
public static native void Mix_CloseAudio();
public static native int Mix_QuerySpec(int frequency, int format, int channels);
public static native int Mix_GetNumChunkDecoders();
public static native String Mix_GetChunkDecoder();
public static native Pointer Mix_LoadWAV_RW(SDL_RWops src, int freesrc);
public static native Pointer Mix_LoadMUS(String file);
public static native int Mix_VolumeMusic(int volume);
public static native int Mix_PlayChannelTimed(int channel, Pointer chunk, int loops, int ticks);
public static native int Mix_PlayMusic(Pointer music, int loops);
public static native int Mix_PlayingMusic();
public static native int Mix_PausedMusic();
public static native void Mix_ResumeMusic();
public static native void Mix_PauseMusic();
public static native void Mix_HaltMusic();
public static native void Mix_FreeChunk(Pointer chunk);
public static native void Mix_FreeMusic(Pointer music);
// Defines
public static Pointer Mix_LoadWAV(String file){
return Mix_LoadWAV_RW(SDL_RWFromFile(file, "rb"), 1);
}
public static int Mix_PlayChannel(int channel, Pointer chunk, int loops){
return Mix_PlayChannelTimed(channel, chunk, loops, -1);
} }
} }

View File

@ -31,7 +31,7 @@ public class Main {
} }
Render.init(); Render.init();
Screen.init(); Screen.init();
Audio.init(); //Audio.init();
scenes.push(new MainMenu()); scenes.push(new MainMenu());
while(!scenes.empty() && !exit){ while(!scenes.empty() && !exit){

View File

@ -17,11 +17,12 @@
package com.fmudanyali.scenes; package com.fmudanyali.scenes;
import com.fmudanyali.FileLoader;
import com.fmudanyali.Main; import com.fmudanyali.Main;
import com.fmudanyali.Screen; import com.fmudanyali.Screen;
import com.fmudanyali.characters.Player; import com.fmudanyali.characters.Player;
import com.fmudanyali.Audio;
import static com.fmudanyali.Audio.*;
import static org.libsdl.api.event.SdlEvents.*; import static org.libsdl.api.event.SdlEvents.*;
import static com.fmudanyali.Render.*; import static com.fmudanyali.Render.*;
import static org.libsdl.api.keycode.SDL_Keycode.*; import static org.libsdl.api.keycode.SDL_Keycode.*;
@ -35,8 +36,22 @@ public class Game extends Scene {
public Game() throws Exception{ public Game() throws Exception{
Screen.makeBackground("scene1/tile.bmp"); Screen.makeBackground("scene1/tile.bmp");
Audio.queueAudio("80-search-intro.wav"); Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048);
Audio.queueAudio("80-search-loop.wav"); Mix_VolumeMusic(128);
Thread thread = new Thread(){
public void run(){
try {
Mix_PlayMusic(Mix_LoadMUS(FileLoader.getFilePath("80-search-intro.wav")), 1);
while(Mix_PlayingMusic() == 1);
Mix_PlayMusic(Mix_LoadMUS(FileLoader.getFilePath("80-search-loop.wav")), -1);
Thread.currentThread().interrupt();
return;
} catch(Exception e){
e.printStackTrace();
}
}
};
thread.start();
} }
@Override @Override
@ -51,6 +66,7 @@ public class Game extends Scene {
case SDLK_ESCAPE: case SDLK_ESCAPE:
if(!escPressed){ if(!escPressed){
Main.scenes.push(new PauseMenu()); Main.scenes.push(new PauseMenu());
Mix_VolumeMusic(30);
escPressed = true; escPressed = true;
} }
break; break;

View File

@ -26,6 +26,7 @@ import org.libsdl.api.render.*;
import org.libsdl.api.surface.SDL_Surface; import org.libsdl.api.surface.SDL_Surface;
import static com.fmudanyali.Render.*; import static com.fmudanyali.Render.*;
import static com.fmudanyali.Audio.*;
import static org.libsdl.api.render.SdlRender.*; import static org.libsdl.api.render.SdlRender.*;
import static org.libsdl.api.surface.SdlSurface.*; import static org.libsdl.api.surface.SdlSurface.*;
import static org.libsdl.api.event.SdlEvents.*; import static org.libsdl.api.event.SdlEvents.*;
@ -43,6 +44,7 @@ public class MainMenu extends Scene {
private int selection = 0; private int selection = 0;
public MainMenu() throws Exception{ public MainMenu() throws Exception{
Mix_PauseMusic();
buttonSize.x = buttonSize.y = 0; buttonSize.x = buttonSize.y = 0;
buttonSize.w = startPos.w = exitPos.w = 150; buttonSize.w = startPos.w = exitPos.w = 150;
buttonSize.h = startPos.h = exitPos.h = 100; buttonSize.h = startPos.h = exitPos.h = 100;

View File

@ -20,12 +20,14 @@ package com.fmudanyali.scenes;
import com.fmudanyali.Main; import com.fmudanyali.Main;
import com.fmudanyali.Screen; import com.fmudanyali.Screen;
import com.fmudanyali.FileLoader; import com.fmudanyali.FileLoader;
import com.fmudanyali.scenes.MainMenu;
import org.libsdl.api.rect.SDL_Rect; import org.libsdl.api.rect.SDL_Rect;
import org.libsdl.api.render.*; import org.libsdl.api.render.*;
import org.libsdl.api.surface.SDL_Surface; import org.libsdl.api.surface.SDL_Surface;
import static com.fmudanyali.Render.*; import static com.fmudanyali.Render.*;
import static com.fmudanyali.Audio.*;
import static org.libsdl.api.render.SdlRender.*; import static org.libsdl.api.render.SdlRender.*;
import static org.libsdl.api.surface.SdlSurface.*; import static org.libsdl.api.surface.SdlSurface.*;
import static org.libsdl.api.event.SdlEvents.*; import static org.libsdl.api.event.SdlEvents.*;
@ -72,6 +74,7 @@ public class PauseMenu extends Scene {
case SDLK_ESCAPE: case SDLK_ESCAPE:
if(!escPressed){ if(!escPressed){
Main.scenes.pop(); Main.scenes.pop();
Mix_VolumeMusic(128);
escPressed = true; escPressed = true;
} }
break; break;
@ -141,15 +144,18 @@ public class PauseMenu extends Scene {
} }
} }
private void confirm(){ private void confirm() throws Exception{
switch(selection){ switch(selection){
case 0: case 0:
Main.scenes.pop(); Main.scenes.pop();
Mix_VolumeMusic(128);
Game.escPressed = false; Game.escPressed = false;
break; break;
case 1: case 1:
Main.scenes.pop(); Main.scenes.pop();
Main.scenes.pop(); Main.scenes.pop();
Main.scenes.pop();
Main.scenes.push(new MainMenu());
break; break;
} }
} }