From 618830a6b94c2a5d14b858d1470d1d26bba05e12 Mon Sep 17 00:00:00 2001 From: "Dr. Rubisco" <76263371+thedocruby@users.noreply.github.com> Date: Tue, 1 Feb 2022 17:13:21 -0500 Subject: [PATCH] Finished variable slot count Finished Variable slot count, the first major feature unique to Resounding! This can be thought of as the reverb "resolution", higher slot counts mean smoother reverb and more detail, but at the cost of memory and performance This setting can be changed with the `reverbResolution` setting in the config Also: - updated config. This will work until i can get around to a full rewrite - rewrote `dev.thedocruby.resounding.openal.*`, since i needed to to get the variable slot count working. - fixed a critical error with material properties inherited from Sound Physics that forced all materials to use fallback values. Material properties should now be applied correctly - fixed a bug from the last commit that prevented the mod from updating properly when the config was changed - Improved the reverb quality by no longer hard-coding some things, like reverb diffusion. Most of these are also now configurable - a few more minor things --- .../dev/thedocruby/resounding/Resounding.java | 248 +++++++++++------- .../thedocruby/resounding/ResoundingLog.java | 5 +- .../resounding/ResoundingModClient.java | 44 ---- .../config/BlueTapePack/ConfigManager.java | 15 +- .../resounding/config/PrecomputedConfig.java | 70 +++-- .../resounding/config/ResoundingConfig.java | 35 ++- .../config/presets/ConfigChanger.java | 26 +- .../config/presets/ConfigPresets.java | 98 +++---- .../resounding/openal/ResoundingEFX.java | 247 ++++++++++++++--- .../{ReverbSlot.java => ReverbEffect.java} | 147 ++--------- .../assets/resounding/lang/en_us.json | 30 +-- 11 files changed, 531 insertions(+), 434 deletions(-) rename src/main/java/dev/thedocruby/resounding/openal/{ReverbSlot.java => ReverbEffect.java} (64%) diff --git a/src/main/java/dev/thedocruby/resounding/Resounding.java b/src/main/java/dev/thedocruby/resounding/Resounding.java index 367a6af3..8c702aa8 100644 --- a/src/main/java/dev/thedocruby/resounding/Resounding.java +++ b/src/main/java/dev/thedocruby/resounding/Resounding.java @@ -4,7 +4,6 @@ import dev.thedocruby.resounding.effects.AirEffects; import dev.thedocruby.resounding.performance.RaycastFix; import dev.thedocruby.resounding.performance.SPHitResult; -import dev.thedocruby.resounding.config.PrecomputedConfig; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.block.BlockState; @@ -12,7 +11,6 @@ import net.minecraft.sound.BlockSoundGroup; import net.minecraft.sound.SoundCategory; import net.minecraft.util.Formatting; -import net.minecraft.util.Pair; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -30,6 +28,9 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import static dev.thedocruby.resounding.config.PrecomputedConfig.pC; +import static dev.thedocruby.resounding.config.PrecomputedConfig.speedOfSound; +import static dev.thedocruby.resounding.openal.ResoundingEFX.efxEnabled; import static java.util.Map.entry; @SuppressWarnings({"CommentedOutCode"}) @@ -77,58 +78,104 @@ private Resounding() { } entry(BlockSoundGroup.LODESTONE, BlockSoundGroup.NETHERITE), entry(BlockSoundGroup.LADDER, BlockSoundGroup.WOOD) );// - public static final Map groupMap = // + public static final Map groupToName = // Map.ofEntries( - entry("field_11528", "Coral" ), // Coral (coral_block) - entry("field_11529", "Gravel, Dirt" ), // Gravel, Dirt (gravel, rooted_dirt) - entry("field_27197", "Amethyst" ), // Amethyst (amethyst_block, small_amethyst_bud, medium_amethyst_bud, large_amethyst_bud, amethyst_cluster) - entry("field_11526", "Sand" ), // Sand (sand) - entry("field_27196", "Candle Wax" ), // Candle Wax (candle) - entry("field_22140", "Weeping Vines" ), // Weeping Vines (weeping_vines, weeping_vines_low_pitch) - entry("field_22141", "Soul Sand" ), // Soul Sand (soul_sand) - entry("field_22142", "Soul Soil" ), // Soul Soil (soul_soil) - entry("field_22143", "Basalt" ), // Basalt (basalt) - entry("field_22145", "Netherrack" ), // Netherrack (netherrack, nether_ore, nether_gold_ore) - entry("field_22146", "Nether Brick" ), // Nether Brick (nether_bricks) - entry("field_21214", "Honey" ), // Honey (honey_block) - entry("field_22149", "Bone" ), // Bone (bone_block) - entry("field_17581", "Nether Wart" ), // Nether Wart (nether_wart, wart_block) - entry("field_11535", "Grass, Crops, Foliage" ), // Grass, Crops, Foliage (grass, crop, bamboo_sapling, sweet_berry_bush) - entry("field_11533", "Metal" ), // Metal (metal, copper, anvil) - entry("field_11534", "Aquatic Foliage" ), // Aquatic Foliage (wet_grass, lily_pad) - entry("field_11537", "Glass, Ice" ), // Glass, Ice (glass) - entry("field_28116", "Sculk Sensor" ), // Sculk Sensor (sculk_sensor) - entry("field_22138", "Nether Foliage" ), // Nether Foliage (roots, nether_sprouts) - entry("field_22139", "Shroomlight" ), // Shroomlight (shroomlight) - entry("field_24119", "Chain" ), // Chain (chain) - entry("field_29033", "Deepslate" ), // Deepslate (deepslate) - entry("field_11547", "Wood" ), // Wood (wood, ladder) - entry("field_29035", "Deepslate Tiles" ), // Deepslate Tiles (deepslate_tiles) - entry("field_11544", "Stone, Blackstone" ), // Stone, Blackstone (stone, calcite, gilded_blackstone) - entry("field_11545", "Slime" ), // Slime (slime_block) - entry("field_29036", "Polished Deepslate" ), // Polished Deepslate (polished_deepslate, deepslate_bricks) - entry("field_11548", "Snow" ), // Snow (snow) - entry("field_28702", "Azalea Leaves" ), // Azalea Leaves (azalea_leaves) - entry("field_11542", "Bamboo" ), // Bamboo (bamboo, scaffolding) - entry("field_18852", "Mushroom Stems" ), // Mushroom Stems (stem) - entry("field_11543", "Wool" ), // Wool (wool) - entry("field_23083", "Dry Foliage" ), // Dry Foliage (vine, hanging_roots, glow_lichen) - entry("field_28694", "Azalea Bush" ), // Azalea Bush (azalea) - entry("field_28692", "Lush Cave Foliage" ), // Lush Cave Foliage (cave_vines, spore_blossom, small_dripleaf, big_dripleaf) - entry("field_22150", "Netherite" ), // Netherite (netherite_block, lodestone) - entry("field_22151", "Ancient Debris" ), // Ancient Debris (ancient_debris) - entry("field_22152", "Nether Fungus Stem" ), // Nether Fungus Stem (nether_stem) - entry("field_27884", "Powder Snow" ), // Powder Snow (powder_snow) - entry("field_27202", "Tuff" ), // Tuff (tuff) - entry("field_28697", "Moss" ), // Moss (moss, moss_carpet) - entry("field_22153", "Nylium" ), // Nylium (nylium) - entry("field_22154", "Nether Mushroom" ), // Nether Mushroom (fungus) - entry("field_17734", "Lanterns" ), // Lanterns (lantern) - entry("field_28060", "Dripstone" ), // Dripstone (dripstone_block, pointed_dripstone) - entry("DEFAULT" , "Default Material" ) // Default Material () + entry(BlockSoundGroup.CORAL , "Coral" ), // Coral (coral_block) + entry(BlockSoundGroup.GRAVEL , "Gravel, Dirt" ), // Gravel, Dirt (gravel, rooted_dirt) + entry(BlockSoundGroup.AMETHYST_BLOCK, "Amethyst" ), // Amethyst (amethyst_block, small_amethyst_bud, medium_amethyst_bud, large_amethyst_bud, amethyst_cluster) + entry(BlockSoundGroup.SAND , "Sand" ), // Sand (sand) + entry(BlockSoundGroup.CANDLE , "Candle Wax" ), // Candle Wax (candle) + entry(BlockSoundGroup.WEEPING_VINES , "Weeping Vines" ), // Weeping Vines (weeping_vines, weeping_vines_low_pitch) + entry(BlockSoundGroup.SOUL_SAND , "Soul Sand" ), // Soul Sand (soul_sand) + entry(BlockSoundGroup.SOUL_SOIL , "Soul Soil" ), // Soul Soil (soul_soil) + entry(BlockSoundGroup.BASALT , "Basalt" ), // Basalt (basalt) + entry(BlockSoundGroup.NETHERRACK , "Netherrack" ), // Netherrack (netherrack, nether_ore, nether_gold_ore) + entry(BlockSoundGroup.NETHER_BRICKS , "Nether Brick" ), // Nether Brick (nether_bricks) + entry(BlockSoundGroup.HONEY , "Honey" ), // Honey (honey_block) + entry(BlockSoundGroup.BONE , "Bone" ), // Bone (bone_block) + entry(BlockSoundGroup.NETHER_WART , "Nether Wart" ), // Nether Wart (nether_wart, wart_block) + entry(BlockSoundGroup.GRASS , "Grass, Foliage" ), // Grass, Foliage (grass, crop, bamboo_sapling, sweet_berry_bush) + entry(BlockSoundGroup.METAL , "Metal" ), // Metal (metal, copper, anvil) + entry(BlockSoundGroup.WET_GRASS , "Aquatic Foliage" ), // Aquatic Foliage (wet_grass, lily_pad) + entry(BlockSoundGroup.GLASS , "Glass, Ice" ), // Glass, Ice (glass) + entry(BlockSoundGroup.SCULK_SENSOR , "Sculk Sensor" ), // Sculk Sensor (sculk_sensor) + entry(BlockSoundGroup.ROOTS , "Nether Foliage" ), // Nether Foliage (roots, nether_sprouts) + entry(BlockSoundGroup.SHROOMLIGHT , "Shroomlight" ), // Shroomlight (shroomlight) + entry(BlockSoundGroup.CHAIN , "Chain" ), // Chain (chain) + entry(BlockSoundGroup.DEEPSLATE , "Deepslate" ), // Deepslate (deepslate) + entry(BlockSoundGroup.WOOD , "Wood" ), // Wood (wood, ladder) + entry(BlockSoundGroup.DEEPSLATE_TILES,"Deepslate Tiles" ), // Deepslate Tiles (deepslate_tiles) + entry(BlockSoundGroup.STONE , "Stone, Blackstone"), // Stone, Blackstone(stone, calcite, gilded_blackstone) + entry(BlockSoundGroup.SLIME , "Slime" ), // Slime (slime_block) + entry(BlockSoundGroup.POLISHED_DEEPSLATE,"Polished Deepslate"),// Polished Deepslate(polished_deepslate, deepslate_bricks) + entry(BlockSoundGroup.SNOW , "Snow" ), // Snow (snow) + entry(BlockSoundGroup.AZALEA_LEAVES , "Azalea Leaves" ), // Azalea Leaves (azalea_leaves) + entry(BlockSoundGroup.BAMBOO , "Bamboo" ), // Bamboo (bamboo, scaffolding) + entry(BlockSoundGroup.STEM , "Mushroom Stems" ), // Mushroom Stems (stem) + entry(BlockSoundGroup.WOOL , "Wool" ), // Wool (wool) + entry(BlockSoundGroup.VINE , "Dry Foliage" ), // Dry Foliage (vine, hanging_roots, glow_lichen) + entry(BlockSoundGroup.AZALEA , "Azalea Bush" ), // Azalea Bush (azalea) + entry(BlockSoundGroup.CAVE_VINES , "Lush Cave Foliage"), // Lush Cave Foliage(cave_vines, spore_blossom, small_dripleaf, big_dripleaf) + entry(BlockSoundGroup.NETHERITE , "Netherite" ), // Netherite (netherite_block, lodestone) + entry(BlockSoundGroup.ANCIENT_DEBRIS, "Ancient Debris" ), // Ancient Debris (ancient_debris) + entry(BlockSoundGroup.NETHER_STEM ,"Nether Fungus Stem"), //Nether Fungus Stem(nether_stem) + entry(BlockSoundGroup.POWDER_SNOW , "Powder Snow" ), // Powder Snow (powder_snow) + entry(BlockSoundGroup.TUFF , "Tuff" ), // Tuff (tuff) + entry(BlockSoundGroup.MOSS_BLOCK , "Moss" ), // Moss (moss_block, moss_carpet) + entry(BlockSoundGroup.NYLIUM , "Nylium" ), // Nylium (nylium) + entry(BlockSoundGroup.FUNGUS , "Nether Mushroom" ), // Nether Mushroom (fungus) + entry(BlockSoundGroup.LANTERN , "Lanterns" ), // Lanterns (lantern) + entry(BlockSoundGroup.DRIPSTONE_BLOCK,"Dripstone" ) // Dripstone (dripstone_block, pointed_dripstone) );/**/ - public static Map> blockSoundGroups; - public static Map groupSoundBlocks; + public static final Map nameToGroup = // + Map.ofEntries( + entry("Coral" , BlockSoundGroup.CORAL ), // Coral (coral_block) + entry("Gravel, Dirt" , BlockSoundGroup.GRAVEL ), // Gravel, Dirt (gravel, rooted_dirt) + entry("Amethyst" , BlockSoundGroup.AMETHYST_BLOCK), // Amethyst (amethyst_block, small_amethyst_bud, medium_amethyst_bud, large_amethyst_bud, amethyst_cluster) + entry("Sand" , BlockSoundGroup.SAND ), // Sand (sand) + entry("Candle Wax" , BlockSoundGroup.CANDLE ), // Candle Wax (candle) + entry("Weeping Vines" , BlockSoundGroup.WEEPING_VINES ), // Weeping Vines (weeping_vines, weeping_vines_low_pitch) + entry("Soul Sand" , BlockSoundGroup.SOUL_SAND ), // Soul Sand (soul_sand) + entry("Soul Soil" , BlockSoundGroup.SOUL_SOIL ), // Soul Soil (soul_soil) + entry("Basalt" , BlockSoundGroup.BASALT ), // Basalt (basalt) + entry("Netherrack" , BlockSoundGroup.NETHERRACK ), // Netherrack (netherrack, nether_ore, nether_gold_ore) + entry("Nether Brick" , BlockSoundGroup.NETHER_BRICKS ), // Nether Brick (nether_bricks) + entry("Honey" , BlockSoundGroup.HONEY ), // Honey (honey_block) + entry("Bone" , BlockSoundGroup.BONE ), // Bone (bone_block) + entry("Nether Wart" , BlockSoundGroup.NETHER_WART ), // Nether Wart (nether_wart, wart_block) + entry("Grass, Foliage" , BlockSoundGroup.GRASS ), // Grass, Foliage (grass, crop, bamboo_sapling, sweet_berry_bush) + entry("Metal" , BlockSoundGroup.METAL ), // Metal (metal, copper, anvil) + entry("Aquatic Foliage" , BlockSoundGroup.WET_GRASS ), // Aquatic Foliage (wet_grass, lily_pad) + entry("Glass, Ice" , BlockSoundGroup.GLASS ), // Glass, Ice (glass) + entry("Sculk Sensor" , BlockSoundGroup.SCULK_SENSOR ), // Sculk Sensor (sculk_sensor) + entry("Nether Foliage" , BlockSoundGroup.ROOTS ), // Nether Foliage (roots, nether_sprouts) + entry("Shroomlight" , BlockSoundGroup.SHROOMLIGHT ), // Shroomlight (shroomlight) + entry("Chain" , BlockSoundGroup.CHAIN ), // Chain (chain) + entry("Deepslate" , BlockSoundGroup.DEEPSLATE ), // Deepslate (deepslate) + entry("Wood" , BlockSoundGroup.WOOD ), // Wood (wood, ladder) + entry("Deepslate Tiles" ,BlockSoundGroup.DEEPSLATE_TILES), // Deepslate Tiles (deepslate_tiles) + entry("Stone, Blackstone", BlockSoundGroup.STONE ), // Stone, Blackstone(stone, calcite, gilded_blackstone) + entry("Slime" , BlockSoundGroup.SLIME ), // Slime (slime_block) + entry("Polished Deepslate",BlockSoundGroup.POLISHED_DEEPSLATE),// Polished Deepslate(polished_deepslate, deepslate_bricks) + entry("Snow" , BlockSoundGroup.SNOW ), // Snow (snow) + entry("Azalea Leaves" , BlockSoundGroup.AZALEA_LEAVES ), // Azalea Leaves (azalea_leaves) + entry("Bamboo" , BlockSoundGroup.BAMBOO ), // Bamboo (bamboo, scaffolding) + entry("Mushroom Stems" , BlockSoundGroup.STEM ), // Mushroom Stems (stem) + entry("Wool" , BlockSoundGroup.WOOL ), // Wool (wool) + entry("Dry Foliage" , BlockSoundGroup.VINE ), // Dry Foliage (vine, hanging_roots, glow_lichen) + entry("Azalea Bush" , BlockSoundGroup.AZALEA ), // Azalea Bush (azalea) + entry("Lush Cave Foliage", BlockSoundGroup.CAVE_VINES ), // Lush Cave Foliage(cave_vines, spore_blossom, small_dripleaf, big_dripleaf) + entry("Netherite" , BlockSoundGroup.NETHERITE ), // Netherite (netherite_block, lodestone) + entry("Ancient Debris" , BlockSoundGroup.ANCIENT_DEBRIS), // Ancient Debris (ancient_debris) + entry("Nether Fungus Stem",BlockSoundGroup.NETHER_STEM ), //Nether Fungus Stem(nether_stem) + entry("Powder Snow" , BlockSoundGroup.POWDER_SNOW ), // Powder Snow (powder_snow) + entry("Tuff" , BlockSoundGroup.TUFF ), // Tuff (tuff) + entry("Moss" , BlockSoundGroup.MOSS_BLOCK ), // Moss (moss_block, moss_carpet) + entry("Nylium" , BlockSoundGroup.NYLIUM ), // Nylium (nylium) + entry("Nether Mushroom" , BlockSoundGroup.FUNGUS ), // Nether Mushroom (fungus) + entry("Lanterns" , BlockSoundGroup.LANTERN ), // Lanterns (lantern) + entry("Dripstone" ,BlockSoundGroup.DRIPSTONE_BLOCK) // Dripstone (dripstone_block, pointed_dripstone) + );// public static Set rays; public static MinecraftClient mc; @@ -143,7 +190,7 @@ private Resounding() { } @Environment(EnvType.CLIENT) public static void init() { LOGGER.info("Initializing Resounding..."); - ResoundingEFX.setupEFX(); + ResoundingEFX.setupEXTEfx(); LOGGER.info("OpenAL EFX successfully primed for Resounding effects"); mc = MinecraftClient.getInstance(); updateRays(); @@ -158,17 +205,17 @@ public static void updateRays() { final double gRatio = 1.618033988; final double epsilon; - if (PrecomputedConfig.pC.nRays >= 600000) { epsilon = 214d; } - else if (PrecomputedConfig.pC.nRays >= 400000) { epsilon = 75d; } - else if (PrecomputedConfig.pC.nRays >= 11000) { epsilon = 27d; } - else if (PrecomputedConfig.pC.nRays >= 890) { epsilon = 10d; } - else if (PrecomputedConfig.pC.nRays >= 177) { epsilon = 3.33d; } - else if (PrecomputedConfig.pC.nRays >= 24) { epsilon = 1.33d; } + if (pC.nRays >= 600000) { epsilon = 214d; } + else if (pC.nRays >= 400000) { epsilon = 75d; } + else if (pC.nRays >= 11000) { epsilon = 27d; } + else if (pC.nRays >= 890) { epsilon = 10d; } + else if (pC.nRays >= 177) { epsilon = 3.33d; } + else if (pC.nRays >= 24) { epsilon = 1.33d; } else { epsilon = 0.33d; } - rays = IntStream.range(0, PrecomputedConfig.pC.nRays).parallel().unordered().mapToObj(i -> { + rays = IntStream.range(0, pC.nRays).parallel().unordered().mapToObj(i -> { final double theta = 2d * Math.PI * i / gRatio; - final double phi = Math.acos(1d - 2d * (i + epsilon) / (PrecomputedConfig.pC.nRays - 1d + 2d * epsilon)); + final double phi = Math.acos(1d - 2d * (i + epsilon) / (pC.nRays - 1d + 2d * epsilon)); return new Vec3d( Math.cos(theta) * Math.sin(phi), @@ -191,21 +238,21 @@ public static void updateRays() { @Environment(EnvType.CLIENT) public static void playSound(double posX, double posY, double posZ, int sourceID, boolean auxOnly) { - if (PrecomputedConfig.pC.off) return; + if (!efxEnabled || pC.off) return; - if (PrecomputedConfig.pC.dLog) { - LOGGER.info("Playing sound!\n Source ID: {}\n Source Pos: {}\n Sound category: {}\n Sound name: {}", sourceID, new double[] {posX, posY, posZ}, lastSoundCategory, lastSoundName); + if (pC.dLog) { + LOGGER.info("Playing sound!\n Source ID: {}\n Source Pos: {}\n Sound category: {}\n Sound name: {}", sourceID, new double[] {posX, posY, posZ}, lastSoundCategory, lastSoundName); } else { - LOGGER.debug("Playing sound!\n Source ID: {}\n Source Pos: {}\n Sound category: {}\n Sound name: {}", sourceID, new double[] {posX, posY, posZ}, lastSoundCategory, lastSoundName); + LOGGER.debug("Playing sound!\n Source ID: {}\n Source Pos: {}\n Sound category: {}\n Sound name: {}", sourceID, new double[] {posX, posY, posZ}, lastSoundCategory, lastSoundName); } long startTime = 0; long endTime; - if (PrecomputedConfig.pC.pLog) startTime = System.nanoTime(); + if (pC.pLog) startTime = System.nanoTime(); evalEnv(sourceID, posX, posY, posZ, auxOnly); - if (PrecomputedConfig.pC.pLog) { endTime = System.nanoTime(); + if (pC.pLog) { endTime = System.nanoTime(); LOGGER.info("Total calculation time for sound {}: {} milliseconds", lastSoundName, (double)(endTime - startTime)/(double)1000000); } @@ -215,10 +262,11 @@ public static void playSound(double posX, double posY, double posZ, int sourceID private static double getBlockReflectivity(final @NotNull BlockState blockState) { BlockSoundGroup soundType = blockState.getSoundGroup(); String blockName = blockState.getBlock().getTranslationKey(); - if (PrecomputedConfig.pC.blockWhiteSet.contains(blockName)) return PrecomputedConfig.pC.blockWhiteMap.get(blockName).reflectivity; + if (pC.blockWhiteSet.contains(blockName)) return pC.blockWhiteMap.get(blockName).reflectivity; - double r = PrecomputedConfig.pC.reflectivityMap.getOrDefault(soundType, Double.NaN); - return Double.isNaN(r) ? PrecomputedConfig.pC.defaultReflectivity : r; + if (redirectMap.containsKey(soundType)) { soundType = redirectMap.get(soundType); } + double r = pC.reflectivityMap.getOrDefault(soundType, Double.NaN); + return Double.isNaN(r) ? pC.defaultReflectivity : r; } /* @Environment(EnvType.CLIENT) @@ -243,13 +291,13 @@ private static double getBlockOcclusionD(final BlockState blockState) { SPHitResult rayHit = RaycastFix.fixedRaycast( soundPos, - soundPos.add(dir.multiply(PrecomputedConfig.pC.maxDistance)), + soundPos.add(dir.multiply(pC.maxDistance)), mc.world, soundBlockPos, soundChunk ); - if (PrecomputedConfig.pC.dRays) RaycastRenderer.addSoundBounceRay(soundPos, rayHit.getPos(), Formatting.GREEN.getColorValue()); + if (pC.dRays) RaycastRenderer.addSoundBounceRay(soundPos, rayHit.getPos(), Formatting.GREEN.getColorValue()); if (rayHit.isMissed()) { result.totalReflectivity = 1; @@ -281,36 +329,36 @@ private static double getBlockOcclusionD(final BlockState blockState) { color = Formatting.WHITE.getColorValue(); result.shared[0] = 1; } - if (PrecomputedConfig.pC.dRays) RaycastRenderer.addSoundBounceRay(lastHitPos, finalRayHit.getPos(), color); + if (pC.dRays) RaycastRenderer.addSoundBounceRay(lastHitPos, finalRayHit.getPos(), color); // Secondary ray bounces - for (int i = 1; i < PrecomputedConfig.pC.nRayBounces; i++) { + for (int i = 1; i < pC.nRayBounces; i++) { final Vec3d newRayDir = pseudoReflect(lastRayDir, lastHitNormal); - rayHit = RaycastFix.fixedRaycast(lastHitPos, lastHitPos.add(newRayDir.multiply(PrecomputedConfig.pC.maxDistance - result.totalDistance)), mc.world, lastHitBlock, rayHit.chunk); + rayHit = RaycastFix.fixedRaycast(lastHitPos, lastHitPos.add(newRayDir.multiply(pC.maxDistance - result.totalDistance)), mc.world, lastHitBlock, rayHit.chunk); // log("New ray dir: " + newRayDir.xCoord + ", " + newRayDir.yCoord + ", " + newRayDir.zCoord); if (rayHit.isMissed()) { - if (PrecomputedConfig.pC.dRays) RaycastRenderer.addSoundBounceRay(lastHitPos, rayHit.getPos(), Formatting.DARK_RED.getColorValue()); - result.missed = Math.pow(result.totalReflectivity, PrecomputedConfig.pC.globalReflRcp); + if (pC.dRays) RaycastRenderer.addSoundBounceRay(lastHitPos, rayHit.getPos(), Formatting.DARK_RED.getColorValue()); + result.missed = Math.pow(result.totalReflectivity, pC.globalReflRcp); break; } final Vec3d newRayHitPos = rayHit.getPos(); final double newRayLength = lastHitPos.distanceTo(newRayHitPos); result.totalDistance += newRayLength; - if (PrecomputedConfig.pC.maxDistance - result.totalDistance < newRayHitPos.distanceTo(playerPos)) + if (pC.maxDistance - result.totalDistance < newRayHitPos.distanceTo(playerPos)) { - if (PrecomputedConfig.pC.dRays) RaycastRenderer.addSoundBounceRay(lastHitPos, newRayHitPos, Formatting.DARK_PURPLE.getColorValue()); - result.missed = Math.pow(result.totalReflectivity, PrecomputedConfig.pC.globalReflRcp); + if (pC.dRays) RaycastRenderer.addSoundBounceRay(lastHitPos, newRayHitPos, Formatting.DARK_PURPLE.getColorValue()); + result.missed = Math.pow(result.totalReflectivity, pC.globalReflRcp); break; } final double newBlockReflectivity = getBlockReflectivity(rayHit.getBlockState()); result.totalReflectivity *= newBlockReflectivity; - if (Math.pow(result.totalReflectivity, PrecomputedConfig.pC.globalReflRcp) < PrecomputedConfig.pC.minEnergy) { if (PrecomputedConfig.pC.dRays) RaycastRenderer.addSoundBounceRay(lastHitPos, newRayHitPos, Formatting.DARK_BLUE.getColorValue()); break; } + if (Math.pow(result.totalReflectivity, pC.globalReflRcp) < pC.minEnergy) { if (pC.dRays) RaycastRenderer.addSoundBounceRay(lastHitPos, newRayHitPos, Formatting.DARK_BLUE.getColorValue()); break; } - if (PrecomputedConfig.pC.dRays) RaycastRenderer.addSoundBounceRay(lastHitPos, newRayHitPos, Formatting.BLUE.getColorValue()); + if (pC.dRays) RaycastRenderer.addSoundBounceRay(lastHitPos, newRayHitPos, Formatting.BLUE.getColorValue()); lastBlockReflectivity = newBlockReflectivity; lastHitPos = newRayHitPos; @@ -335,13 +383,13 @@ private static double getBlockOcclusionD(final BlockState blockState) { color = Formatting.WHITE.getColorValue(); result.shared[i] = 1; } - if (PrecomputedConfig.pC.dRays) RaycastRenderer.addSoundBounceRay(lastHitPos, finalRayHit.getPos(), color); + if (pC.dRays) RaycastRenderer.addSoundBounceRay(lastHitPos, finalRayHit.getPos(), color); } if (result.missed == 1) return result; for(int i = 0; i <= result.lastBounce; i++){ if (result.shared[i] > 0) continue; double accumulator = 1; - for(int j = i; result.shared[j] == 0 && j < PrecomputedConfig.pC.nRayBounces - 1; j++){ + for(int j = i; result.shared[j] == 0 && j < pC.nRayBounces - 1; j++){ accumulator *= result.bounceReflectivity[j+1]; } result.shared[i] = accumulator; @@ -351,13 +399,13 @@ private static double getBlockOcclusionD(final BlockState blockState) { @Environment(EnvType.CLIENT) private static void evalEnv(final int sourceID, double posX, double posY, double posZ, boolean auxOnly) { - if (PrecomputedConfig.pC.off) return; + if (pC.off) return; - if (mc.player == null || mc.world == null || posY <= mc.world.getBottomY() || (PrecomputedConfig.pC.recordsDisable && lastSoundCategory == SoundCategory.RECORDS) || uiPattern.matcher(lastSoundName).matches() || (posX == 0.0 && posY == 0.0 && posZ == 0.0)) + if (mc.player == null || mc.world == null || posY <= mc.world.getBottomY() || (pC.recordsDisable && lastSoundCategory == SoundCategory.RECORDS) || uiPattern.matcher(lastSoundName).matches() || (posX == 0.0 && posY == 0.0 && posZ == 0.0)) { //logDetailed("Menu sound!"); try { - ResoundingEFX.setEnv(sourceID, new double[]{0f, 0f, 0f, 0f}, new double[]{1f, 1f, 1f, 1f}, auxOnly ? 0f : 1f, 1f); + ResoundingEFX.setEnv(sourceID, new double[pC.resolution], new double[pC.resolution], auxOnly ? 0f : 1f, 1f); } catch (IllegalArgumentException e) { e.printStackTrace(); } return; } @@ -367,10 +415,10 @@ private static void evalEnv(final int sourceID, double posX, double posY, double boolean block = blockPattern.matcher(lastSoundName).matches() && !stepPattern.matcher(lastSoundName).matches(); if (lastSoundCategory == SoundCategory.RECORDS){posX+=0.5;posY+=0.5;posZ+=0.5;block = true;} - if (PrecomputedConfig.pC.skipRainOcclusionTracing && isRain) + if (pC.skipRainOcclusionTracing && isRain) { try { - ResoundingEFX.setEnv(sourceID, new double[]{0f, 0f, 0f, 0f}, new double[]{1f, 1f, 1f, 1f}, auxOnly ? 0f : 1f, 1f); + ResoundingEFX.setEnv(sourceID, new double[pC.resolution], new double[pC.resolution], auxOnly ? 0f : 1f, 1f); } catch (IllegalArgumentException e) { e.printStackTrace(); } return; } @@ -520,7 +568,7 @@ private static void processEnv(int sourceID, boolean auxOnly, @Nullable Set { - try { - return Modifier.isStatic(f.getModifiers()) && Modifier.isPublic(f.getModifiers()) - && (f.get(null) instanceof BlockSoundGroup group) && !Resounding.redirectMap.containsKey(group); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - return false; - }) - .collect(Collectors.toMap( - (f) -> { - try { - return (BlockSoundGroup)f.get(null); - } catch (IllegalAccessException | ClassCastException e) { - e.printStackTrace(); - } - return null; - }, - (f) -> { - try { - return new Pair<>(f.getName(), (f.get(null) instanceof BlockSoundGroup g ? (Resounding.groupMap.containsKey(f.getName()) ? Resounding.groupMap.get(f.getName()) : g.getBreakSound().getId().getPath().split("\\.")[1] ): "not a group")); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - return new Pair<>("", ""); - })); - Resounding.groupSoundBlocks = Arrays.stream(BlockSoundGroup.class.getDeclaredFields()) - .filter((f) -> { - try { - return Modifier.isStatic(f.getModifiers()) && Modifier.isPublic(f.getModifiers()) - && (f.get(null) instanceof BlockSoundGroup group) && !Resounding.redirectMap.containsKey(group); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - return false; - }).map((f)-> { - BlockSoundGroup b; - try { b = (BlockSoundGroup)f.get(null); } - catch (IllegalAccessException | ClassCastException e) { e.printStackTrace(); b = null;} - return new Pair<>(f.getName(),b); - }).filter((f) -> f.getRight() != null) - .collect(Collectors.toMap(Pair::getLeft, Pair::getRight)); - ConfigManager.registerAutoConfig(); } } diff --git a/src/main/java/dev/thedocruby/resounding/config/BlueTapePack/ConfigManager.java b/src/main/java/dev/thedocruby/resounding/config/BlueTapePack/ConfigManager.java index 2bb1101d..3a8ec74b 100644 --- a/src/main/java/dev/thedocruby/resounding/config/BlueTapePack/ConfigManager.java +++ b/src/main/java/dev/thedocruby/resounding/config/BlueTapePack/ConfigManager.java @@ -5,6 +5,7 @@ import dev.thedocruby.resounding.config.PrecomputedConfig; import dev.thedocruby.resounding.config.ResoundingConfig; import dev.thedocruby.resounding.config.presets.ConfigPresets; +import dev.thedocruby.resounding.openal.ResoundingEFX; import me.shedaniel.autoconfig.AutoConfig; import me.shedaniel.autoconfig.ConfigHolder; import me.shedaniel.autoconfig.serializer.JanksonConfigSerializer; @@ -23,12 +24,13 @@ private ConfigManager() {} private static ConfigHolder holder; + public static String configVersion = "1.0.0-alpha.2"; + @Environment(EnvType.CLIENT) public static final ResoundingConfig DEFAULT = Resounding.env == EnvType.CLIENT ? new ResoundingConfig(){{ - Map map = - Resounding.blockSoundGroups.entrySet().stream() - .collect(Collectors.toMap((e)-> e.getValue().getLeft(), (e) -> new MaterialData(e.getValue().getRight(), 0.5, 0.5))); - map.putIfAbsent("DEFAULT", new MaterialData(Resounding.groupMap.get("DEFAULT"), 0.5, 0.5)); + Map map = Resounding.nameToGroup.keySet().stream() + .collect(Collectors.toMap(e -> e, e -> new MaterialData(e, 0.5, 0.5))); + map.putIfAbsent("DEFAULT", new MaterialData("DEFAULT", 0.5, 0.5)); Materials.materialProperties = map; }} : null; @@ -73,17 +75,18 @@ public static void handleUnstableConfig( ResoundingConfig c ){ Resounding.LOGGER.error("Error: Config file is not from a compatible version! Resetting the config..."); ConfigPresets.DEFAULT_PERFORMANCE.configChanger.accept(c); ConfigPresets.RESET_MATERIALS.configChanger.accept(c); - c.version = "1.0.0-alpha.1"; + c.version = configVersion; } public static ActionResult onSave(ResoundingConfig c) { if (Resounding.env == EnvType.CLIENT && (c.Materials.materialProperties == null || c.Materials.materialProperties.get("DEFAULT") == null)) handleBrokenMaterials(c); if (Resounding.env == EnvType.CLIENT && c.preset != ConfigPresets.LOAD_SUCCESS) c.preset.configChanger.accept(c); - if (c.version == null || !Objects.equals(c.version, "1.0.0-alpha.1")) handleUnstableConfig(c); + if (c.version == null || !Objects.equals(c.version, configVersion)) handleUnstableConfig(c); if (PrecomputedConfig.pC != null) PrecomputedConfig.pC.deactivate(); try {PrecomputedConfig.pC = new PrecomputedConfig(c);} catch (CloneNotSupportedException e) {e.printStackTrace(); return ActionResult.FAIL;} if (Resounding.env == EnvType.CLIENT) { Resounding.updateRays(); + ResoundingEFX.initEAXReverb(); } return ActionResult.SUCCESS; } diff --git a/src/main/java/dev/thedocruby/resounding/config/PrecomputedConfig.java b/src/main/java/dev/thedocruby/resounding/config/PrecomputedConfig.java index 5fbbd6b2..5ed02a4e 100644 --- a/src/main/java/dev/thedocruby/resounding/config/PrecomputedConfig.java +++ b/src/main/java/dev/thedocruby/resounding/config/PrecomputedConfig.java @@ -1,7 +1,6 @@ package dev.thedocruby.resounding.config; import dev.thedocruby.resounding.Resounding; -import dev.thedocruby.resounding.ResoundingLog; import it.unimi.dsi.fastutil.objects.Reference2DoubleOpenHashMap; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -11,6 +10,8 @@ import java.util.*; import java.util.stream.Collectors; +import static dev.thedocruby.resounding.Resounding.nameToGroup; + /* Values, which remain constant after the config has changed Only one instance allowed @@ -25,8 +26,13 @@ public class PrecomputedConfig { public final boolean off; public final float globalReverbGain; + public final double minEnergy; + public final int resolution; + public final double warpFactor; public final float globalReverbBrightness; + public final double reverbCondensationFactor; public final double globalBlockAbsorption; + public final double globalAbsorptionBrightness; public final double globalBlockReflectance; public final double globalReflRcp; public final float airAbsorption; @@ -45,6 +51,8 @@ public class PrecomputedConfig { @Environment(EnvType.CLIENT) public double rcpTotRays; @Environment(EnvType.CLIENT) + public double maxDistance; + @Environment(EnvType.CLIENT) public boolean simplerSharedAirspaceSimulation; @Environment(EnvType.CLIENT) @@ -81,14 +89,6 @@ public class PrecomputedConfig { public final boolean pLog; public final boolean dRays; - public final int resolution; - public final double warpFactor; - public final double globalAbsorptionBrightness; - public final double maxDecayTime; - public final int traceRange; - public final double minEnergy; - public final double maxDistance; - private boolean active = true; public PrecomputedConfig(ResoundingConfig c) throws CloneNotSupportedException { @@ -96,10 +96,15 @@ public PrecomputedConfig(ResoundingConfig c) throws CloneNotSupportedException { off = !c.enabled; defaultAttenuationFactor = c.General.attenuationFactor; - globalReverbGain = (float) (1 / c.General.globalReverbGain); + globalReverbGain = (float) c.General.globalReverbGain; + minEnergy = Math.exp(-1 * c.General.globalReverbStrength); + resolution = c.General.reverbResolution; + warpFactor = c.General.reverbWarpFactor; globalReverbBrightness = (float) c.General.globalReverbBrightness; + reverbCondensationFactor = 1 - c.General.globalReverbSmoothness; globalBlockAbsorption = c.General.globalBlockAbsorption; - soundDistanceAllowance = c.General.soundDistanceAllowance; + globalAbsorptionBrightness = c.General.globalAbsorptionBrightness; + soundDistanceAllowance = c.General.soundDistanceAllowance; // TODO: Refactor to sound render distance globalBlockReflectance = c.General.globalBlockReflectance; globalReflRcp = 1 / globalBlockReflectance; airAbsorption = (float) c.General.airAbsorption; @@ -113,6 +118,7 @@ public PrecomputedConfig(ResoundingConfig c) throws CloneNotSupportedException { rcpNRays = 1d / nRays; nRayBounces = c.Performance.environmentEvaluationRayBounces; rcpTotRays = rcpNRays / nRayBounces; + maxDistance = c.Performance.traceRange * nRayBounces * Math.sqrt(2 * (16*16)) * 2; simplerSharedAirspaceSimulation = c.Performance.simplerSharedAirspaceSimulation; blockWhiteSet = new HashSet<>(c.Materials.blockWhiteList); @@ -133,13 +139,13 @@ public PrecomputedConfig(ResoundingConfig c) throws CloneNotSupportedException { absorptionMap = new Reference2DoubleOpenHashMap<>(); final List wrong = new java.util.ArrayList<>(); final List toRemove = new java.util.ArrayList<>(); - c.Materials.materialProperties.forEach((k, v) -> { - BlockSoundGroup bsg = Resounding.groupSoundBlocks.get(k); - if (bsg != null) { + c.Materials.materialProperties.forEach((k, v) -> { //TODO Materials need to be reworked. + if (nameToGroup.containsKey(k)) { + BlockSoundGroup bsg = nameToGroup.get(k); reflectivityMap.put(bsg, v.reflectivity); - absorptionMap.put(bsg, v.absorption * 2); + absorptionMap.put(bsg, v.absorption); } else { - if (!k.equals("DEFAULT") && !blockWhiteSet.contains(k)) { + if (!blockWhiteSet.contains(k) && !k.equals("DEFAULT")) { wrong.add(k + " (" + v.example + ")"); toRemove.add(k); } @@ -150,28 +156,20 @@ public PrecomputedConfig(ResoundingConfig c) throws CloneNotSupportedException { toRemove.forEach(c.Materials.materialProperties::remove); } - recordsDisable = c.Vlads_Tweaks.recordsDisable; - continuousRefreshRate = c.Vlads_Tweaks.continuousRefreshRate; - maxDirectOcclusionFromBlocks = c.Vlads_Tweaks.maxDirectOcclusionFromBlocks; - _9Ray = c.Vlads_Tweaks._9RayDirectOcclusion; - soundDirectionEvaluation = c.Vlads_Tweaks.soundDirectionEvaluation; - directRaysDirEvalMultiplier = Math.pow(c.Vlads_Tweaks.directRaysDirEvalMultiplier, 10.66); - notOccludedRedirect = !c.Vlads_Tweaks.notOccludedNoRedirect; + recordsDisable = c.Misc.recordsDisable; + continuousRefreshRate = c.Misc.continuousRefreshRate; + maxDirectOcclusionFromBlocks = c.Misc.maxDirectOcclusionFromBlocks; + _9Ray = c.Misc._9RayDirectOcclusion; + soundDirectionEvaluation = c.Misc.soundDirectionEvaluation; // TODO: DirEval + directRaysDirEvalMultiplier = Math.pow(c.Misc.directRaysDirEvalMultiplier, 10.66); // TODO: DirEval + notOccludedRedirect = !c.Misc.notOccludedNoRedirect; } - dLog = c.Misc.debugLogging; - oLog = c.Misc.occlusionLogging; - eLog = c.Misc.environmentLogging; - pLog = c.Misc.performanceLogging; - dRays = c.Misc.raytraceParticles; - - resolution = 4; - warpFactor = 4; - globalAbsorptionBrightness = 1d / 1d; - maxDecayTime = Math.min(20, 4.142); - traceRange = 256; - minEnergy = Math.exp(-1 * c.Misc.minEnergy); - maxDistance = traceRange * nRayBounces; + dLog = c.Debug.debugLogging; + oLog = c.Debug.occlusionLogging; + eLog = c.Debug.environmentLogging; + pLog = c.Debug.performanceLogging; + dRays = c.Debug.raytraceParticles; } public void deactivate(){ active = false;} diff --git a/src/main/java/dev/thedocruby/resounding/config/ResoundingConfig.java b/src/main/java/dev/thedocruby/resounding/config/ResoundingConfig.java index 3bfca81e..f1a2ae83 100644 --- a/src/main/java/dev/thedocruby/resounding/config/ResoundingConfig.java +++ b/src/main/java/dev/thedocruby/resounding/config/ResoundingConfig.java @@ -12,6 +12,8 @@ import java.util.List; import java.util.Map; +import static dev.thedocruby.resounding.config.BlueTapePack.ConfigManager.configVersion; + @SuppressWarnings("CanBeFinal") @Config(name = "resounding") @Config.Gui.Background("minecraft:textures/block/note_block.png") @@ -32,20 +34,30 @@ public class ResoundingConfig implements ConfigData { public Materials Materials = new Materials(); @ConfigEntry.Gui.CollapsibleObject - public Vlads_Tweaks Vlads_Tweaks = new Vlads_Tweaks(); + public ResoundingConfig.Misc Misc = new Misc(); @ConfigEntry.Gui.CollapsibleObject - public Misc Misc = new Misc(); + public Debug Debug = new Debug(); public static class General{ + @ConfigEntry.Gui.Excluded // TODO: remove this @Comment("Affects how quiet a sound gets based on distance. Lower values mean distant sounds are louder.\n1.0 is the physically correct value.\n0.2 - 1.0 or just don't set it to 0") public double attenuationFactor = 1.0; + @ConfigEntry.Gui.Excluded // TODO: remove this @Comment("The global volume of simulated reverberations.\n0.1 - 2.0") public double globalReverbGain = 1.0; + @ConfigEntry.BoundedDiscrete(max = 32, min = 4) + public int reverbResolution = 12; + public double globalReverbStrength = 5.0; + public double reverbWarpFactor = 4; + public double globalReverbSmoothness = 0.62; @Comment("The brightness of reverberation.\nHigher values result in more high frequencies in reverberation.\nLower values give a more muffled sound to the reverb.\n0.1 - 2.0") public double globalReverbBrightness = 1.0; + @ConfigEntry.Gui.Excluded // TODO: Occlusion @Comment("The global amount of sound that will be absorbed when traveling through blocks.\n 0.1 - 4.0") public double globalBlockAbsorption = 1.0; + @ConfigEntry.Gui.Excluded // TODO: Occlusion + public double globalAbsorptionBrightness = 1.0; @Comment("The global amount of sound reflectance energy of all blocks.\nLower values result in more conservative reverb simulation with shorter reverb tails.\nHigher values result in more generous reverb simulation with higher reverb tails.\n0.1 - 4.0") public double globalBlockReflectance = 1.0; @Comment("Minecraft won't allow sounds to play past a certain distance;\nResounding makes that configurable by multiplying this parameter by the default distance.\nValues too high can cause polyphony issues.\n1.0 - 6.0") @@ -62,6 +74,7 @@ public static class General{ public static class Performance{ @Environment(EnvType.CLIENT) + @ConfigEntry.Gui.Excluded // TODO: Occlusion @Comment("If true, rain sound sources won't trace for sound occlusion.\nThis can help performance during rain.") public boolean skipRainOcclusionTracing = true; @Environment(EnvType.CLIENT) @@ -73,6 +86,9 @@ public static class Performance{ @ConfigEntry.BoundedDiscrete(max = 32, min = 2) public int environmentEvaluationRayBounces = 12; @Environment(EnvType.CLIENT) + public double traceRange = 6; + @Environment(EnvType.CLIENT) + @ConfigEntry.Gui.Excluded // TODO: Remove @Comment("If true, enables a simpler technique for determining when the player and a sound source share airspace.\nMight sometimes miss recognizing shared airspace, but it's faster to calculate.") public boolean simplerSharedAirspaceSimulation = false; } @@ -87,7 +103,7 @@ public static class Materials { public List blockWhiteList = new ArrayList<>(); } - public static class Vlads_Tweaks { + public static class Misc { @Environment(EnvType.CLIENT) @Comment("Disable occlusion of jukeboxes and note blocks.\nUseful if you have an audio signaling system that you need to hear clearly") public boolean recordsDisable = false; @@ -95,25 +111,31 @@ public static class Vlads_Tweaks { @Comment("Continuous sources reverb refresh interval (ticks per refresh or 1/(20Hz))") public int continuousRefreshRate = 4; @Environment(EnvType.CLIENT) + @ConfigEntry.Gui.Excluded // TODO: Occlusion @Comment("The amount at which occlusion is capped. 10 * block_occlusion is the theoretical limit") public double maxDirectOcclusionFromBlocks = 10; @Environment(EnvType.CLIENT) + @ConfigEntry.Gui.Excluded // TODO: Occlusion @Comment("Calculate direct occlusion as the minimum of 9 rays from vertices of a block") public boolean _9RayDirectOcclusion = true; @Environment(EnvType.CLIENT) + @ConfigEntry.Gui.Excluded // TODO: DirEval @Comment("Whether to try calculating where the sound should come from based on reflections") public boolean soundDirectionEvaluation = true; @Environment(EnvType.CLIENT) + @ConfigEntry.Gui.Excluded // TODO: DirEval @Comment("How much the sound direction depends on reflected sounds.\nRequires \"Re-calculate sound direction\" to be enabled.\n0.0 is no reflected sounds, 1.0 is 100% reflected sounds.\n0.5 is approximately physically accurate.") public double directRaysDirEvalMultiplier = 0.5; @Environment(EnvType.CLIENT) + @ConfigEntry.Gui.Excluded // TODO: DirEval, Occlusion @Comment("Skip redirecting non-occluded sounds (the ones you can see directly).\nCan be inaccurate in some situations, especially when \"Re-calculate sound direction\" is enabled.") public boolean notOccludedNoRedirect = false; } - public static class Misc { + public static class Debug { @Comment("General debug logging") public boolean debugLogging = false; + @ConfigEntry.Gui.Excluded // TODO: Occlusion @Comment("Occlusion tracing information logging") public boolean occlusionLogging = false; @Comment("Environment evaluation information logging") @@ -122,14 +144,13 @@ public static class Misc { public boolean performanceLogging = false; @Comment("Particles on traced blocks (structure_void is a block)") public boolean raytraceParticles = false; - public double minEnergy = 5; } // TODO: change preset back to "Balanced" when performance permits - @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.DROPDOWN) + @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON) @Comment("Soft presets. Some of these can be applied one after another to stack effects onto a base profile.") public ConfigPresets preset = ConfigPresets.DEFAULT_PERFORMANCE; @ConfigEntry.Gui.Excluded - public String version = "1.0.0-alpha.1"; + public String version = configVersion; } diff --git a/src/main/java/dev/thedocruby/resounding/config/presets/ConfigChanger.java b/src/main/java/dev/thedocruby/resounding/config/presets/ConfigChanger.java index 261124cb..216a2341 100644 --- a/src/main/java/dev/thedocruby/resounding/config/presets/ConfigChanger.java +++ b/src/main/java/dev/thedocruby/resounding/config/presets/ConfigChanger.java @@ -22,8 +22,8 @@ public static void changeConfig(ResoundingConfig config, @Nullable Boolean enabl setGeneral(config.General, attenuationFactor, globalReverbGain, globalReverbBrightness, globalBlockAbsorption, globalBlockReflectance, soundDistanceAllowance, airAbsorption, humidityAbsorption, rainAbsorption, underwaterFilter); if(Resounding.env == EnvType.SERVER) return; setPerformance(config.Performance, skipRainOcclusionTracing, environmentEvaluationRays, environmentEvaluationRayBounces, simplerSharedAirspaceSimulation); - setMaterial_Properties(config.Materials, materialProperties); - setVlads_Tweaks(config.Vlads_Tweaks, continuousRefreshRate, maxDirectOcclusionFromBlocks, _9RayDirectOcclusion, soundDirectionEvaluation, directRaysDirEvalMultiplier, notOccludedNoRedirect); + setMaterialProperties(config.Materials, materialProperties); + setMisc(config.Misc, continuousRefreshRate, maxDirectOcclusionFromBlocks, _9RayDirectOcclusion, soundDirectionEvaluation, directRaysDirEvalMultiplier, notOccludedNoRedirect); config.preset = ConfigPresets.LOAD_SUCCESS; } @@ -49,25 +49,23 @@ public static void setPerformance(ResoundingConfig.Performance performance, @Nul } @Environment(EnvType.CLIENT) - public static void setMaterial_Properties(ResoundingConfig.Materials materials, @Nullable Map materialProperties) { + public static void setMaterialProperties(ResoundingConfig.Materials materials, @Nullable Map materialProperties) { if (materialProperties != null) materialProperties.forEach((s, newData) -> materials.materialProperties.compute(s, (k, v) -> (v == null) ? - new MaterialData( hasExample(s) ? getExample(s) : "error", + new MaterialData( s, newData.getReflectivity() == -1 ? 0.5 : newData.getReflectivity(), newData.getAbsorption() == -1 ? 0.5 : newData.getAbsorption()) - : new MaterialData( (v.getExample() == null) ? (hasExample(s) ? getExample(s) : "error") : v.getExample(), + : new MaterialData( (v.getExample() == null) ? s : v.getExample(), newData.getReflectivity() == -1 ? v.getReflectivity() : newData.getReflectivity(), newData.getAbsorption() == -1 ? v.getAbsorption() : newData.getAbsorption()))); } @Environment(EnvType.CLIENT) - public static void setVlads_Tweaks(ResoundingConfig.Vlads_Tweaks vlads_tweaks, @Nullable Integer continuousRefreshRate, @Nullable Double maxDirectOcclusionFromBlocks, @Nullable Boolean _9RayDirectOcclusion, @Nullable Boolean soundDirectionEvaluation, @Nullable Double directRaysDirEvalMultiplier, @Nullable Boolean notOccludedNoRedirect) { - if (continuousRefreshRate != null) vlads_tweaks.continuousRefreshRate = continuousRefreshRate; - if (maxDirectOcclusionFromBlocks != null) vlads_tweaks.maxDirectOcclusionFromBlocks = maxDirectOcclusionFromBlocks; - if (_9RayDirectOcclusion != null) vlads_tweaks._9RayDirectOcclusion = _9RayDirectOcclusion; - if (soundDirectionEvaluation != null) vlads_tweaks.soundDirectionEvaluation = soundDirectionEvaluation; - if (directRaysDirEvalMultiplier != null) vlads_tweaks.directRaysDirEvalMultiplier = directRaysDirEvalMultiplier; - if (notOccludedNoRedirect != null) vlads_tweaks.notOccludedNoRedirect = notOccludedNoRedirect; + public static void setMisc(ResoundingConfig.Misc misc, @Nullable Integer continuousRefreshRate, @Nullable Double maxDirectOcclusionFromBlocks, @Nullable Boolean _9RayDirectOcclusion, @Nullable Boolean soundDirectionEvaluation, @Nullable Double directRaysDirEvalMultiplier, @Nullable Boolean notOccludedNoRedirect) { + if (continuousRefreshRate != null) misc.continuousRefreshRate = continuousRefreshRate; + if (maxDirectOcclusionFromBlocks != null) misc.maxDirectOcclusionFromBlocks = maxDirectOcclusionFromBlocks; + if (_9RayDirectOcclusion != null) misc._9RayDirectOcclusion = _9RayDirectOcclusion; + if (soundDirectionEvaluation != null) misc.soundDirectionEvaluation = soundDirectionEvaluation; + if (directRaysDirEvalMultiplier != null) misc.directRaysDirEvalMultiplier = directRaysDirEvalMultiplier; + if (notOccludedNoRedirect != null) misc.notOccludedNoRedirect = notOccludedNoRedirect; } - public static String getExample(String s) {return Resounding.groupMap.get(s);} - public static boolean hasExample(String s) {return Resounding.groupMap.containsKey(s);} } diff --git a/src/main/java/dev/thedocruby/resounding/config/presets/ConfigPresets.java b/src/main/java/dev/thedocruby/resounding/config/presets/ConfigPresets.java index eee8e44a..2cd769b0 100644 --- a/src/main/java/dev/thedocruby/resounding/config/presets/ConfigPresets.java +++ b/src/main/java/dev/thedocruby/resounding/config/presets/ConfigPresets.java @@ -51,6 +51,7 @@ public enum ConfigPresets { 4, 10.0, true, true, 0.5, false )),// + /* // THEDOCRUBY("Dr. Rubisco's Signature Sound", (ResoundingConfig c) -> ConfigChanger.changeConfig(c, true, @@ -114,6 +115,7 @@ public enum ConfigPresets { 4, 10.0, true, true, 0.5, false )),// + */ // TODO add back // SUPER_REVERB("Super Reverb", (ResoundingConfig c) -> ConfigChanger.changeConfig(c, true, null, 1.8, null, null, @@ -201,7 +203,7 @@ public enum ConfigPresets { null, 10.0, null, null, null, null )),// // - RESET_MATERIALS("Clear Material Properties", (ResoundingConfig c) -> ConfigChanger.changeConfig(c, true, + RESET_MATERIALS("Reset Materials", (ResoundingConfig c) -> ConfigChanger.changeConfig(c, true, null, null, null, null, null, null, null, null, @@ -210,53 +212,53 @@ public enum ConfigPresets { // Map.ofEntries( - entry("field_11528", new MaterialData(0.2, 0.45 )), // Coral (coral_block) - entry("field_11529", new MaterialData(0.5, 0.4 )), // Gravel, Dirt (gravel, rooted_dirt) - entry("field_27197", new MaterialData(0.75, 0.45 )), // Amethyst (amethyst_block, small_amethyst_bud, medium_amethyst_bud, large_amethyst_bud, amethyst_cluster) - entry("field_11526", new MaterialData(0.1, 0.45 )), // Sand (sand) - entry("field_27196", new MaterialData(0.4, 0.3 )), // Candle Wax (candle) - entry("field_22140", new MaterialData(0.2, 0.2 )), // Weeping Vines (weeping_vines, weeping_vines_low_pitch) - entry("field_22141", new MaterialData(0.05, 0.65 )), // Soul Sand (soul_sand) - entry("field_22142", new MaterialData(0.1, 0.7 )), // Soul Soil (soul_soil) - entry("field_22143", new MaterialData(0.8, 0.3 )), // Basalt (basalt) - entry("field_22145", new MaterialData(0.75, 0.45 )), // Netherrack (netherrack, nether_ore, nether_gold_ore) - entry("field_22146", new MaterialData(0.85, 0.55 )), // Nether Brick (nether_bricks) - entry("field_21214", new MaterialData(0.08, 0.85 )), // Honey (honey_block) - entry("field_22149", new MaterialData(0.7, 0.55 )), // Bone (bone_block) - entry("field_17581", new MaterialData(0.2, 0.8 )), // Nether Wart (nether_wart, wart_block) - entry("field_11535", new MaterialData(0.2, 0.6 )), // Crops and Foliage (grass, crop, bamboo_sapling, sweet_berry_bush) - entry("field_11533", new MaterialData(0.85, 0.5 )), // Metal (metal, copper, anvil) - entry("field_11534", new MaterialData(0.15, 0.8 )), // Aquatic Foliage (wet_grass, lily_pad) - entry("field_11537", new MaterialData(0.5, 0.45 )), // Glass, Ice (glass) - entry("field_28116", new MaterialData(0.4, 0.6 )), // Sculk Sensor (sculk_sensor) - entry("field_22138", new MaterialData(0.15, 0.55 )), // Nether Foliage (roots, nether_sprouts) - entry("field_22139", new MaterialData(0.85, 0.75 )), // Shroomlight (shroomlight) - entry("field_24119", new MaterialData(0.4, 0.4 )), // Chain (chain) - entry("field_29033", new MaterialData(0.88, 0.55 )), // Deepslate (deepslate) - entry("field_11547", new MaterialData(0.65, 0.45 )), // Wood (wood, ladder) - entry("field_29035", new MaterialData(0.95, 0.55 )), // Deepslate Tiles (deepslate_tiles) - entry("field_11544", new MaterialData(0.83, 0.5 )), // Stone, Blackstone (stone, calcite, gilded_blackstone) - entry("field_11545", new MaterialData(1.0, 0.25 )), // Slime (slime_block) - entry("field_29036", new MaterialData(0.99, 0.55 )), // Polished Deepslate (polished_deepslate, deepslate_bricks) - entry("field_11548", new MaterialData(0.1, 0.5 )), // Snow (snow) - entry("field_28702", new MaterialData(0.3, 0.35 )), // Azalea Leaves (azalea_leaves) - entry("field_11542", new MaterialData(0.5, 0.4 )), // Bamboo (bamboo, scaffolding) - entry("field_18852", new MaterialData(0.6, 0.65 )), // Mushroom Stems (stem) - entry("field_11543", new MaterialData(0.02, 1.0 )), // Wool (wool) - entry("field_23083", new MaterialData(0.1, 0.15 )), // Dry Foliage (vine, hanging_roots, glow_lichen) - entry("field_28694", new MaterialData(0.15, 0.5 )), // Azalea Bush (azalea) - entry("field_28692", new MaterialData(0.2, 0.2 )), // Lush Foliage (cave_vines, spore_blossom, small_dripleaf, big_dripleaf) - entry("field_22150", new MaterialData(1.0, 0.6 )), // Netherite (netherite_block, lodestone) - entry("field_22151", new MaterialData(0.45, 0.8 )), // Ancient Debris (ancient_debris) - entry("field_22152", new MaterialData(0.3, 0.55 )), // Nether Fungus Stem (nether_stem) - entry("field_27884", new MaterialData(0.01, 0.1 )), // Powder Snow (powder_snow) - entry("field_27202", new MaterialData(0.35, 0.4 )), // Tuff (tuff) - entry("field_28697", new MaterialData(0.1, 0.85 )), // Moss (moss, moss_carpet) - entry("field_22153", new MaterialData(0.4, 0.55 )), // Nylium (nylium) - entry("field_22154", new MaterialData(0.4, 0.6 )), // Nether Fungus (fungus) - entry("field_17734", new MaterialData(0.75, 0.4 )), // Lanterns (lantern) - entry("field_28060", new MaterialData(0.9, 0.6 )), // Dripstone (dripstone_block, pointed_dripstone) - entry("DEFAULT" , new MaterialData(0.5, 0.5 )), // Default Material () + entry("Coral", new MaterialData(0.2, 0.45 )), // Coral (coral_block) + entry("Gravel, Dirt", new MaterialData(0.5, 0.4 )), // Gravel, Dirt (gravel, rooted_dirt) + entry("Amethyst", new MaterialData(0.75, 0.45 )), // Amethyst (amethyst_block, small_amethyst_bud, medium_amethyst_bud, large_amethyst_bud, amethyst_cluster) + entry("Sand", new MaterialData(0.1, 0.45 )), // Sand (sand) + entry("Candle Wax", new MaterialData(0.4, 0.3 )), // Candle Wax (candle) + entry("Weeping Vines", new MaterialData(0.2, 0.2 )), // Weeping Vines (weeping_vines, weeping_vines_low_pitch) + entry("Soul Sand", new MaterialData(0.05, 0.65 )), // Soul Sand (soul_sand) + entry("Soul Soil", new MaterialData(0.1, 0.7 )), // Soul Soil (soul_soil) + entry("Basalt", new MaterialData(0.8, 0.3 )), // Basalt (basalt) + entry("Netherrack", new MaterialData(0.75, 0.45 )), // Netherrack (netherrack, nether_ore, nether_gold_ore) + entry("Nether Brick", new MaterialData(0.85, 0.55 )), // Nether Brick (nether_bricks) + entry("Honey", new MaterialData(0.08, 0.85 )), // Honey (honey_block) + entry("Bone", new MaterialData(0.7, 0.55 )), // Bone (bone_block) + entry("Nether Wart", new MaterialData(0.2, 0.8 )), // Nether Wart (nether_wart, wart_block) + entry("Grass, Foliage", new MaterialData(0.2, 0.6 )), // Grass, Foliage (grass, crop, bamboo_sapling, sweet_berry_bush) + entry("Metal", new MaterialData(0.85, 0.5 )), // Metal (metal, copper, anvil) + entry("Aquatic Foliage", new MaterialData(0.15, 0.8 )), // Aquatic Foliage (wet_grass, lily_pad) + entry("Glass, Ice", new MaterialData(0.5, 0.45 )), // Glass, Ice (glass) + entry("Sculk Sensor", new MaterialData(0.4, 0.6 )), // Sculk Sensor (sculk_sensor) + entry("Nether Foliage", new MaterialData(0.15, 0.55 )), // Nether Foliage (roots, nether_sprouts) + entry("Shroomlight", new MaterialData(0.85, 0.75 )), // Shroomlight (shroomlight) + entry("Chain", new MaterialData(0.4, 0.4 )), // Chain (chain) + entry("Deepslate", new MaterialData(0.88, 0.55 )), // Deepslate (deepslate) + entry("Wood", new MaterialData(0.65, 0.45 )), // Wood (wood, ladder) + entry("Deepslate Tiles", new MaterialData(0.95, 0.55 )), // Deepslate Tiles (deepslate_tiles) + entry("Stone, Blackstone", new MaterialData(0.83, 0.5 )), // Stone, Blackstone (stone, calcite, gilded_blackstone) + entry("Slime", new MaterialData(1.0, 0.25 )), // Slime (slime_block) + entry("Polished Deepslate", new MaterialData(0.99, 0.55 )), // Polished Deepslate (polished_deepslate, deepslate_bricks) + entry("Snow", new MaterialData(0.1, 0.5 )), // Snow (snow) + entry("Azalea Leaves", new MaterialData(0.3, 0.35 )), // Azalea Leaves (azalea_leaves) + entry("Bamboo", new MaterialData(0.5, 0.4 )), // Bamboo (bamboo, scaffolding) + entry("Mushroom Stems", new MaterialData(0.6, 0.65 )), // Mushroom Stems (stem) + entry("Wool", new MaterialData(0.02, 1.0 )), // Wool (wool) + entry("Dry Foliage", new MaterialData(0.1, 0.15 )), // Dry Foliage (vine, hanging_roots, glow_lichen) + entry("Azalea Bush", new MaterialData(0.15, 0.5 )), // Azalea Bush (azalea) + entry("Lush Foliage", new MaterialData(0.2, 0.2 )), // Lush Foliage (cave_vines, spore_blossom, small_dripleaf, big_dripleaf) + entry("Netherite", new MaterialData(1.0, 0.6 )), // Netherite (netherite_block, lodestone) + entry("Ancient Debris", new MaterialData(0.45, 0.8 )), // Ancient Debris (ancient_debris) + entry("Nether Fungus Stem", new MaterialData(0.3, 0.55 )), // Nether Fungus Stem (nether_stem) + entry("Powder Snow", new MaterialData(0.01, 0.1 )), // Powder Snow (powder_snow) + entry("Tuff", new MaterialData(0.35, 0.4 )), // Tuff (tuff) + entry("Moss", new MaterialData(0.1, 0.85 )), // Moss (moss, moss_carpet) + entry("Nylium", new MaterialData(0.4, 0.55 )), // Nylium (nylium) + entry("Nether Fungus", new MaterialData(0.4, 0.6 )), // Nether Fungus (fungus) + entry("Lanterns", new MaterialData(0.75, 0.4 )), // Lanterns (lantern) + entry("Dripstone", new MaterialData(0.9, 0.6 )), // Dripstone (dripstone_block, pointed_dripstone) + entry("Default Material" , new MaterialData(0.5, 0.5 )), // Default Material () entry("block.minecraft.water" , new MaterialData(0.5, 0.03 )) // Water (block.minecraft.water) ),// diff --git a/src/main/java/dev/thedocruby/resounding/openal/ResoundingEFX.java b/src/main/java/dev/thedocruby/resounding/openal/ResoundingEFX.java index 6bc249d8..8b3de589 100644 --- a/src/main/java/dev/thedocruby/resounding/openal/ResoundingEFX.java +++ b/src/main/java/dev/thedocruby/resounding/openal/ResoundingEFX.java @@ -2,17 +2,16 @@ import dev.thedocruby.resounding.Resounding; import dev.thedocruby.resounding.ResoundingLog; -import dev.thedocruby.resounding.config.PrecomputedConfig; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.util.math.MathHelper; +import org.apache.commons.lang3.ArrayUtils; import org.jetbrains.annotations.NotNull; import org.lwjgl.openal.AL10; +import org.lwjgl.openal.AL11; import org.lwjgl.openal.ALC10; import org.lwjgl.openal.EXTEfx; -import java.util.ArrayList; -import java.util.List; +import static dev.thedocruby.resounding.config.PrecomputedConfig.pC; /* !!!Documentation for OpenAL!!! @@ -26,43 +25,212 @@ Source attributes(2&3): https://www.openal.org/documentation/openal-1.1-specific */ @Environment(EnvType.CLIENT) -public class ResoundingEFX { +public class ResoundingEFX { // TODO: Create separate debug toggle for OpenAl EFX instead of using pC.dLog private ResoundingEFX() {} - private static final List slots = new ArrayList<>(); - private static int directFilter0; + private static int[] slots = new int[0]; + private static int[] effects = new int[0]; + private static int[] filters = new int[0]; + private static int directFilter; + public static boolean efxEnabled = false; + private static boolean initialized = false; - public static void setupEFX() { + public static void setEffect// + ( + int id, + float decayTime, + float density, + float diffusion, + float gainHF, + float decayHFRatio, + float reflectionsGain, + float reflectionsDelay, + float lateReverbGain, + float lateReverbDelay + ) // + { + // + EXTEfx.alEffectf(effects[id], EXTEfx.AL_EAXREVERB_DENSITY, density); + ResoundingLog.checkErrorLog("Error while assigning \"density\" property to Effect object "+effects[id]+"! Attempted to assign value of \""+density+"\"."); + EXTEfx.alEffectf(effects[id], EXTEfx.AL_EAXREVERB_DIFFUSION, diffusion); + ResoundingLog.checkErrorLog("Error while assigning \"diffusion\" property to Effect object "+effects[id]+"! Attempted to assign value of \""+diffusion+"\"."); + EXTEfx.alEffectf(effects[id], EXTEfx.AL_EAXREVERB_GAIN, 0.89f); + ResoundingLog.checkErrorLog("Error while assigning \"gain\" property to Effect object "+effects[id]+"! Attempted to assign value of \""+0.89f+"\"."); + EXTEfx.alEffectf(effects[id], EXTEfx.AL_EAXREVERB_GAINHF, gainHF); + ResoundingLog.checkErrorLog("Error while assigning \"gainHF\" property to Effect object "+effects[id]+"! Attempted to assign value of \""+gainHF+"\"."); + EXTEfx.alEffectf(effects[id], EXTEfx.AL_EAXREVERB_DECAY_TIME, decayTime); + ResoundingLog.checkErrorLog("Error while assigning \"decayTime\" property to Effect object "+effects[id]+"! Attempted to assign value of \""+decayTime+"\"."); + EXTEfx.alEffectf(effects[id], EXTEfx.AL_EAXREVERB_DECAY_HFRATIO, decayHFRatio); + ResoundingLog.checkErrorLog("Error while assigning \"decayHFRatio\" property to Effect object "+effects[id]+"! Attempted to assign value of \""+decayHFRatio+"\"."); + EXTEfx.alEffectf(effects[id], EXTEfx.AL_EAXREVERB_REFLECTIONS_GAIN, reflectionsGain); + ResoundingLog.checkErrorLog("Error while assigning \"reflectionsGain\" property to Effect object "+effects[id]+"! Attempted to assign value of \""+reflectionsGain+"\"."); + EXTEfx.alEffectf(effects[id], EXTEfx.AL_EAXREVERB_REFLECTIONS_DELAY, reflectionsDelay); + ResoundingLog.checkErrorLog("Error while assigning \"reflectionsDelay\" property to Effect object "+effects[id]+"! Attempted to assign value of \""+reflectionsDelay+"\"."); + EXTEfx.alEffectf(effects[id], EXTEfx.AL_EAXREVERB_LATE_REVERB_GAIN, lateReverbGain); + ResoundingLog.checkErrorLog("Error while assigning \"lateReverbGain\" property to Effect object "+effects[id]+"! Attempted to assign value of \""+lateReverbGain+"\"."); + EXTEfx.alEffectf(effects[id], EXTEfx.AL_EAXREVERB_LATE_REVERB_DELAY, lateReverbDelay); + ResoundingLog.checkErrorLog("Error while assigning \"lateReverbDelay\" property to Effect object "+effects[id]+"! Attempted to assign value of \""+lateReverbDelay+"\"."); + EXTEfx.alEffectf(effects[id], EXTEfx.AL_EAXREVERB_AIR_ABSORPTION_GAINHF, 1f); + ResoundingLog.checkErrorLog("Error while assigning \"density\" property to Effect object "+effects[id]+"! Attempted to assign value of \""+1f+"\"."); + // + + //Attach updated effect object + EXTEfx.alAuxiliaryEffectSloti(slots[id], EXTEfx.AL_EFFECTSLOT_EFFECT, effects[id]); + if (!ResoundingLog.checkErrorLog("Error applying Effect object "+effects[id]+" to aux slot "+slots[id]+"!") && pC.dLog){ + Resounding.LOGGER.info("Successfully initialized Effect object {}!", effects[id]); + } + } + + public static void setFilter(int id, int sourceID, float gain, float cutoff) { + // Set reverb send filter values and set source to send to all reverb fx slots + EXTEfx.alFilterf(filters[id], EXTEfx.AL_LOWPASS_GAIN, gain); + ResoundingLog.checkErrorLog("Error while assigning \"gain\" property to Effect object "+filters[id]+"! Attempted to assign value of \""+gain+"\"."); + EXTEfx.alFilterf(filters[id], EXTEfx.AL_LOWPASS_GAINHF, cutoff); + ResoundingLog.checkErrorLog("Error while assigning \"cutoff\" property to Filter object "+filters[id]+"! Attempted to assign value of \""+cutoff+"\"."); + AL11.alSource3i(sourceID, EXTEfx.AL_AUXILIARY_SEND_FILTER, slots[id], 1, filters[id]); + ResoundingLog.checkErrorLog("Error applying Filter object "+filters[id]+" and aux slot "+slots[id]+" to source "+sourceID+"!"); + } + + private static int[] initAuxiliaryEffectSlots() { + if (slots.length < pC.resolution) { return createAuxiliaryEffectSlots(); } + return slots; + } + + /*private static int[] deleteAuxiliaryEffectSlots(){ // Remove unused OpenAL Auxiliary Effect slots + int[] slotsToRemove = ArrayUtils.subarray(slots, pC.resolution, slots.length); + if (pC.dLog) Resounding.LOGGER.info("Removing {} extra Auxiliary Effect slots...", slotsToRemove.length); + EXTEfx.alDeleteAuxiliaryEffectSlots(slotsToRemove); + for (int j : slotsToRemove) { + if (EXTEfx.alIsAuxiliaryEffectSlot(j)) { Resounding.LOGGER.error("Failed to delete Auxiliary Effect slot {}!", j); } + else if (pC.dLog) { Resounding.LOGGER.info("Auxiliary Effect slot {} deleted.", j); } + } + return ArrayUtils.subarray(slots , 0, pC.resolution); + }*/ + + private static int[] createAuxiliaryEffectSlots(){ // Create new OpenAL Auxiliary Effect slots + int[] newSlots = new int[pC.resolution - slots.length]; + if (pC.dLog) Resounding.LOGGER.info("Creating {} new Auxiliary Effect slots...", newSlots.length); + EXTEfx.alGenAuxiliaryEffectSlots(newSlots); + for(int i = 0; i < newSlots.length; i++) { + if(EXTEfx.alIsAuxiliaryEffectSlot(newSlots[i])){ + if (pC.dLog) Resounding.LOGGER.info("Auxiliary Effect slot {} created", newSlots[i]); + EXTEfx.alAuxiliaryEffectSloti(newSlots[i], EXTEfx.AL_EFFECTSLOT_AUXILIARY_SEND_AUTO, AL10.AL_TRUE); + ResoundingLog.checkErrorLog("Failed to initialize Auxiliary Effect slot "+newSlots[i]+"!"); + } else { Resounding.LOGGER.error("Failed to create Auxiliary Effect slot! (index {})", i); } + } + return ArrayUtils.addAll(slots, newSlots); + } + + private static int[] initEffectObjects(){ + if (effects.length < pC.resolution) { return createEffectObjects(); } + return effects; + } + + /* private static int[] deleteEffectObjects(){ // Remove unused OpenAL Effect objects + int[] effectsToRemove = ArrayUtils.subarray(effects, pC.resolution, effects.length); + if (pC.dLog) Resounding.LOGGER.info("Removing {} extra Effect objects...", effectsToRemove.length); + EXTEfx.alDeleteEffects(effectsToRemove); + for (int j : effectsToRemove) { + if (EXTEfx.alIsEffect(j)) { Resounding.LOGGER.error("Failed to delete Effect object {}!", j); } + else if (pC.dLog) { Resounding.LOGGER.info("Effect object {} deleted.", j); } + } + return ArrayUtils.subarray(effects, 0, pC.resolution); + }*/ + + private static int[] createEffectObjects(){ // Create new OpenAL Effect objects + int[] newEffects = new int[pC.resolution - effects.length]; + if (pC.dLog) Resounding.LOGGER.info("Creating {} new Effect objects...", newEffects.length); + EXTEfx.alGenEffects(newEffects); + for(int i = 0; i < newEffects.length; i++) { + if(EXTEfx.alIsEffect(newEffects[i])){ + if (pC.dLog) Resounding.LOGGER.info("Effect object {} created!", newEffects[i]); + EXTEfx.alEffecti(newEffects[i], EXTEfx.AL_EFFECT_TYPE, EXTEfx.AL_EFFECT_EAXREVERB); //Set effect object to be reverb + ResoundingLog.checkErrorLog("Failed to initialize Effect object "+newEffects[i]+"!"); + } else { Resounding.LOGGER.error("Failed to create Effect object! (index {})", i); } + } + return ArrayUtils.addAll(effects, newEffects); + } + + private static int[] initFilterObjects(){ + if (filters.length < pC.resolution) { return createFilterObjects(); } + return filters; + } + + /* private static int[] deleteFilterObjects(){ // Remove unused OpenAL Filter objects + int[] filtersToRemove = ArrayUtils.subarray(filters, pC.resolution, filters.length); + if (pC.dLog) Resounding.LOGGER.info("Removing {} extra Filter objects...", filtersToRemove.length); + EXTEfx.alDeleteFilters(filtersToRemove); + for (int j : filtersToRemove) { + if (EXTEfx.alIsFilter(j)) { Resounding.LOGGER.error("Failed to delete Filter object {}!", j); } + else if (pC.dLog) { Resounding.LOGGER.info("Filter object {} deleted.", j); } + } + return ArrayUtils.subarray(filters, 0, pC.resolution); + } */ + + private static int[] createFilterObjects(){ // Create new OpenAL Filter objects + int[] newFilters = new int[pC.resolution - filters.length]; + if (pC.dLog) Resounding.LOGGER.info("Creating {} new Filter objects...", newFilters.length); + EXTEfx.alGenFilters(newFilters); + for(int i = 0; i < newFilters.length; i++) { + if(EXTEfx.alIsFilter(newFilters[i])){ + if (pC.dLog) Resounding.LOGGER.info("Filter object {} created!", newFilters[i]); + EXTEfx.alFilteri(newFilters[i], EXTEfx.AL_FILTER_TYPE, EXTEfx.AL_FILTER_LOWPASS); + ResoundingLog.checkErrorLog("Failed to initialize Filter object "+newFilters[i]+"!"); + } else { Resounding.LOGGER.error("Failed to create Filter object! (index {})", i); } + } + return ArrayUtils.addAll(filters, newFilters); + } + + public static void initEAXReverb(){ // TODO: Figure out how to properly delete aux slots + if (!efxEnabled || pC.off) return; + + slots = initAuxiliaryEffectSlots(); + effects = initEffectObjects(); + filters = initFilterObjects(); + + for(int i = 0; i < pC.resolution; i++){ + double t = Math.pow((double) i / pC.resolution, pC.warpFactor); + double t1 = Math.pow((double)(i + 1) / pC.resolution, pC.warpFactor); + setEffect(i, + (float) Math.max(t1 * 4.142, 0.1), + (float) (t1 * 0.5), + (float) (0.95 - (pC.reverbCondensationFactor * t1)), + (float) (0.95 - (0.75 * t1)), + (float) Math.max(0.95 - (0.5 * t1), 0.1), + (float) Math.max(Math.pow(1 - t1, 5), 0.1), + (float) (t1 * 0.01), + (float) (Math.pow(t, 0.2) * 1.618), + (float) (t1 * 0.01) + ); + } + + if (!initialized){ + // Create filters + directFilter = EXTEfx.alGenFilters(); + if(!EXTEfx.alIsFilter(directFilter)) { Resounding.LOGGER.error("Failed to create direct filter object!"); } + else if(pC.dLog){ Resounding.LOGGER.info("Direct filter object created with ID {}", directFilter); } + EXTEfx.alFilteri(directFilter, EXTEfx.AL_FILTER_TYPE, EXTEfx.AL_FILTER_LOWPASS); + ResoundingLog.checkErrorLog("Failed to initialize direct filter object!"); + + initialized = true; + Resounding.LOGGER.info("Finished initializing OpenAL Auxiliary Effect slots!"); + } else if (pC.dLog) { Resounding.LOGGER.info("Finished re-initializing OpenAL Auxiliary Effect slots!"); } + } + + public static void setupEXTEfx() { //Get current context and device final long currentContext = ALC10.alcGetCurrentContext(); final long currentDevice = ALC10.alcGetContextsDevice(currentContext); - if (ALC10.alcIsExtensionPresent(currentDevice, "ALC_EXT_EFX")) { - Resounding.LOGGER.info("EFX Extension recognized."); - } else { - Resounding.LOGGER.error("EFX Extension not found on current device. Aborting."); - return; - } - // Delete previous filter if it was there - if (slots.size() > 0 && slots.get(0).initialised){ - EXTEfx.alDeleteFilters(directFilter0); - for (ReverbSlot slot : slots) { slot.delete(); } - slots.clear(); + if (!ALC10.alcIsExtensionPresent(currentDevice, "ALC_EXT_EFX")) { + Resounding.LOGGER.error("EFX Extension not found on current device, Aborting."); } - - // Create auxiliary effect slots - // TODO: make this parametric so it can be iterated, allowing for the effect slot count to be variable - slots.add(0, new ReverbSlot(0.15f , 0.0f, 1.0f, 0.2f, 0.99f, 0.8571429f, 2.5f, 0.001f, 1.26f, 0.011f, 0.994f, 0.16f).initialize()); - slots.add(1, new ReverbSlot(0.55f , 0.0f, 1.0f, 0.3f, 0.99f, 1 , 0.2f, 0.015f, 1.26f, 0.011f, 0.994f, 0.15f).initialize()); - slots.add(2, new ReverbSlot(1.68f , 0.1f, 1.0f, 0.5f, 0.99f, 1 , 0.0f, 0.021f, 1.26f, 0.021f, 0.994f, 0.13f).initialize()); - slots.add(3, new ReverbSlot(4.142f, 0.5f, 1.0f, 0.4f, 0.89f, 1 , 0.0f, 0.025f, 1.26f, 0.021f, 0.994f, 0.11f).initialize()); - - // Create filters - directFilter0 = EXTEfx.alGenFilters(); - EXTEfx.alFilteri(directFilter0, EXTEfx.AL_FILTER_TYPE, EXTEfx.AL_FILTER_LOWPASS); - Resounding.LOGGER.info("Direct filter object created with ID {}", directFilter0); + Resounding.LOGGER.info("EFX Extension recognized! "); + efxEnabled = true; + initEAXReverb(); } + // TODO: do more Javadoc /** * Registers the calculated reverb environment with OpenAL. * @@ -78,20 +246,19 @@ public static void setEnv( final double @NotNull [] sendGain, final double @NotNull [] sendCutoff, final double directGain, final double directCutoff ) { - if (sendGain.length != PrecomputedConfig.pC.resolution || sendCutoff.length != PrecomputedConfig.pC.resolution) { + if (sendGain.length != pC.resolution || sendCutoff.length != pC.resolution) { throw new IllegalArgumentException("Error: Reverb parameter count does not match reverb slot count!"); } // Set reverb send filter values and set source to send to all reverb fx slots - for(int i = 0; i < slots.size(); i++){ slots.get(i).applyFilter(sourceID, (float) sendGain[i], (float) sendCutoff[i]); } - - EXTEfx.alFilterf(directFilter0, EXTEfx.AL_LOWPASS_GAIN, (float) directGain); - EXTEfx.alFilterf(directFilter0, EXTEfx.AL_LOWPASS_GAINHF, (float) directCutoff); - AL10.alSourcei(sourceID, EXTEfx.AL_DIRECT_FILTER, directFilter0); - ResoundingLog.checkErrorLog("Set Environment directFilter0:"); + for(int i = 0; i < pC.resolution; i++){ setFilter(i, sourceID, (float) sendGain[i], (float) sendCutoff[i]); } - AL10.alSourcef(sourceID, EXTEfx.AL_AIR_ABSORPTION_FACTOR, MathHelper.clamp(PrecomputedConfig.pC.airAbsorption, 0.0f, 10.0f)); - ResoundingLog.checkErrorLog("Set Environment airAbsorption:"); + EXTEfx.alFilterf(directFilter, EXTEfx.AL_LOWPASS_GAIN, (float) directGain); + ResoundingLog.checkErrorLog("Error while assigning \"gain\" property to direct filter object! Attempted to assign value of \""+directGain+"\"."); + EXTEfx.alFilterf(directFilter, EXTEfx.AL_LOWPASS_GAINHF, (float) directCutoff); + ResoundingLog.checkErrorLog("Error while assigning \"cutoff\" property to direct filter object! Attempted to assign value of \""+directCutoff+"\"."); + AL10.alSourcei(sourceID, EXTEfx.AL_DIRECT_FILTER, directFilter); + ResoundingLog.checkErrorLog("Error applying direct filter object to source "+sourceID+"!"); } /* public static void setSoundPos(final int sourceID, final Vec3d pos) { diff --git a/src/main/java/dev/thedocruby/resounding/openal/ReverbSlot.java b/src/main/java/dev/thedocruby/resounding/openal/ReverbEffect.java similarity index 64% rename from src/main/java/dev/thedocruby/resounding/openal/ReverbSlot.java rename to src/main/java/dev/thedocruby/resounding/openal/ReverbEffect.java index 46f67dd9..6c61df70 100644 --- a/src/main/java/dev/thedocruby/resounding/openal/ReverbSlot.java +++ b/src/main/java/dev/thedocruby/resounding/openal/ReverbEffect.java @@ -1,22 +1,10 @@ package dev.thedocruby.resounding.openal; -import dev.thedocruby.resounding.Resounding; -import dev.thedocruby.resounding.ResoundingLog; -import dev.thedocruby.resounding.config.PrecomputedConfig; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import org.lwjgl.openal.AL10; -import org.lwjgl.openal.AL11; -import org.lwjgl.openal.EXTEfx; - -@Environment(EnvType.CLIENT) -@SuppressWarnings("DanglingJavadoc")//!!!!!!!!!!!! Ctrl + Shift + '-' !!!!!!!!!!!! -public class ReverbSlot { - public boolean initialised = false; - public int auxSlotId; - public int effectId; - public int filterId; +@Environment(EnvType.CLIENT) //!!!!!!!!!!!! Ctrl + Shift + '-' !!!!!!!!!!!! +class ReverbEffect { // TODO: Find a new home for these docs and delete class. // // from: Effects Guide (p. 66+) and other sources; altered /** @@ -50,7 +38,7 @@ public class ReverbSlot { * Although derived for rectangular rooms, the above expressions give good estimates of the modal behaviour for rooms of arbitrary shape, provided that the aspect ratio of the room is not too extreme. *

