<commit_before>import nico
import nico/gui
import strformat
import strutils

var data: SynthData
var editIndex = 0
var editMode = 0

var outputStr: string
var dirty = true

const minNote = 32
const maxNote = 32 + 64

const initData = synthDataFromString("0037A235C232D22FC22C82296227422422")

data = initData

proc gameInit() =
  masterVol(255)
  sfxVol(255)
  musicVol(255)

  for v in data.steps.mitems:
    if v.shape == synSame:
      v.shape = synSqr

proc play() =
  synth(0, outputStr)

var xval,yval: int

proc gameGui() =
  G.beginArea(4,4,screenWidth-8,20,gLeftToRight)
  var speed = data.speed.int
  if G.slider("speed", speed, 0, 15):
    data.speed = speed.uint8
  var loop = data.loop.int
  if G.slider("loop", loop, 0, 15):
    data.loop = loop.uint8
  if G.button("-"):
    for v in data.steps.mitems:
      v.note -= 12
  if G.button("+"):
    for v in data.steps.mitems:
      v.note += 12
  G.endArea()

  let playIndex = synthIndex(0)

  let (mx,my) = mouse()

  # pitch
  let pitchHeight = 64
  if G.xyarea(xval,yval,4, 24, screenWidth - 8, pitchHeight, proc(G: Gui, x,y,w,h: int, style: GuiStyle, ta,va: TextAlign) =
    for i in 0..<data.steps.len:
      let x0 = x + i * 4
      let x1 = x + i * 4 + 2
      let bottom = y + h - 1

      let yrange = h

      setColor(if editIndex == i: 10 elif data.steps[i].volume == 0: 1 else: 6)
      let noteRel = clamp01(invLerp(minNote, maxNote, data.steps[i].note.float32))
      rectfill(x0, bottom, x1, bottom - noteRel * yrange.float32)
      if playIndex == i:
        setColor(7)
        rect(x0, bottom - noteRel * yrange.float32, x1, bottom)

      if editIndex == i and G.downElement == G.element:
        setColor(10)
        printc(noteToNoteStr(data.steps[editIndex].note.int), x0, bottom - noteRel * yrange.float32 - 10)

    setColor(7)
    printr("pitch", x + w - 1, y)
    setColor(10)
    printr(noteToNoteStr(data.steps[editIndex].note.int), x + w - 1, y + 10)


  ):
    let ix = xval div 4
    if ix >= 0 and ix < data.steps.len:
      editMode = 0
      editIndex = ix
      data.steps[ix].note = clamp(minNote + pitchHeight - yval, minNote, maxNote).uint8

  # volume
  let volumeHeight = 32
  if G.xyarea(xval,yval,4, 24 + pitchHeight + 4, screenWidth - 8, volumeHeight, proc(G: Gui, x,y,w,h: int, style: GuiStyle, ta,va: TextAlign) =
    for i in 0..<data.steps.len:
      let x0 = x + i * 4
      let x1 = x + i * 4 + 2
      let bottom = y + h - 1<commit_msg>nicosynth clamp to scale when holding shift<commit_after>import nico
import nico/gui
import strformat
import strutils

var data: SynthData
var editIndex = 0
var editMode = 0

var outputStr: string
var dirty = true

const minNote = 32
const maxNote = 32 + 64

const initData = synthDataFromString("0037A235C232D22FC22C82296227422422")

data = initData

proc gameInit() =
  masterVol(255)
  sfxVol(255)
  musicVol(255)

  for v in data.steps.mitems:
    if v.shape == synSame:
      v.shape = synSqr

proc play() =
  synth(0, outputStr)

var xval,yval: int

proc gameGui() =
  G.beginArea(4,4,screenWidth-8,20,gLeftToRight)
  var speed = data.speed.int
  if G.slider("speed", speed, 0, 15):
    data.speed = speed.uint8
  var loop = data.loop.int
  if G.slider("loop", loop, 0, 15):
    data.loop = loop.uint8
  if G.button("-"):
    for v in data.steps.mitems:
      v.note -= 12
  if G.button("+"):
    for v in data.steps.mitems:
      v.note += 12
  G.endArea()

  let playIndex = synthIndex(0)

  let (mx,my) = mouse()

  # pitch
  let pitchHeight = 64
  if G.xyarea(xval,yval,4, 24, screenWidth - 8, pitchHeight, proc(G: Gui, x,y,w,h: int, style: GuiStyle, ta,va: TextAlign) =
    for i in 0..<data.steps.len:
      let x0 = x + i * 4
      let x1 = x + i * 4 + 2
      let bottom = y + h - 1

      let yrange = h

      setColor(if editIndex == i: 10 elif data.steps[i].volume == 0: 1 else: 6)
      let noteRel = clamp01(invLerp(minNote, maxNote, data.steps[i].note.float32))
      rectfill(x0, bottom, x1, bottom - noteRel * yrange.float32)
      if playIndex == i:
        setColor(7)
        rect(x0, bottom - noteRel * yrange.float32, x1, bottom)

      if editIndex == i and G.downElement == G.element:
        setColor(10)
        printc(noteToNoteStr(data.steps[editIndex].note.int), x0, bottom - noteRel * yrange.float32 - 10)

    setColor(7)
    printr("pitch", x + w - 1, y)
    setColor(10)
    printr(noteToNoteStr(data.steps[editIndex].note.int), x + w - 1, y + 10)


  ):
    let ix = xval div 4
    if ix >= 0 and ix < data.steps.len:
      editMode = 0
      editIndex = ix
      var note = clamp(minNote + pitchHeight - yval, minNote, maxNote)
      if key(K_LSHIFT):
        # lock to C maj, 0 2 4 7 9 11
        let oct = note div 12
        let noteInOct = note mod 12
        let adjusted = case noteInOct:
          of 0,1: 0
          of 2,3: 2
          of 4,5: 4
          of 6,7: 7
          of 8,9: 9
          of 10,11: 11
          else: 0
        note = oct * 12 + adjusted
      data.steps[ix].note = note.uint8

  # volume
  let volumeHeight = 32
  if G.xyarea(xval,yval,4, 24 + pitchHeight + 4, screenWidth - 8, volumeHeight, proc(G: Gui, x,y,w,h: int, style: GuiStyle, ta,va: TextAlign) =
    for i in 0..<data.steps.len:
      let x0 = x + i * 4
      let x1 = x + i * 4 + 2
      let bottom = y + h - 1
{'fraction_non_alphanumeric': 0.12837455163299982, 'fraction_numerical': 0.05455918444402492, 'mean_word_length': 2.485526315789474, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1506629', 'n_tokens_mistral': 2231, 'n_tokens_neox': 1990, 'n_words': 580}