generated from FabricMC/fabric-example-mod
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
84 additions
and
36 deletions.
There are no files selected for viewing
65 changes: 38 additions & 27 deletions
65
src/main/java/io/github/imurx/audioswitcher/AudioSwitcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,70 @@ | ||
package io.github.imurx.audioswitcher; | ||
|
||
import io.github.imurx.audioswitcher.events.SoundSystemCallback; | ||
import io.github.imurx.audioswitcher.mixin.SoundEngineAccessor; | ||
import io.github.imurx.audioswitcher.mixin.SoundManagerAccessor; | ||
import io.github.imurx.audioswitcher.mixin.SoundSystemAccessor; | ||
import net.fabricmc.api.ClientModInitializer; | ||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; | ||
import net.minecraft.client.MinecraftClient; | ||
import net.minecraft.client.sound.SoundEngine; | ||
import net.minecraft.client.sound.SoundSystem; | ||
import org.lwjgl.openal.*; | ||
|
||
import java.nio.LongBuffer; | ||
import java.util.List; | ||
import java.util.Timer; | ||
import java.util.TimerTask; | ||
|
||
public class AudioSwitcher implements ClientModInitializer { | ||
private Timer timer; | ||
private int tickCounter = -1; | ||
static private Thread thread; | ||
static public List<String> devices; | ||
static public String defaultDevice = ""; | ||
static public String currentDevice = ""; | ||
static public AudioSwitcher switcher; | ||
static public String preferredDevice = ""; | ||
static public boolean useDefault = true; | ||
|
||
@Override | ||
public void onInitializeClient() { | ||
updateDevices(); | ||
switcher = this; //not good | ||
} | ||
ClientTickEvents.END_CLIENT_TICK.register((client) -> { | ||
if(tickCounter < 0 || ++tickCounter < 40) return; | ||
SoundEngine engine = ((SoundSystemAccessor) ((SoundManagerAccessor) client.getSoundManager()).getSoundSystem()).getSoundEngine(); | ||
SoundEngineAccessor accessor = (SoundEngineAccessor) engine; | ||
int connect = ALC11.alcGetInteger(accessor.getDevicePointer(), EXTDisconnect.ALC_CONNECTED); | ||
updateDevices(); | ||
|
||
public void onInitialized() { | ||
timer = new Timer("AudioSwitcherChecker"); | ||
timer.scheduleAtFixedRate(new DisconnectCheckTask(), 0, 2000); | ||
} | ||
if(thread != null) { | ||
try { | ||
thread.join(); | ||
} catch(InterruptedException ex) { | ||
ex.printStackTrace(); | ||
} | ||
thread = null; | ||
return; | ||
} | ||
|
||
public void onStopSystem() { | ||
if(timer != null) timer.cancel(); | ||
if(connect == ALC11.ALC_FALSE) { | ||
thread = new Thread(() -> restartSoundSystem(defaultDevice)); | ||
} else if(!currentDevice.equals(preferredDevice) && devices.contains(preferredDevice)) { | ||
thread = new Thread(() -> restartSoundSystem(preferredDevice)); | ||
} else { | ||
return; | ||
} | ||
|
||
thread.setName("AudioSwitcher"); | ||
thread.start(); | ||
}); | ||
SoundSystemCallback.STARTED_SYSTEM.register((_x) -> tickCounter = 0); | ||
SoundSystemCallback.STOPPING_SYSTEM.register((_x) -> tickCounter = -1); | ||
} | ||
|
||
static public void updateDevices() { | ||
devices = ALUtil.getStringList(0, ALC11.ALC_ALL_DEVICES_SPECIFIER); | ||
defaultDevice = ALC11.alcGetString(0, ALC11.ALC_DEFAULT_ALL_DEVICES_SPECIFIER); | ||
} | ||
|
||
static public class DisconnectCheckTask extends TimerTask { | ||
@Override | ||
public void run() { | ||
SoundSystem soundSystem = ((SoundManagerAccessor) MinecraftClient.getInstance().getSoundManager()).getSoundSystem(); | ||
SoundEngine engine = ((SoundSystemAccessor) soundSystem).getSoundEngine(); | ||
SoundEngineAccessor accessor = (SoundEngineAccessor) engine; | ||
int connect = ALC11.alcGetInteger(accessor.getDevicePointer(), EXTDisconnect.ALC_CONNECTED); | ||
if(connect == ALC11.ALC_FALSE) { | ||
updateDevices(); | ||
currentDevice = defaultDevice; | ||
soundSystem.reloadSounds(); | ||
} | ||
} | ||
static public void restartSoundSystem(String device) { | ||
SoundSystem soundSystem = ((SoundManagerAccessor) MinecraftClient.getInstance().getSoundManager()).getSoundSystem(); | ||
soundSystem.stop(); | ||
currentDevice = device; | ||
((SoundSystemAccessor) soundSystem).callStart(); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/main/java/io/github/imurx/audioswitcher/events/SoundSystemCallback.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package io.github.imurx.audioswitcher.events; | ||
|
||
import net.fabricmc.fabric.api.event.Event; | ||
import net.fabricmc.fabric.api.event.EventFactory; | ||
import net.minecraft.client.sound.SoundSystem; | ||
|
||
public interface SoundSystemCallback { | ||
|
||
Event<SoundSystemCallback> STARTED_SYSTEM = EventFactory.createArrayBacked(SoundSystemCallback.class, | ||
(listeners) -> (soundSystem) -> { | ||
for(SoundSystemCallback listener : listeners) { | ||
listener.onStateChange(soundSystem); | ||
} | ||
}); | ||
|
||
Event<SoundSystemCallback> STOPPING_SYSTEM = EventFactory.createArrayBacked(SoundSystemCallback.class, | ||
(listeners) -> (soundSystem) -> { | ||
for(SoundSystemCallback listener : listeners) { | ||
listener.onStateChange(soundSystem); | ||
} | ||
}); | ||
|
||
void onStateChange(SoundSystem soundSystem); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters