package ocelot.desktop.audio

import java.nio.ByteBuffer

object BeepGenerator {
  def newBeep(pattern: String, frequency: Short, duration: Short): SoundSource.Factory = {
    val sampleCounts = pattern.toCharArray
      .map(ch => if (ch == '.') duration else 2 * duration)
      .map(_ * Audio.sampleRate / 1000)

    val pauseSampleCount = 50 * Audio.sampleRate / 1000
    val data = ByteBuffer.allocateDirect(2 * (sampleCounts.sum + (sampleCounts.length - 1) * pauseSampleCount))
    val step = frequency / Audio.sampleRate.toFloat
    var offset = 0f

    for (sampleCount <- sampleCounts) {
      for (_ <- 0 until sampleCount) {
        val angle = 2 * math.Pi * offset
        val value = (math.signum(math.sin(angle)) * 8192).toShort
        offset += step
        if (offset > 1) offset -= 1
        data.put((value & 0xff).toByte)
        data.put(((value >> 8) & 0xff).toByte)
      }
      if (data.hasRemaining) {
        for (_ <- 0 until pauseSampleCount) {
          data.putShort(32767)
        }
      }
    }

    data.rewind()
    SoundSource.fromSamples(SoundSamples(data, Audio.sampleRate, SoundSamples.Format.Mono16), SoundCategory.Beep)
  }
}
