<commit_before>package edu.depauw.scales.music

import scala.scalajs.js
import js.annotation.JSExport
import org.scalajs.dom
import rx._

trait Scales {}

trait ScalesNote extends Scales {
	val ctx = js.Dynamic.newInstance(js.Dynamic.global.AudioContext)()

	def play(t: Double): Unit

	def duration: Double

	def count: Int

	def before(that: ScalesNote): SoundComposite = SoundComposite(this, that) //redefining these prob unnecessary

	def after(that: ScalesNote): SoundComposite = SoundComposite(that, this)

	def par(that: ScalesNote): ParallelComposite = ParallelComposite(this, that)
}

case class Note(freq: Double, dur: Double = 1, vol: Double = 1) extends ScalesNote {

	def count = 1

	def duration = dur

	def play(time: Double = 0): Unit = {
		val o = ctx.createOscillator()
		val g = ctx.createGain()

		o.frequency.value = freq
		g.gain.value = vol

		o.connect(g)
		g.connect(ctx.destination)

		val startTime = ctx.currentTime.toString().toDouble + time
		o.start(startTime)
		o.stop(startTime + dur)
	}
}

case class SoundComposite(first: ScalesNote, second: ScalesNote) extends ScalesNote {

	def count = first.count + second.count

	def duration = first.duration + second.duration

	def play(time: Double = 0) {
		val startTime = ctx.currentTime.toString().toDouble + time
		first.play(startTime)
		second.play(startTime + first.duration)
	}

}

case class ParallelComposite(first: ScalesNote, second: ScalesNote) extends ScalesNote {

	def count = first.count + second.count

	def duration = math.max(first.duration, second.duration)

	def play(time: Double = 0) {
		val startTime = ctx.currentTime.toString().toDouble + time
		first.play(startTime)
		second.play(startTime)
	}<commit_msg>added methods to move up/down octaves<commit_after>package edu.depauw.scales.music

import scala.scalajs.js
import js.annotation.JSExport
import org.scalajs.dom
import rx._

trait Scales {}

trait ScalesNote extends Scales {
	val ctx = js.Dynamic.newInstance(js.Dynamic.global.AudioContext)()

	def play(t: Double): Unit

	def duration: Double

	def count: Int

	def before(that: ScalesNote): SoundComposite = SoundComposite(this, that)

	def after(that: ScalesNote): SoundComposite = SoundComposite(that, this)

	def par(that: ScalesNote): ParallelComposite = ParallelComposite(this, that)
}

case class Note(freq: Double, dur: Double = 1, vol: Double = 1) extends ScalesNote {

	def count = 1

	def duration = dur

	def play(time: Double = 0): Unit = {
		val o = ctx.createOscillator()
		val g = ctx.createGain()

		o.frequency.value = freq
		g.gain.value = vol

		o.connect(g)
		g.connect(ctx.destination)

		val startTime = ctx.currentTime.toString().toDouble + time
		o.start(startTime)
		o.stop(startTime + dur)
	}

	/*
	** returns a new note moved up @params octaves
	*/
	def >(octaves: Int = 1): Note = {
		val mult = math.pow(2, octaves)
		Note(freq * mult, dur, vol)
	}

	def <(octaves: Int = 1): Note = {
		val mult = math.pow(2, octaves)
		Note(freq / mult, dur, vol)
	}

	/*
	** returns a new note moved up 4 octaves
	*/
	def >>>> : Note = {
		Note(freq * 16, dur, vol)
	}

	def <<<< : Note = {
		Note(freq / 16, dur, vol)
	}

}

case class SoundComposite(first: ScalesNote, second: ScalesNote) extends ScalesNote {

	def count = first.count + second.count

	def duration = first.duration + second.duration

	def play(time: Double = 0) {
		val startTime = ctx.currentTime.toString().toDouble + time
		first.play(startTime)
		second.play(startTime + first.duration)
	}

}

case class ParallelComposite(first: ScalesNote, second: ScalesNote) extends ScalesNote {

	def count = first.count + second.count

	def duration = math.max(first.duration, second.duration)

	def play(time: Double = 0) {
		val startTime = ctx.currentTime.toString().toDouble + time
		first.play(startTime)
		second.play(startTime)
	}
{'fraction_non_alphanumeric': 0.11758557616932323, 'fraction_numerical': 0.005487326887901751, 'mean_word_length': 4.076923076923077, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, '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': '408825', 'n_tokens_mistral': 1391, 'n_tokens_neox': 1292, 'n_words': 347}