Changes
2 changed files (+48/-31)
-
-
@@ -1,7 +1,7 @@import musiclib, std/math import musiclib, std/[math, sugar] # Number of times to sample each second let bitrate = 44100 const bitrate = 44100 func osc_piano*(f, t: float): float = ## Returns the intensity of a tone of frequency f sampled at time t
-
@@ -20,14 +20,27 @@ Y += Y * Y * YY *= 1 + 16 * t * math.exp(-6 * t) Y func osc_pulse*(f,t:float):float = let width = (1.0 / f) / 2 let phase: float = t mod (width * 2) if phase < width: 1.0 else: -1.0 func freq*(octave, step: float): float = ## Returns the frequency of a note 55 * pow(2, (octave + step / 12 - 1)) func p*(len, octave, step, vol: float = 1): Note = var osc: OscFn = (f, t: float) => 0.0 proc p*(len, octave, step, vol: float = 1): Note = ## Note helper constructor let osc: OscFn = osc_piano (len, freq(octave, step), vol, osc) #------- song region ------- const GAIN_NORMAL = 0.24 osc = (f, t: float) => osc_piano(f, t) * GAIN_NORMAL let intro = [ p(1,3,3),
-
@@ -50,6 +63,8 @@ p(1,3,0),p(1,3,3), p(8,3,7), ] # osc = osc_pulse let melody = [ p(1,3,3),
-
@@ -119,17 +134,6 @@ p(1,4,8),p(2,4,10), ] let bass = [ p(1,1,3), p(1,1,10), p(1,1,1), p(1,1,8), p(1,1,3), p(1,2,3), p(1,1,1), p(1,1,10), ] let melody2 = [ p(1,0,0), p(1,5,10),
-
@@ -273,6 +277,19 @@ p(2,3,3),p(16,3,7,2), ] osc = (f, t: float) => osc_piano(f, t) * GAIN_NORMAL * 1.5 let bass = [ p(1,1,3), p(1,1,10), p(1,1,1), p(1,1,8), p(1,1,3), p(1,2,3), p(1,1,1), p(1,1,10), ] from std/algorithm import sort # Process all lists of notes
-
@@ -280,16 +297,16 @@ var music: seq[ProcessedNote] = @[]music.process(intro, 0, 4) music.process(melody, 8, 4) music.process(melody, 24, 4) music.process(bass, 24, gain=1.5) music.process(bass, 32, gain=1.5) music.process(bass, 24) music.process(bass, 32) music.process(melody, 40, 4) music.process(melody2, 40, 4) music.process(bass, 40, gain=1.5) music.process(bass, 48, gain=1.5) music.process(bass, 40) music.process(bass, 48) music.process(melody, 56, 4) music.process(melody3, 56, 4) music.process(bass, 56, gain=1.5) music.process(bass, 64, gain=1.5) music.process(bass, 56) music.process(bass, 64) music.process(outro, 72, 4) music.sortByStart()
-
-
-
@@ -16,12 +16,9 @@ freq: floatvol: float osc: OscFn ## give some seconds for the note to fade out const HACK_DROPOFF_DELAY = 2.0 const HACK_LONGEST_NOTE = 16.0 func process*(music: var seq[ProcessedNote], notes: openArray[Note]; start_init: float, speed: float=1, gain:float = 1) = func process*(music: var seq[ProcessedNote], notes: openArray[Note]; start_init: float, speed: float=1) = ## Adds a list of notes to the music list ## ## `notes` sequence of notes with no rests in between
-
@@ -32,7 +29,7 @@ assert note.len >= 0.0assert note.len <= HACK_LONGEST_NOTE, &"note too long: {note.len}" start = t let stop = t + note.len / speed music &= (start, stop, note.freq, note.vol * gain, note.osc) music &= (start, stop, note.freq, note.vol, note.osc) t = stop func sortByStart*(music: var seq[ProcessedNote]) =
-
@@ -45,7 +42,7 @@ ## assumes `music` is sorted by `.start`music.lowerBound(x, (m, key) => cmp(m.start, key)) const GAIN_BIAS: float = pow(2.0, 28.0) const GAIN_BIAS: float = pow(2.0, 31.0) proc at*(music: openArray[ProcessedNote], t: float): int32 = ## Returns the total intensity of music sampled at time t
-
@@ -59,10 +56,13 @@while i >= 0: let m = music[i] assert m.start <= t if m.stop + HACK_DROPOFF_DELAY >= t: if m.start + HACK_LONGEST_NOTE < t: break else: ret += m.vol * m.osc(m.freq, t - m.start) if m.start + HACK_LONGEST_NOTE + HACK_DROPOFF_DELAY < t: break i -= 1 int32(ret * GAIN_BIAS) ret *= GAIN_BIAS # clip sample clamp(ret, int32.low.float..int32.high.float).int32
-