Skip to content

Commit

Permalink
Volume controls and music disc range
Browse files Browse the repository at this point in the history
Feature update.
  • Loading branch information
Navoei committed Aug 10, 2022
1 parent 9460719 commit ec4076f
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 22 deletions.
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ bukkit_version=1.19-R0.1-SNAPSHOT
mod_id=customdiscsplugin

# Target an older API to make it compatible with older versions of Simple Voice Chat
voicechat_api_version=2.2.39
voicechat_api_version=2.3.3

plugin_version=2.0
plugin_version=2.1
maven_group=me.Navoei.customdiscsplugin
archives_base_name=custom-discs
12 changes: 8 additions & 4 deletions src/main/java/me/Navoei/customdiscsplugin/CustomDiscs.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import javax.annotation.Nullable;
import java.io.File;
import java.util.Objects;

public final class CustomDiscs extends JavaPlugin {

Expand All @@ -28,6 +29,9 @@ public final class CustomDiscs extends JavaPlugin {
@Nullable
private VoicePlugin voicechatPlugin;

public float musicDiscDistance;
public float musicDiscVolume;

@Override
public void onEnable() {

Expand All @@ -37,10 +41,7 @@ public void onEnable() {

CustomDisc command = new CustomDisc();

if (!new File(this.getDataFolder(), "config.yml").exists()) {
this.getConfig().options().copyDefaults(true);
}
this.saveConfig();
this.saveDefaultConfig();

File musicData = new File(this.getDataFolder(), "musicdata");
if (!(musicData.exists())) {
Expand All @@ -59,6 +60,9 @@ public void onEnable() {
getServer().getPluginManager().registerEvents(new HopperManager(), this);
getCommand("customdisc").setExecutor(command);

musicDiscDistance = getConfig().getInt("music-disc-distance");
musicDiscVolume = Float.parseFloat(Objects.requireNonNull(getConfig().getString("music-disc-volume")));

ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();

protocolManager.addPacketListener(new PacketAdapter(this, ListenerPriority.NORMAL, PacketType.Play.Server.WORLD_EVENT) {
Expand Down
45 changes: 37 additions & 8 deletions src/main/java/me/Navoei/customdiscsplugin/PlayerManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@
import org.bukkit.entity.Player;

import javax.annotation.Nullable;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.*;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Map;
Expand Down Expand Up @@ -49,6 +46,9 @@ public void playLocationalAudio(VoicechatServerApi api, Path soundFilePath, Play

if (audioChannel == null) return;

audioChannel.setCategory(VoicePlugin.MUSIC_DISC_CATEGORY);
audioChannel.setDistance(CustomDiscs.getInstance().musicDiscDistance);

AtomicBoolean stopped = new AtomicBoolean();
AtomicReference<de.maxhenkel.voicechat.api.audiochannel.AudioPlayer> player = new AtomicReference<>();

Expand Down Expand Up @@ -103,11 +103,11 @@ private de.maxhenkel.voicechat.api.audiochannel.AudioPlayer playChannel(Voicecha
}
}

private static short[] readSoundFile(Path file) throws UnsupportedAudioFileException, IOException {
private static short[] readSoundFile(Path file) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
return VoicePlugin.voicechatApi.getAudioConverter().bytesToShorts(convertFormat(file, FORMAT));
}

private static byte[] convertFormat(Path file, AudioFormat audioFormat) throws UnsupportedAudioFileException, IOException {
private static byte[] convertFormat(Path file, AudioFormat audioFormat) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
AudioInputStream finalInputStream = null;

if (getFileExtension(file.toFile().toString()).equals("wav")) {
Expand All @@ -124,9 +124,38 @@ private static byte[] convertFormat(Path file, AudioFormat audioFormat) throws U
}

assert finalInputStream != null;
return finalInputStream.readAllBytes();

return adjustVolume(finalInputStream.readAllBytes(), CustomDiscs.getInstance().musicDiscVolume);
}

private static byte[] adjustVolume(byte[] audioSamples, double volume) {

if (volume > 1d || volume < 0d) {
CustomDiscs.getInstance().getServer().getLogger().info("Error: The volume must be between 0 and 1 in the config!");
return null;
}

byte[] array = new byte[audioSamples.length];
for (int i = 0; i < array.length; i+=2) {
// convert byte pair to int
short buf1 = audioSamples[i+1];
short buf2 = audioSamples[i];

buf1 = (short) ((buf1 & 0xff) << 8);
buf2 = (short) (buf2 & 0xff);

short res= (short) (buf1 | buf2);
res = (short) (res * volume);

// convert back
array[i] = (byte) res;
array[i+1] = (byte) (res >> 8);

}
return array;
}


public void stopLocationalAudio(Location blockLocation) {
UUID id = UUID.nameUUIDFromBytes(blockLocation.toString().getBytes());
Stoppable player = playerMap.get(id);
Expand All @@ -136,7 +165,7 @@ public void stopLocationalAudio(Location blockLocation) {
playerMap.remove(id);
}

public static float getLengthSeconds(Path file) throws UnsupportedAudioFileException, IOException {
public static float getLengthSeconds(Path file) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
short[] audio = readSoundFile(file);
return (float) audio.length / FORMAT.getSampleRate();
}
Expand Down
57 changes: 51 additions & 6 deletions src/main/java/me/Navoei/customdiscsplugin/VoicePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,25 @@
import de.maxhenkel.voicechat.api.VoicechatApi;
import de.maxhenkel.voicechat.api.VoicechatPlugin;
import de.maxhenkel.voicechat.api.VoicechatServerApi;
import de.maxhenkel.voicechat.api.VolumeCategory;
import de.maxhenkel.voicechat.api.events.EventRegistration;
import de.maxhenkel.voicechat.api.events.VoicechatServerStartedEvent;

import javax.annotation.Nullable;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.Enumeration;

public class VoicePlugin implements VoicechatPlugin {

public static VoicechatApi voicechatApi;
public static String MUSIC_DISC_CATEGORY = "music_discs";

public static VoicechatApi voicechatApi;
@Nullable
public static VoicechatServerApi voicechatServerApi;
@Nullable
public static VolumeCategory musicDiscs;

/**
* @return the unique ID for this voice chat plugin
Expand All @@ -29,8 +37,8 @@ public String getPluginId() {
* @param api the voice chat API
*/
@Override
public void initialize(final VoicechatApi api) {
VoicePlugin.voicechatApi = api;
public void initialize(VoicechatApi api) {
voicechatApi = api;
}

/**
Expand All @@ -39,11 +47,48 @@ public void initialize(final VoicechatApi api) {
* @param registration the event registration
*/
@Override
public void registerEvents(final EventRegistration registration) {
public void registerEvents(EventRegistration registration) {
registration.registerEvent(VoicechatServerStartedEvent.class, this::onServerStarted);
}

public void onServerStarted(final VoicechatServerStartedEvent event) {
VoicePlugin.voicechatServerApi = event.getVoicechat();
public void onServerStarted(VoicechatServerStartedEvent event) {
voicechatServerApi = event.getVoicechat();

musicDiscs = voicechatServerApi.volumeCategoryBuilder()
.setId(MUSIC_DISC_CATEGORY)
.setName("Music Discs")
.setDescription("The volume of music discs")
.setIcon(getMusicDiscIcon())
.build();
voicechatServerApi.registerVolumeCategory(musicDiscs);

}

private int[][] getMusicDiscIcon() {
try {
Enumeration<URL> resources = CustomDiscs.getInstance().getClass().getClassLoader().getResources("music_disc_category.png");

while (resources.hasMoreElements()) {
BufferedImage bufferedImage = ImageIO.read(resources.nextElement().openStream());
if (bufferedImage.getWidth() != 16) {
continue;
}
if (bufferedImage.getHeight() != 16) {
continue;
}
int[][] image = new int[16][16];
for (int x = 0; x < bufferedImage.getWidth(); x++) {
for (int y = 0; y < bufferedImage.getHeight(); y++) {
image[x][y] = bufferedImage.getRGB(x, y);
}
}
return image;
}

} catch (Exception e) {
e.printStackTrace();
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import java.io.IOException;
import java.nio.file.Path;
import java.util.Objects;
import java.util.UUID;

public class JukeBox implements Listener{

Expand Down
8 changes: 7 additions & 1 deletion src/main/resources/config.yml
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
#Might add config options in the future.
# [Music Disc Config]

# The distance from which music discs can be heard in blocks.
music-disc-distance: 16

# The master volume of music discs from 0-1. (You can set values like 0.5 for 50% volume).
music-disc-volume: 1
Binary file added src/main/resources/music_disc_category.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit ec4076f

Please sign in to comment.