mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-16 02:39:48 -04:00
Added check for out of memory errors when trying to play computer beeps.
This commit is contained in:
parent
39f666ea94
commit
29d112ac33
@ -11,7 +11,7 @@ import net.minecraft.client.audio.SoundCategory
|
||||
import org.lwjgl.BufferUtils
|
||||
import org.lwjgl.openal.AL
|
||||
import org.lwjgl.openal.AL10
|
||||
import org.lwjgl.openal.Util
|
||||
import org.lwjgl.openal.OpenALException
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
@ -29,13 +29,14 @@ object Audio {
|
||||
|
||||
private def volume = Minecraft.getMinecraft.gameSettings.getSoundLevel(SoundCategory.BLOCKS)
|
||||
|
||||
private var errored = false
|
||||
private var disableAudio = false
|
||||
|
||||
def play(x: Float, y: Float, z: Float, frequencyInHz: Int, durationInMilliseconds: Int): Unit = {
|
||||
play(x, y, z, ".", frequencyInHz, durationInMilliseconds)
|
||||
}
|
||||
|
||||
def play(x: Float, y: Float, z: Float, pattern: String, frequencyInHz: Int = 1000, durationInMilliseconds: Int = 200) {
|
||||
def play(x: Float, y: Float, z: Float, pattern: String, frequencyInHz: Int = 1000, durationInMilliseconds: Int = 200): Unit = {
|
||||
if (!disableAudio) {
|
||||
val distanceBasedGain = math.max(0, 1 - Minecraft.getMinecraft.thePlayer.getDistance(x, y, z) / 12).toFloat
|
||||
val gain = distanceBasedGain * volume
|
||||
if (gain > 0 && AL.isCreated) {
|
||||
@ -69,12 +70,27 @@ object Audio {
|
||||
}
|
||||
data.rewind()
|
||||
|
||||
sources.synchronized(sources += new Source(x, y, z, data, gain))
|
||||
// Watch out for sound cards running out of memory... this apparently
|
||||
// really does happen. I'm assuming this is due to too many sounds being
|
||||
// kept loaded, since from what I can see OC's releasing its audio
|
||||
// memory as it should.
|
||||
try sources.synchronized(sources += new Source(x, y, z, data, gain)) catch {
|
||||
case e: LessUselessOpenALException =>
|
||||
if (e.errorCode == AL10.AL_OUT_OF_MEMORY) {
|
||||
// Well... let's just stop here.
|
||||
OpenComputers.log.info("Couldn't play computer speaker sound because your sound card ran out of memory. Either your sound card is just really low-end, or there are just too many sounds in use already by other mods. Disabling computer speakers to avoid spamming your log file now.")
|
||||
disableAudio = true
|
||||
}
|
||||
else {
|
||||
OpenComputers.log.warn("Error playing computer speaker sound.", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def update() {
|
||||
if (!errored) {
|
||||
if (!disableAudio) {
|
||||
sources.synchronized(sources --= sources.filter(_.checkFinished))
|
||||
|
||||
// Clear error stack.
|
||||
@ -82,7 +98,7 @@ object Audio {
|
||||
try AL10.alGetError() catch {
|
||||
case _: UnsatisfiedLinkError =>
|
||||
OpenComputers.log.warn("Negotiations with OpenAL broke down, disabling sounds.")
|
||||
errored = true
|
||||
disableAudio = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -94,25 +110,25 @@ object Audio {
|
||||
|
||||
val (source, buffer) = {
|
||||
val buffer = AL10.alGenBuffers()
|
||||
Util.checkALError()
|
||||
checkALError()
|
||||
|
||||
try {
|
||||
AL10.alBufferData(buffer, AL10.AL_FORMAT_MONO8, data, sampleRate)
|
||||
Util.checkALError()
|
||||
checkALError()
|
||||
|
||||
val source = AL10.alGenSources()
|
||||
Util.checkALError()
|
||||
checkALError()
|
||||
|
||||
try {
|
||||
AL10.alSourceQueueBuffers(source, buffer)
|
||||
Util.checkALError()
|
||||
checkALError()
|
||||
|
||||
AL10.alSource3f(source, AL10.AL_POSITION, x, y, z)
|
||||
AL10.alSourcef(source, AL10.AL_GAIN, gain * 0.3f)
|
||||
Util.checkALError()
|
||||
checkALError()
|
||||
|
||||
AL10.alSourcePlay(source)
|
||||
Util.checkALError()
|
||||
checkALError()
|
||||
|
||||
(source, buffer)
|
||||
}
|
||||
@ -136,6 +152,17 @@ object Audio {
|
||||
}
|
||||
}
|
||||
|
||||
// Having the error code in an accessible way is really cool, you know.
|
||||
class LessUselessOpenALException(val errorCode: Int) extends OpenALException(errorCode)
|
||||
|
||||
// Custom implementation of Util.checkALError() that uses our custom exception.
|
||||
def checkALError(): Unit = {
|
||||
val errorCode = AL10.alGetError()
|
||||
if (errorCode != AL10.AL_NO_ERROR) {
|
||||
throw new LessUselessOpenALException(errorCode)
|
||||
}
|
||||
}
|
||||
|
||||
FMLCommonHandler.instance.bus.register(this)
|
||||
|
||||
@SubscribeEvent
|
||||
|
Loading…
x
Reference in New Issue
Block a user