Waveform/dutyCycle
This commit is contained in:
@@ -49,6 +49,13 @@ class PlayingNote(
|
|||||||
var actualVolume = 0f
|
var actualVolume = 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class Waveform {
|
||||||
|
SINE,
|
||||||
|
SQUARE,
|
||||||
|
TRIANGLE,
|
||||||
|
SAWTOOTH
|
||||||
|
}
|
||||||
|
|
||||||
@ExperimentalJsExport
|
@ExperimentalJsExport
|
||||||
@JsExport
|
@JsExport
|
||||||
class VstChipProcessor : AudioWorkletProcessor() {
|
class VstChipProcessor : AudioWorkletProcessor() {
|
||||||
@@ -57,6 +64,8 @@ class VstChipProcessor : AudioWorkletProcessor() {
|
|||||||
0
|
0
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
var waveform = Waveform.SINE.ordinal
|
||||||
|
var dutyCycle = 0.5
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.port.onmessage = ::handleMessage
|
this.port.onmessage = ::handleMessage
|
||||||
@@ -117,6 +126,27 @@ class VstChipProcessor : AudioWorkletProcessor() {
|
|||||||
noteOff(note)
|
noteOff(note)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
0xc9 -> {
|
||||||
|
if (bytes.length >= 1) {
|
||||||
|
val waveform = bytes[1]
|
||||||
|
|
||||||
|
if (waveform < 4) {
|
||||||
|
this.waveform = waveform
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
0xb0 -> {
|
||||||
|
if (bytes.length == 3) {
|
||||||
|
val knob = bytes[1]
|
||||||
|
val value = bytes[2]
|
||||||
|
|
||||||
|
when(knob) {
|
||||||
|
0x4a -> {
|
||||||
|
dutyCycle = value / 127.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,20 +205,39 @@ class VstChipProcessor : AudioWorkletProcessor() {
|
|||||||
note.releaseSamples--
|
note.releaseSamples--
|
||||||
targetVolume *= (note.releaseSamples / 10000f)
|
targetVolume *= (note.releaseSamples / 10000f)
|
||||||
}
|
}
|
||||||
note.actualVolume += (targetVolume - note.actualVolume) * 0.005f
|
note.actualVolume += (targetVolume - note.actualVolume) * 0.001f
|
||||||
|
|
||||||
if (note.state == NoteState.RELEASED && note.actualVolume <= 0) {
|
if (note.state == NoteState.RELEASED && note.actualVolume <= 0) {
|
||||||
note.state = NoteState.OFF
|
note.state = NoteState.OFF
|
||||||
}
|
}
|
||||||
|
|
||||||
left[i] = left[i] + sin(note.cycleOffset * PI2).toFloat() * note.actualVolume * 0.3f
|
val cycleOffset = note.cycleOffset
|
||||||
right[i] = right[i] + sin(note.cycleOffset * PI2).toFloat() * note.actualVolume * 0.3f
|
|
||||||
|
|
||||||
//left[i] = left[i] + if (note.cycleOffset < 0.5) { 0.3f } else { -0.3f } * note.actualVolume //sin(note.cycleOffset * PI2).toFloat() * note.actualVolume * 0.3f
|
val waveValue: Float = when (waveform) {
|
||||||
//right[i] = right[i] + if (note.cycleOffset < 0.5) { 0.3f } else { -0.3f } * note.actualVolume //sin(note.cycleOffset * PI2).toFloat() * note.actualVolume * 0.3f
|
0 -> {
|
||||||
|
sin(cycleOffset * PI2).toFloat()
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
if (cycleOffset < dutyCycle) { 1f } else { -1f }
|
||||||
|
}
|
||||||
|
2 -> when {
|
||||||
|
cycleOffset < 0.25 -> 4 * cycleOffset
|
||||||
|
cycleOffset < 0.75 -> 2 - 4 * cycleOffset
|
||||||
|
else -> 4 * cycleOffset - 4
|
||||||
|
}.toFloat()
|
||||||
|
3 -> {
|
||||||
|
((cycleOffset * 2f) - 1f).toFloat()
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
if (cycleOffset < 0.5) { 1f } else { -1f }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
left[i] = left[i] + waveValue * note.actualVolume * 0.3f
|
||||||
|
right[i] = right[i] + waveValue * note.actualVolume * 0.3f
|
||||||
|
|
||||||
note.cycleOffset += sampleDelta
|
note.cycleOffset += sampleDelta
|
||||||
if (note.cycleOffset > 1f) {
|
if (cycleOffset > 1f) {
|
||||||
note.cycleOffset -= 1f
|
note.cycleOffset -= 1f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,16 +15,16 @@ enum class Note(
|
|||||||
val sharp: String,
|
val sharp: String,
|
||||||
val flat: String
|
val flat: String
|
||||||
) {
|
) {
|
||||||
NONE("---", "---"),
|
NO01("C--","C--"),
|
||||||
No02("C--","C--"),
|
NO02("C#-","Db-"),
|
||||||
NO03("C#-","Db-"),
|
NO03("D--","D--"),
|
||||||
NO04("D--","D--"),
|
NO04("D#-","Eb-"),
|
||||||
NO05("D#-","Eb-"),
|
NO05("E--","E--"),
|
||||||
NO06("E--","E--"),
|
NO06("F--","F--"),
|
||||||
NO07("F--","F--"),
|
NO07("F#-","Gb-"),
|
||||||
NO08("F#-","Gb-"),
|
NO08("G--","G--"),
|
||||||
NO09("G--","G--"),
|
NO09("G#-","Ab-"),
|
||||||
NO10("G#-","Ab-"),
|
NO10("A--","A--"),
|
||||||
NO11("A#-","Bb-"),
|
NO11("A#-","Bb-"),
|
||||||
NO12("B--","B--"),
|
NO12("B--","B--"),
|
||||||
C0("C-0","C-0"),
|
C0("C-0","C-0"),
|
||||||
@@ -148,12 +148,13 @@ enum class Note(
|
|||||||
//A9("A-9","A-9"),
|
//A9("A-9","A-9"),
|
||||||
//A9s("A#9","Bb9"),
|
//A9s("A#9","Bb9"),
|
||||||
//B9("B-9","B-9"),
|
//B9("B-9","B-9"),
|
||||||
|
NONE("---", "---"),
|
||||||
UP("^^^","^^^"),
|
UP("^^^","^^^"),
|
||||||
END("XXX","XXX"),
|
END("XXX","XXX"),
|
||||||
;
|
;
|
||||||
|
|
||||||
// 69 = A4.ordinal
|
// 69 = A4.ordinal
|
||||||
val freq: Double = round(440.0 * 2.0.pow((ordinal - 69)/12.0) * 100.0) / 100.0
|
val freq: Double = round(440.0 * 2.0.pow((ordinal - 69)/12.0) * 10000.0) / 10000.0
|
||||||
val cycleLength: Double = 1.0 / freq
|
val cycleLength: Double = 1.0 / freq
|
||||||
var sampleDelta: Double = 0.0
|
var sampleDelta: Double = 0.0
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package nl.astraeus.vst.chip.midi
|
|||||||
import kotlinx.browser.window
|
import kotlinx.browser.window
|
||||||
import nl.astraeus.vst.chip.audio.VstChipWorklet
|
import nl.astraeus.vst.chip.audio.VstChipWorklet
|
||||||
import nl.astraeus.vst.chip.view.MainView
|
import nl.astraeus.vst.chip.view.MainView
|
||||||
|
import org.khronos.webgl.Uint8Array
|
||||||
|
import org.khronos.webgl.get
|
||||||
|
|
||||||
external class MIDIInput {
|
external class MIDIInput {
|
||||||
val connection: String
|
val connection: String
|
||||||
@@ -77,7 +79,13 @@ object Midi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
currentInput?.onmidimessage = { message ->
|
currentInput?.onmidimessage = { message ->
|
||||||
console.log("Midi message:", message)
|
val data = message.data as Uint8Array
|
||||||
|
val hex = StringBuilder()
|
||||||
|
for (index in 0 until data.length) {
|
||||||
|
hex.append(data[index].toString(16))
|
||||||
|
hex.append(" ")
|
||||||
|
}
|
||||||
|
console.log("Midi message:", hex)
|
||||||
VstChipWorklet.postMessage(
|
VstChipWorklet.postMessage(
|
||||||
message.data
|
message.data
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user