mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-13 12:04:06 +09:00
antialiased squarewave generator
Former-commit-id: c7d69891460f8f04681c28e1d05421ec1a93379d Former-commit-id: 5767a006dd9221f1839eec3b1b0223670262f8fd
This commit is contained in:
@@ -1,11 +1,24 @@
|
|||||||
package net.torvald.terrarum
|
package net.torvald.terrarum
|
||||||
|
|
||||||
|
|
||||||
|
import com.jme3.math.FastMath
|
||||||
|
import net.torvald.terrarum.gameactors.floorInt
|
||||||
|
import net.torvald.terrarum.gameactors.roundInt
|
||||||
|
import net.torvald.terrarum.virtualcomputer.terminal.ALException
|
||||||
import org.apache.commons.csv.CSVRecord
|
import org.apache.commons.csv.CSVRecord
|
||||||
|
import org.lwjgl.BufferUtils
|
||||||
|
import org.lwjgl.openal.AL
|
||||||
|
import org.lwjgl.openal.AL10
|
||||||
import org.newdawn.slick.GameContainer
|
import org.newdawn.slick.GameContainer
|
||||||
import org.newdawn.slick.Graphics
|
import org.newdawn.slick.Graphics
|
||||||
import org.newdawn.slick.state.BasicGameState
|
import org.newdawn.slick.state.BasicGameState
|
||||||
import org.newdawn.slick.state.StateBasedGame
|
import org.newdawn.slick.state.StateBasedGame
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
import java.util.*
|
||||||
|
import javax.sound.sampled.AudioFormat
|
||||||
|
import javax.sound.sampled.AudioInputStream
|
||||||
|
import javax.sound.sampled.AudioSystem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 16-09-05.
|
* Created by minjaesong on 16-09-05.
|
||||||
@@ -13,28 +26,118 @@ import org.newdawn.slick.state.StateBasedGame
|
|||||||
class StateTestingSandbox : BasicGameState() {
|
class StateTestingSandbox : BasicGameState() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override fun init(container: GameContainer?, game: StateBasedGame?) {
|
override fun init(container: GameContainer?, game: StateBasedGame?) {
|
||||||
|
playTone()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val sampleRate = 22050
|
||||||
|
private var beepSource: Int? = null
|
||||||
|
private var beepBuffer: Int? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param duration : milliseconds
|
||||||
|
*/
|
||||||
|
private fun makeAudioData(duration: Int, freq: Float): ByteBuffer {
|
||||||
|
val audioData = BufferUtils.createByteBuffer(duration.times(sampleRate).div(1000))
|
||||||
|
|
||||||
|
val realDuration = duration * sampleRate / 1000
|
||||||
|
val chopSize = freq * 2f / sampleRate
|
||||||
|
|
||||||
|
val amp = Math.max(4600f / freq, 1f)
|
||||||
|
val nHarmonics = 4
|
||||||
|
|
||||||
|
val transitionThre = 1150f
|
||||||
|
|
||||||
|
if (freq < transitionThre) { // chopper generator (for low freq)
|
||||||
|
for (x in 0..realDuration - 1) {
|
||||||
|
var sine: Float = amp * FastMath.cos(FastMath.PI * x * chopSize)
|
||||||
|
if (sine > 1f) sine = 1f
|
||||||
|
else if (sine < -1f) sine = -1f
|
||||||
|
audioData.put(
|
||||||
|
(0.5f + 0.5f * sine).times(0xFF).toByte()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // harmonics generator (for high freq)
|
||||||
|
for (x in 0..realDuration - 1) {
|
||||||
|
var sine: Float = 0f
|
||||||
|
for (k in 0..nHarmonics) { // mix only odd harmonics to make squarewave
|
||||||
|
sine += (1f / (2*k + 1)) *
|
||||||
|
FastMath.sin((2*k + 1) * FastMath.PI * x * chopSize)
|
||||||
|
}
|
||||||
|
audioData.put(
|
||||||
|
(0.5f + 0.5f * sine).times(0xFF).toByte()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
audioData.rewind()
|
||||||
|
|
||||||
|
return audioData
|
||||||
|
}
|
||||||
|
|
||||||
|
var audioData: ByteBuffer? = null
|
||||||
|
|
||||||
|
private fun playTone() {
|
||||||
|
if (audioData == null) audioData = makeAudioData(5000, 27.5f)
|
||||||
|
|
||||||
|
|
||||||
|
if (!AL.isCreated()) AL.create()
|
||||||
|
|
||||||
|
|
||||||
|
// Clear error stack.
|
||||||
|
AL10.alGetError()
|
||||||
|
|
||||||
|
beepBuffer = AL10.alGenBuffers()
|
||||||
|
checkALError()
|
||||||
|
|
||||||
|
try {
|
||||||
|
AL10.alBufferData(beepBuffer!!, AL10.AL_FORMAT_MONO8, audioData, sampleRate)
|
||||||
|
checkALError()
|
||||||
|
|
||||||
|
beepSource = AL10.alGenSources()
|
||||||
|
checkALError()
|
||||||
|
|
||||||
|
try {
|
||||||
|
AL10.alSourceQueueBuffers(beepSource!!, beepBuffer!!)
|
||||||
|
checkALError()
|
||||||
|
|
||||||
|
AL10.alSource3f(beepSource!!, AL10.AL_POSITION, 0f, 0f, 1f)
|
||||||
|
AL10.alSourcef(beepSource!!, AL10.AL_REFERENCE_DISTANCE, 1f)
|
||||||
|
AL10.alSourcef(beepSource!!, AL10.AL_MAX_DISTANCE, 1f)
|
||||||
|
AL10.alSourcef(beepSource!!, AL10.AL_GAIN, 0.3f)
|
||||||
|
checkALError()
|
||||||
|
|
||||||
|
AL10.alSourcePlay(beepSource!!)
|
||||||
|
checkALError()
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (e: ALException) {
|
||||||
|
AL10.alDeleteSources(beepSource!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e: ALException) {
|
||||||
|
if (beepSource != null) AL10.alDeleteSources(beepSource!!)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun update(container: GameContainer?, game: StateBasedGame?, delta: Int) {
|
override fun update(container: GameContainer?, game: StateBasedGame?, delta: Int) {
|
||||||
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom implementation of Util.checkALError() that uses our custom exception.
|
||||||
|
private fun checkALError() {
|
||||||
|
val errorCode = AL10.alGetError()
|
||||||
|
if (errorCode != AL10.AL_NO_ERROR) {
|
||||||
|
throw ALException(errorCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun getID() = Terrarum.STATE_ID_TEST_SHIT
|
override fun getID() = Terrarum.STATE_ID_TEST_SHIT
|
||||||
|
|
||||||
override fun render(container: GameContainer?, game: StateBasedGame?, g: Graphics?) {
|
override fun render(container: GameContainer?, game: StateBasedGame?, g: Graphics?) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun intVal(rec: CSVRecord, s: String): Int {
|
|
||||||
var ret = -1
|
|
||||||
try {
|
|
||||||
ret = Integer.decode(rec.get(s))!!
|
|
||||||
}
|
|
||||||
catch (e: NullPointerException) {
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -100,8 +100,8 @@ constructor(gamename: String) : StateBasedGame(gamename) {
|
|||||||
|
|
||||||
gc.graphics.clear() // clean up any 'dust' in the buffer
|
gc.graphics.clear() // clean up any 'dust' in the buffer
|
||||||
|
|
||||||
addState(StateVTTest())
|
//addState(StateVTTest())
|
||||||
//addState(StateTestingSandbox())
|
addState(StateTestingSandbox())
|
||||||
//addState(StateSplash())
|
//addState(StateSplash())
|
||||||
//addState(StateMonitorCheck())
|
//addState(StateMonitorCheck())
|
||||||
//addState(StateFontTester())
|
//addState(StateFontTester())
|
||||||
|
|||||||
Reference in New Issue
Block a user