package ocelot.desktop.audio import ocelot.desktop.geometry.Vector3D import java.util.concurrent.TimeUnit import scala.concurrent.duration.Duration class SoundSource( val kind: SoundSource.Kind, val soundCategory: SoundCategory.Value, val looping: Boolean, val pitch: Float, var volume: Float, var position: Vector3D = Vector3D(0, 0, 0), ) { def duration: Option[Duration] = kind match { case SoundSource.KindSoundBuffer(buffer) => Some(Duration(buffer.numSamples.toFloat / buffer.sampleRate, TimeUnit.SECONDS)) case SoundSource.KindSoundSamples(SoundSamples(buffer, rate, format)) => val bps = format match { case SoundSamples.Format.Stereo16 => 2 case SoundSamples.Format.Mono8 => 1 case SoundSamples.Format.Mono16 => 2 } Some(Duration(buffer.limit().toFloat / (rate * bps), TimeUnit.SECONDS)) case SoundSource.KindStream(_) => None } def status: SoundSource.Status.Value = { Audio.getSourceStatus(this) } def playing: Boolean = { status == SoundSource.Status.Playing } def paused: Boolean = { status == SoundSource.Status.Paused } def stopped: Boolean = { status == SoundSource.Status.Stopped } def play(): Unit = { Audio.playSource(this) } def pause(): Unit = { Audio.pauseSource(this) } def stop(): Unit = { Audio.stopSource(this) } } object SoundSource { sealed trait Kind case class KindSoundBuffer(buffer: SoundBuffer) extends Kind case class KindSoundSamples(samples: SoundSamples) extends Kind case class KindStream(stream: SoundStream) extends Kind def fromBuffer(buffer: SoundBuffer, soundCategory: SoundCategory.Value, looping: Boolean = false, pitch: Float = 1f, volume: Float = 1f): SoundSource = { new SoundSource(SoundSource.KindSoundBuffer(buffer), soundCategory, looping, pitch, volume) } def fromSamples(samples: SoundSamples, soundCategory: SoundCategory.Value, looping: Boolean = false, pitch: Float = 1f, volume: Float = 1f): SoundSource = { new SoundSource(SoundSource.KindSoundSamples(samples), soundCategory, looping, pitch, volume) } def fromStream(stream: SoundStream, soundCategory: SoundCategory.Value, looping: Boolean = false, pitch: Float = 1f, volume: Float = 1f): SoundSource = { new SoundSource(SoundSource.KindStream(stream), soundCategory, looping, pitch, volume) } object Status extends Enumeration { val Playing, Paused, Stopped = Value } // ---------------------------------------------------------------- object InterfaceClick extends ClickSoundSource { override lazy val press: SoundSource = SoundSource.fromBuffer(SoundBuffers.InterfaceClickPress, SoundCategory.Interface) override lazy val release: SoundSource = SoundSource.fromBuffer(SoundBuffers.InterfaceClickRelease, SoundCategory.Interface) } object InterfaceClickLow extends ClickSoundSource { override lazy val press: SoundSource = SoundSource.fromBuffer(SoundBuffers.InterfaceClickPress, SoundCategory.Interface, pitch = 0.8f) override lazy val release: SoundSource = SoundSource.fromBuffer(SoundBuffers.InterfaceClickRelease, SoundCategory.Interface, pitch = 0.8f) } object InterfaceTick extends ClickSoundSource { override lazy val press: SoundSource = SoundSource.fromBuffer(SoundBuffers.InterfaceTickPress, SoundCategory.Interface) override lazy val release: SoundSource = SoundSource.fromBuffer(SoundBuffers.InterfaceTickRelease, SoundCategory.Interface) } lazy val InterfaceShutter: SoundSource = SoundSource.fromBuffer(SoundBuffers.InterfaceShutter, SoundCategory.Interface) object MinecraftClick extends ClickSoundSource { override lazy val press: SoundSource = SoundSource.fromBuffer(SoundBuffers.MinecraftClickPress, SoundCategory.Interface) override lazy val release: SoundSource = SoundSource.fromBuffer(SoundBuffers.MinecraftClickRelease, SoundCategory.Interface) } lazy val MachineFloppyInsert: SoundSource = SoundSource.fromBuffer(SoundBuffers.MachineFloppyInsert, SoundCategory.Environment) lazy val MachineFloppyEject: SoundSource = SoundSource.fromBuffer(SoundBuffers.MachineFloppyEject, SoundCategory.Environment) }