library(midiblender)
library(dplyr)
library(pyramidi)
all_tracks <- data.frame()
# note parameters
bars <- 12 * 4 * 4
possible_time_steps <- 16
note_duration <- 24
track_params <- list(track_1_bass =
list(possible_notes = rep(60:72, #1 2 3 4 5 6 7 8
times = c(6, 0, 3, 0, 0, 3, 0, 3, 0, 0, 3, 0, 6)),
key_vector = rep(rep(c(0, 0, 0, 0, 5, 5, 0, 0, 7, 5, 0, 7),
each = possible_time_steps),
times = 4 * 4)
),
track_2_mid =
list(possible_notes = rep(60:72, #1 2 3 4 5 6 7 8
times = c(6, 0, 2, 0, 0, 2, 0, 3, 0, 0, 3, 0, 6)),
key_vector = rep(rep(c(0, 0, 0, 0, 5, 5, 0, 0, 7, 5, 0, 7),
each = possible_time_steps),
times = 4 * 4)
),
track_3_mid =
list(possible_notes = rep(60:72, #1 2 3 4 5 6 7 8
times = c(1, 0, 0, 2, 0, 3, 2, 3, 0, 0, 2, 0, 1)),
key_vector = rep(rep(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
each = possible_time_steps),
times = 4 * 4)
)
)
# loop for each track
for(t in 1:3) {
compose_notes <- tibble::tibble(
note_id = integer(),
note = integer(),
beat_on = integer(),
note_on = integer(),
note_off = integer()
) %>%
# use euclidean rhythm
rowwise() %>%
add_row(
beat_on = c(replicate(
bars,
bresenham_euclidean(sample(c(1, 2, 2, 3, 4, 5, 5, 6, 8, 11, 13), 1),
possible_time_steps,
start = 1)
)),
note = sample(track_params[[t]]$possible_notes,
size = possible_time_steps * bars,
replace = TRUE) + track_params[[t]]$key_vector
) %>%
ungroup() %>%
# handle note times
mutate(
note_id = 1:n(),
note_on = (1:n() - 1) * note_duration,
note_off = note_on + note_duration
) %>%
filter(beat_on == 1) %>%
#pivot to long
tidyr::pivot_longer(c("note_on", "note_off"),
names_to = "type",
values_to = "time") %>%
mutate(time = time - lag(time, default = 0))
######################
# End composition
#######################
## add composition to a new midi df
new_midi_df <- create_empty_midi_df() %>% # initialize
add_meta_track_name(name = "My track") %>%
add_meta_tempo(tempo = 500000) %>%
add_meta_time_sig(
numerator = 4,
denominator = 4,
clocks_per_click = 36,
notated_32nd_notes_per_beat = 8
) %>%
add_program_change(program = 0,
channel = 0) %>%
add_control_change(control = 0, value = 0) %>%
# Composition added here
add_row(
i_track = rep(0, dim(compose_notes)[1]),
meta = rep(FALSE, dim(compose_notes)[1]),
note = compose_notes$note,
type = compose_notes$type,
time = compose_notes$time,
velocity = 64
) %>%
add_meta_end_of_track() %>%
mutate(i_track = t) # set current track number
all_tracks <- rbind(all_tracks,new_midi_df)
}
#write midi
#Initialize new pyramidi object
new_pyramidi_object <- pyramidi::MidiFramer$new()
# update ticks per beat
new_pyramidi_object$ticks_per_beat <- 96L
# update object with new midi df
new_pyramidi_object$mf$midi_frame_unnested$update_unnested_mf(all_tracks)
# write to midi file
new_pyramidi_object$mf$write_file("bluesy_C.mid")