*/ - public final float density; // min: 0.0f max: 1.0f (?) default: 1.0f + public float density; // min: 0.0f max: 1.0f (?) default: 1.0f /** * The Reverb Diffusion property controls the echo density in the reverberation decay. * It is set by default to 1.0, which provides the highest density. @@ -66,7 +54,7 @@ public class ReverbSlot { * As a guide, for clearer more natural sounding mixes, vocals and instruments use low parameter settings. * If you’re looking to enhance percussion and drum hits use medium to high settings. */ - public final float diffusion; // min: 0.0f max: 1.0f (a linear multiplier value) default: 1.0f + public float diffusion; // min: 0.0f max: 1.0f (a linear multiplier value) default: 1.0f /** * The Reverb Gain property is the master volume control for the reflected sound * (both early reflections and reverberation), that the reverb effect adds to all sound sources. @@ -74,27 +62,27 @@ public class ReverbSlot { * The value of the Reverb Gain property ranges from 1.0 (0db) (the maximum amount) * to 0.0 (-100db) (no reflected sound at all). */ - public final float gain; // min: 0.0f max: 1.0f (Linear gain) default: 0.32f + public float gain; // min: 0.0f max: 1.0f (Linear gain) default: 0.32f /** * The Reverb Gain HF property further tweaks reflected sound by attenuating (gradually fading) it at high frequencies. * It controls a low-pass filter that applies globally to the reflected sound of all sound sources feeding the particular instance of the reverb effect. * The value of the Reverb Gain HF property ranges from 1.0 (0db) (no filter) to 0.0 (-100db) (virtually no reflected sound). * #HF Reference# sets the frequency at which the value of this property is measured. */ - public final float gainHF; // min: 0.0f max: 1.0f (Linear gain) default: 0.89f + public float gainHF; // min: 0.0f max: 1.0f (Linear gain) default: 0.89f /** * The Reverb Gain LF property further tweaks reflected sound by attenuating it at low frequencies. * It controls a high-pass filter that applies globally to the reflected sound of all sound sources feeding the particular instance of the reverb effect. * The value of the Reverb Gain LF property ranges from 1.0 (0db) (no filter) to 0.0 (-100db) (virtually no reflected sound). * #LF Reference# sets the frequency at which the value of this property is measured. */ - //public final float gainLF; // min: 0.0f max: 1.0f (Linear gain) default: 0.0f + public float gainLF; // min: 0.0f max: 1.0f (Linear gain) default: 0.0f /** * The Decay Time property sets the reverberation decay time. * It ranges from 0.1 (typically a small room with very dead surfaces) * to 20.0 (typically a large room with very live surfaces). */ - public final float decayTime; // min: 0.1f max: 20.0f (Seconds) default: 1.49f + public float decayTime; // min: 0.1f max: 20.0f (Seconds) default: 1.49f /** * The Decay HF Ratio property adjusts the spectral quality of the Decay Time parameter. * It is the ratio of high-frequency decay time relative to the time set by Decay Time. @@ -108,7 +96,7 @@ public class ReverbSlot { * so it’s shorter than the decay time of the mid-frequencies. * You hear a more natural reverberation. */ - public final float decayHFRatio; // min: 0.1f max: 20.0f (Linear multiplier) default: 0.83f + public float decayHFRatio; // min: 0.1f max: 20.0f (Linear multiplier) default: 0.83f /** * The Decay LF Ratio property adjusts the spectral quality of the Decay Time parameter. * It is the ratio of low-frequency decay time relative to the time set by Decay Time. @@ -122,7 +110,7 @@ public class ReverbSlot { * so it’s shorter than the decay time of the mid-frequencies. * You hear a more tinny reverberation. */ - //public final float decayLFRatio; // min: 0.1f max: 20.0f (Linear multiplier) default: 1.0f + public float decayLFRatio; // min: 0.1f max: 20.0f (Linear multiplier) default: 1.0f /** * The Reflections Gain property controls the overall amount of initial reflections relative to the Gain property. * (The Gain property sets the overall amount of reflected sound: both initial reflections and later reverberation.) @@ -135,14 +123,14 @@ public class ReverbSlot { * To simulate open or semi-open environments, you can maintain the amount of early reflections while reducing the value of * the Late Reverb Gain property, which controls later reflections. */ - public final float reflectionsGain; // min: 0.1f max: 3.16f (Linear gain) default: 0.05 + public float reflectionsGain; // min: 0.1f max: 3.16f (Linear gain) default: 0.05 /** * The Reflections Delay property is the amount of delay between the arrival time of the direct path from the source * to the first reflection from the source. It ranges from 0 to 300 milliseconds. * You can reduce or increase "Reflections Delay" to simulate closer or more distant reflective surfaces, * and therefore control the perceived size of the room. */ - public final float reflectionsDelay; // min: 0.0f max: 0.3f (Seconds) default: 0.007 + public float reflectionsDelay; // min: 0.0f max: 0.3f (Seconds) default: 0.007 /** * The Reflections Pan property is a 3D vector that controls the spatial distribution of the cluster of early reflections. * The direction of this vector controls the global direction of the reflections, @@ -157,7 +145,7 @@ public class ReverbSlot { * As the magnitude increases, the reflections become more focused in the direction pointed to by the vector. * A magnitude of 1.0 would represent the extreme case, where all reflections come from a single direction. */ - //public float[] reflectionsPan;//magnitude min: 0.0f max: 1.0f (Vector) default: [0f, 0f, 0f] + public float[] reflectionsPan;//magnitude min: 0.0f max: 1.0f (Vector) default: [0f, 0f, 0f] /** * The Late Reverb Gain property controls the overall amount of later reverberation relative to the Gain property. * (The Gain property sets the overall amount of both initial reflections and later reverberation.) @@ -166,20 +154,20 @@ public class ReverbSlot { * If you adjust Decay Time without changing Late Reverb Gain, the total intensity * (the averaged square of the amplitude) of the late reverberation remains constant. */ - public final float lateReverbGain; // min: 0.0f max: 10.0f (Linear gain) default: 1.26f + public float lateReverbGain; // min: 0.0f max: 10.0f (Linear gain) default: 1.26f /** * The Late Reverb Delay property defines the beginning time of the late reverberation * relative to the time of the initial reflection (the first of the early reflections). It ranges from 0 to 100 milliseconds. * Reducing or increasing Late Reverb Delay is useful for simulating a smaller or larger room. */ - public final float lateReverbDelay; // min: 0.0f max: 0.1f (Seconds) default: 0.011f + public float lateReverbDelay; // min: 0.0f max: 0.1f (Seconds) default: 0.011f /** * The Late Reverb Pan property is a 3D vector that controls the spatial distribution of the late reverb. * The direction of this vector controls the global direction of the reverb, * while its magnitude controls how focused the reverb are towards this direction. * The details under Reflections Pan (above) also apply to Late Reverb Pan. */ - //public float[] lateReverbPan;//magnitude min: 0.0f max: 1.0f (Vector) default: [0f, 0f, 0f] + public float[] lateReverbPan; //magnitude min: 0.0f max: 1.0f (Vector) default: [0f, 0f, 0f] /** * Echo Depth introduces a cyclic echo in the reverberation decay, which will be noticeable with transient or percussive sounds. * A larger value of Echo Depth will make this effect more prominent. @@ -196,8 +184,8 @@ public class ReverbSlot { * * If Diffusion is set to 0.0 and Echo Depth is set to 1.0, the echo will persist distinctly until the end of the reverberation decay. */ - //public float echoTime; // min: 0.075f max: 0.25f (Seconds) default: 0.25f - //public float echoDepth; // min: 0.0f max: 1.0f (Linear multiplier) default: 0.0f + public float echoTime; // min: 0.075f max: 0.25f (Seconds) default: 0.25f + public float echoDepth; // min: 0.0f max: 1.0f (Linear multiplier) default: 0.0f /** * Using these two properties, you can create a pitch modulation in the reverberant sound. * This will be most noticeable applied to sources that have tonal color or pitch. @@ -207,8 +195,8 @@ public class ReverbSlot { * Low values of Diffusion will contribute to reinforcing the perceived effect by * reducing the mixing of overlapping reflections in the reverberation decay. */ - //public final float modulationTime; // min: 0.004f max: 4.0f (Seconds) default: 0.25f - //public final float modulationDepth; // min: 0.0f max: 1.0f (Linear multiplier) default: 0.0f + public float modulationTime; // min: 0.004f max: 4.0f (Seconds) default: 0.25f + public float modulationDepth; // min: 0.0f max: 1.0f (Linear multiplier) default: 0.0f /** * The properties "HF Reference" and "LF Reference" determine respectively the frequencies at which * the high-frequency effects and the low-frequency effects created by EAX Reverb properties are measured, @@ -217,8 +205,8 @@ public class ReverbSlot { * low frequency and high frequency properties can be accurately controlled and will produce independent effects. * In other words, the LF Reference value should be less than 1/10 of the HF Reference value. */ - //public final float HFReference; // min: 1000f max: 20000f (Hertz) default: 5000f - //public final float LFReference; // min: 20.0f max: 1000f (Hertz) default: 250f + public float HFReference; // min: 1000f max: 20000f (Hertz) default: 5000f + public float LFReference; // min: 20.0f max: 1000f (Hertz) default: 250f /** * The Room Rolloff Factor property is one of the two methods available to attenuate the reflected sound * (containing both reflections and reverberation) according to source-listener distance. @@ -235,7 +223,7 @@ public class ReverbSlot { * (Note that this isn’t the case if the source property flag AL_AUXILIARY_SEND_FILTER_GAIN_AUTO is set to AL_FALSE) * You can use Room Rolloff Factor as an option to automatic control, so you can exaggerate or replace the default automatically-controlled rolloff. */ - public final float roomRolloffFactor; // min: 0.0f max: 10.0f (Linear multiplier) default: 0.0f + public float roomRolloffFactor; // min: 0.0f max: 10.0f (Linear multiplier) default: 0.0f /** * The Air Absorption Gain HF property controls the distance-dependent attenuation at high frequencies caused by the propagation medium. * It applies to reflected sound only. @@ -253,94 +241,9 @@ public class ReverbSlot { * value of Decay Time without the risk of getting an unnaturally long decay time at high frequencies. * If this flag is set to AL_FALSE, high-frequency decay time isn’t automatically limited. */ - //public final int decayHFLimit; // min:AL_FALSE max:AL_TRUE (Boolean) default: true + public int decayHFLimit; // min:AL_FALSE max:AL_TRUE (Boolean) default: true //
- public ReverbSlot(/**/float decayTime, float density, float diffusion, float gain, float gainHF, float decayHFRatio, float reflectionsGain, float reflectionsDelay, float lateReverbGain, float lateReverbDelay, float airAbsorptionGainHF, float roomRolloffFactor/**/) { - this.decayTime = decayTime; - this.density = density; - this.diffusion = diffusion; - this.gain = gain; - this.gainHF = gainHF; - this.decayHFRatio = decayHFRatio; - this.reflectionsGain = reflectionsGain; - this.reflectionsDelay = reflectionsDelay; - this.lateReverbGain = lateReverbGain; - this.lateReverbDelay = lateReverbDelay; - this.airAbsorptionGainHF = airAbsorptionGainHF; - this.roomRolloffFactor = roomRolloffFactor; - } - - public ReverbSlot initialize() { - if (initialised) delete(); - - // - // Create auxiliary effect slot (secondary audio output) - auxSlotId = EXTEfx.alGenAuxiliaryEffectSlots(); - Resounding.LOGGER.info("Aux slot {} created", auxSlotId); - EXTEfx.alAuxiliaryEffectSloti(auxSlotId, EXTEfx.AL_EFFECTSLOT_AUXILIARY_SEND_AUTO, AL10.AL_TRUE); - ResoundingLog.checkErrorLog("Failed creating aux slot "+auxSlotId+"!"); - - //Create effect objects - effectId = EXTEfx.alGenEffects(); //Create effect object - EXTEfx.alEffecti(effectId, EXTEfx.AL_EFFECT_TYPE, EXTEfx.AL_EFFECT_EAXREVERB); //Set effect object to be reverb - ResoundingLog.checkErrorLog("Failed creating reverb effect object "+effectId+"!"); - Resounding.LOGGER.info("Created effect object {} for aux slot {}.", effectId, auxSlotId); - - filterId = EXTEfx.alGenFilters(); - EXTEfx.alFilteri(filterId, EXTEfx.AL_FILTER_TYPE, EXTEfx.AL_FILTER_LOWPASS); - Resounding.LOGGER.info("Created filter object {} for aux slot {}.", filterId, auxSlotId); - // - - initialised = true; - return this.set(); - } - - public void delete() { - EXTEfx.alDeleteAuxiliaryEffectSlots(auxSlotId); - EXTEfx.alDeleteEffects(effectId); - EXTEfx.alDeleteFilters(filterId); - initialised = false; - } - - private ReverbSlot set() { - // - EXTEfx.alEffectf(effectId, EXTEfx.AL_EAXREVERB_DENSITY, density); - ResoundingLog.checkErrorLog("Error while assigning reverb density: " + density); - EXTEfx.alEffectf(effectId, EXTEfx.AL_EAXREVERB_DIFFUSION, diffusion); - ResoundingLog.checkErrorLog("Error while assigning reverb diffusion: " + diffusion); - EXTEfx.alEffectf(effectId, EXTEfx.AL_EAXREVERB_GAIN, gain); - ResoundingLog.checkErrorLog("Error while assigning reverb gain: " + gain); - EXTEfx.alEffectf(effectId, EXTEfx.AL_EAXREVERB_GAINHF, gainHF); - ResoundingLog.checkErrorLog("Error while assigning reverb gainHF: " + gainHF); - EXTEfx.alEffectf(effectId, EXTEfx.AL_EAXREVERB_DECAY_TIME, decayTime); - ResoundingLog.checkErrorLog("Error while assigning reverb decayTime: " + decayTime); - EXTEfx.alEffectf(effectId, EXTEfx.AL_EAXREVERB_DECAY_HFRATIO, decayHFRatio); - ResoundingLog.checkErrorLog("Error while assigning reverb decayHFRatio: " + decayHFRatio); - EXTEfx.alEffectf(effectId, EXTEfx.AL_EAXREVERB_REFLECTIONS_GAIN, reflectionsGain); - ResoundingLog.checkErrorLog("Error while assigning reverb reflectionsGain: " + reflectionsGain); - EXTEfx.alEffectf(effectId, EXTEfx.AL_EAXREVERB_REFLECTIONS_DELAY, reflectionsDelay); - ResoundingLog.checkErrorLog("Error while assigning reverb reflectionsDelay: " + reflectionsDelay); - EXTEfx.alEffectf(effectId, EXTEfx.AL_EAXREVERB_LATE_REVERB_GAIN, lateReverbGain); - ResoundingLog.checkErrorLog("Error while assigning reverb lateReverbGain: " + lateReverbGain); - EXTEfx.alEffectf(effectId, EXTEfx.AL_EAXREVERB_LATE_REVERB_DELAY, lateReverbDelay); - ResoundingLog.checkErrorLog("Error while assigning reverb lateReverbDelay: " + lateReverbDelay); - EXTEfx.alEffectf(effectId, EXTEfx.AL_EAXREVERB_AIR_ABSORPTION_GAINHF, airAbsorptionGainHF); - ResoundingLog.checkErrorLog("Error while assigning reverb airAbsorptionGainHF: " + airAbsorptionGainHF); - EXTEfx.alEffectf(effectId, EXTEfx.AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, (float) (roomRolloffFactor * PrecomputedConfig.defaultAttenuationFactor)); - ResoundingLog.checkErrorLog("Error while assigning reverb roomRolloffFactor: " + roomRolloffFactor * PrecomputedConfig.defaultAttenuationFactor); - // - - //Attach updated effect object - EXTEfx.alAuxiliaryEffectSloti(auxSlotId, EXTEfx.AL_EFFECTSLOT_EFFECT, effectId); - return this; - } + public ReverbEffect(){} - public void applyFilter(int sourceID, float gain, float cutoff) { - // Set reverb send filter values and set source to send to all reverb fx slots - EXTEfx.alFilterf(filterId, EXTEfx.AL_LOWPASS_GAIN, gain); - EXTEfx.alFilterf(filterId, EXTEfx.AL_LOWPASS_GAINHF, cutoff); - AL11.alSource3i(sourceID, EXTEfx.AL_AUXILIARY_SEND_FILTER, auxSlotId, 1, filterId); - ResoundingLog.checkErrorLog("Set Environment filter"+filterId+" to "+auxSlotId+":"); - } } diff --git a/src/main/resources/assets/resounding/lang/en_us.json b/src/main/resources/assets/resounding/lang/en_us.json index 9ccf4dcc..09cd49ab 100644 --- a/src/main/resources/assets/resounding/lang/en_us.json +++ b/src/main/resources/assets/resounding/lang/en_us.json @@ -6,8 +6,8 @@ "text.autoconfig.resounding.option.General": "General options:", "text.autoconfig.resounding.option.Performance": "Performance options:", "text.autoconfig.resounding.option.Materials": "Materials:", - "text.autoconfig.resounding.option.Vlads_Tweaks": "Vlad's tweaks:", - "text.autoconfig.resounding.option.Misc": "Logging options:", + "text.autoconfig.resounding.option.Misc": "Other options:", + "text.autoconfig.resounding.option.Debug": "Debug options:", "text.autoconfig.resounding.option.General.attenuationFactor": "Attenuation (fade over distance) factor", "text.autoconfig.resounding.option.General.globalReverbGain": "Reverb volume gain", @@ -28,19 +28,19 @@ "text.autoconfig.resounding.option.Materials.materialProperties": "Material Properties", "text.autoconfig.resounding.option.Materials.blockWhiteList": "Block Whitelist", - "text.autoconfig.resounding.option.Vlads_Tweaks.recordsDisable": "Skip Jukebox/Note Block occlusion", - "text.autoconfig.resounding.option.Vlads_Tweaks.continuousRefreshRate": "Continuous sources refresh interval", - "text.autoconfig.resounding.option.Vlads_Tweaks.maxDirectOcclusionFromBlocks": "Maximum direct occlusion", - "text.autoconfig.resounding.option.Vlads_Tweaks._9RayDirectOcclusion": "9 ray direct occlusion calculation", - "text.autoconfig.resounding.option.Vlads_Tweaks.soundDirectionEvaluation": "Re-calculate sound direction", - "text.autoconfig.resounding.option.Vlads_Tweaks.directRaysDirEvalMultiplier": "Sound reflection bias", - "text.autoconfig.resounding.option.Vlads_Tweaks.notOccludedNoRedirect": "Skip redirecting visible blocks", - - "text.autoconfig.resounding.option.Misc.debugLogging": "Logging", - "text.autoconfig.resounding.option.Misc.occlusionLogging": "Occlusion logging", - "text.autoconfig.resounding.option.Misc.environmentLogging": "Environment logging", - "text.autoconfig.resounding.option.Misc.performanceLogging": "Performance logging", - "text.autoconfig.resounding.option.Misc.raytraceParticles": "Raytracing Particles", + "text.autoconfig.resounding.option.Misc.recordsDisable": "Skip Jukebox/Note Block occlusion", + "text.autoconfig.resounding.option.Misc.continuousRefreshRate": "Continuous sources refresh interval", + "text.autoconfig.resounding.option.Misc.maxDirectOcclusionFromBlocks": "Maximum direct occlusion", + "text.autoconfig.resounding.option.Misc._9RayDirectOcclusion": "9 ray direct occlusion calculation", + "text.autoconfig.resounding.option.Misc.soundDirectionEvaluation": "Re-calculate sound direction", + "text.autoconfig.resounding.option.Misc.directRaysDirEvalMultiplier": "Sound reflection bias", + "text.autoconfig.resounding.option.Misc.notOccludedNoRedirect": "Skip redirecting visible blocks", + + "text.autoconfig.resounding.option.Debug.debugLogging": "Logging", + "text.autoconfig.resounding.option.Debug.occlusionLogging": "Occlusion logging", + "text.autoconfig.resounding.option.Debug.environmentLogging": "Environment logging", + "text.autoconfig.resounding.option.Debug.performanceLogging": "Performance logging", + "text.autoconfig.resounding.option.Debug.raytraceParticles": "Raytracing Particles", "text.autoconfig.resounding.option.preset": "Preset",