Skip to content

Instantly share code, notes, and snippets.

@dlew
Created September 24, 2022 14:36
Show Gist options
  • Save dlew/9d3e60c22872b9637033436910e86201 to your computer and use it in GitHub Desktop.
Save dlew/9d3e60c22872b9637033436910e86201 to your computer and use it in GitHub Desktop.
Trombone Champ hacky trombone code
import be.tarsos.dsp.AudioEvent
import be.tarsos.dsp.io.jvm.AudioDispatcherFactory
import be.tarsos.dsp.pitch.PitchDetectionHandler
import be.tarsos.dsp.pitch.PitchDetectionResult
import be.tarsos.dsp.pitch.PitchProcessor
import be.tarsos.dsp.pitch.PitchProcessor.PitchEstimationAlgorithm
import java.awt.Robot
import java.awt.event.InputEvent
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import kotlin.math.log2
import kotlin.math.roundToInt
var pressing = false
val detectionHandler = object : PitchDetectionHandler {
val robot = Robot()
// Controls where upper C and lower C are on my computer (Y-value)
val min = 196
val max = 955
val range = max - min
// Controls the range of notes we accept
val minInput = 124.0
val middleC = 261.63
val maxInput = 556.0
// When true, disables Robot
val debug = false
override fun handlePitch(pitchDetectionResult: PitchDetectionResult, audioEvent: AudioEvent) {
if (pitchDetectionResult.isPitched) {
val pitch = pitchDetectionResult.pitch
val halftones = 12 * log2(pitch / middleC)
val percentUp = (halftones + 12) / 24.0
if (pitch !in (minInput..maxInput)) {
// For some reason pitch detection hits the floor every once in a while, ignore it
println("IGNORE pitch=${pitchDetectionResult.pitch.roundToInt()} halftones=${halftones.roundToInt()} precent=${(percentUp * 100).roundToInt()}")
return
}
else {
println("pitch=${pitchDetectionResult.pitch.roundToInt()} halftones=${halftones.roundToInt()} precent=${(percentUp * 100).roundToInt()}")
}
val where = percentUp * range
val y = max - where
if (!debug) {
robot.mouseMove(500, y.roundToInt())
}
if (!pressing) {
if (!debug) {
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK)
}
pressing = true;
println("PRESS")
}
}
else if (pressing) {
if (!debug) {
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK)
}
pressing = false;
println("RELEASE")
}
}
}
fun main(args: Array<String>) {
val sampleRate = 44100
val bufferSize = 4096
val bufferOverlap = 0
val dispatcher = AudioDispatcherFactory.fromDefaultMicrophone(sampleRate, bufferSize, bufferOverlap)
val algo = PitchEstimationAlgorithm.MPM;
dispatcher.addAudioProcessor(PitchProcessor(algo, sampleRate.toFloat(), bufferSize, detectionHandler));
val executorService = Executors.newCachedThreadPool()
executorService.execute(dispatcher)
executorService.awaitTermination(10, TimeUnit.MINUTES)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment