Skip to content

Commit f61c3e7

Browse files
committed
Merge branch 'great-refactor'
2 parents 98c443a + e8505ac commit f61c3e7

14 files changed

Lines changed: 165 additions & 142 deletions

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Generated by roxygen2: do not edit by hand
22

33
export(MIDI2freq)
4+
export(cents2frac)
45
export(cents2ratio)
56
export(et_scale_table)
67
export(freq2MIDI)

R/consonaR.R renamed to R/scales.R

Lines changed: 86 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,22 @@ ratio2cents <- function(ratio) {
6969
return(log2(ratio) * 1200)
7070
}
7171

72+
#' @title Cents to Fraction
73+
#' @name cents2frac
74+
#' @description Converts a vector of cents to a vector of the corresponding
75+
#' ratios, expressed as a character vector of vulgar fractions
76+
#' @importFrom fractional fractional
77+
#' @export cents2frac
78+
#' @param cents a numeric vector of cents values
79+
#' @returns a vector of the corresponding vulgar fractions
80+
#' @examples
81+
#' print(cents2frac(seq(0, 1200, by = 100)))
82+
#'
83+
84+
cents2frac <- function(cents) {
85+
return(as.character(fractional::fractional(2 ^ (cents / 1200))))
86+
}
87+
7288
#' @title Ratio to Factors
7389
#' @name ratio2factors
7490
#' @description Converts a vector of ratios to a vector of the corresponding
@@ -80,17 +96,17 @@ ratio2cents <- function(ratio) {
8096
#' @returns a list of vectors, with each vector the integer factors that
8197
#' determined the corresponding ratio
8298
#' @examples
83-
#' (super <- sclfile_scale_table(system.file(
99+
#' print(super <- sclfile_scale_table(system.file(
84100
#' "test_scl_files/carlos_super.scl",
85101
#' package = "consonaR"
86-
#' ))$scale_table$ratio)
87-
#' (super_factors <- ratio2factors(super))
102+
#' ))$scale_table)
103+
#' print(super_factors <- ratio2factors(cents2ratio(super$ratio_cents)))
88104
#'
89-
#' (harm <- sclfile_scale_table(system.file(
105+
#' print(harm <- sclfile_scale_table(system.file(
90106
#' "test_scl_files/carlos_harm.scl",
91107
#' package = "consonaR"
92-
#' ))$scale_table$ratio)
93-
#' (harm_factors <- ratio2factors(harm))
108+
#' ))$scale_table)
109+
#' print(harm_factors <- ratio2factors(cents2ratio(harm$ratio_cents)))
94110
#'
95111
#' # we know the factors that yield the 1-3-5-7 Hexany
96112
#' # can we recover them?
@@ -195,33 +211,26 @@ sine_dissonance <- function(freq1, freq2, loud1, loud2) {
195211
#' @importFrom data.table data.table
196212
#' @importFrom data.table setkey
197213
#' @importFrom data.table ":="
198-
#' @importFrom data.table ".I"
199214
#' @importFrom data.table "shift"
200-
#' @importFrom fractional fractional
201215
#' @importFrom utils globalVariables
202216
#' @export et_scale_table
203217
#' @param period The period - default is 2, for an octave
204218
#' @param divisions Number of degrees in the scale - default is 12
205-
#' @param tonic_note_number MIDI note number of the tonic for the scale -
206-
#' - default is middle C = 60
207-
#' @returns a `data.table` with seven columns:
219+
#' @param root_freq root frequency of the scale - default is middle C:
220+
#' 440 / (2 ^ (9 / 12))
221+
#' @returns a `data.table` with six columns:
208222
#' \itemize{
209-
#' \item `ratio`: the ratio that defines the note, as a number between 1 and
210-
#' `period`
223+
#' \item `degree`: scale degree from zero to (number of notes) - 1
224+
#' \item `ratio_cents`: the ratio in cents (hundredths of a semitone)
211225
#' \item `ratio_frac`: the ratio as a vulgar fraction (character). The ratios
212226
#' for this type of scale are usually irrational, so this is an approximation,
213227
#' computed by `fractional::fractional`.
214-
#' \item `ratio_cents`: the ratio in cents (hundredths of a semitone)
215-
#' \item `frequency`: frequency of the note given the `tonic_note_number`
228+
#' \item `frequency`: frequency of the note given the `root_freq`
216229
#' parameter
217-
#' \item `bent_midi`: the MIDI note number as an integer plus a fraction. For
218-
#' example, middle C is MIDI note number 60 and middle C sharp is 61. The
219-
#' quarter-tone half-way between C and C sharp would have a `bent_midi` value
220-
#' of 60.5. The name `bent_midi` comes from the fact that a MIDI sequencer
221-
#' can convert the value to a regular integer MIDI note number message and
222-
#' a pitch bend message.
223230
#' \item `interval_cents`: interval between this note and the previous note
224-
#' \item `degree`: scale degree from zero to (number of notes) - 1
231+
#' in cents
232+
#' \item `interval_frac`: interval between this note and the previous note
233+
#' as a vulgar fraction
225234
#' }
226235
#' @examples
227236
#'
@@ -242,26 +251,24 @@ sine_dissonance <- function(freq1, freq2, loud1, loud2) {
242251
et_scale_table <- function(
243252
period = 2.0,
244253
divisions = 12,
245-
tonic_note_number = 60
254+
root_freq = 440 / (2 ^ (9 / 12))
246255
) {
247256
degree <- seq(0, divisions)
248257
ratio_cents <- degree * ratio2cents(period) / divisions
249-
ratio <- cents2ratio(ratio_cents)
250-
ratio_frac <- as.character(fractional::fractional(ratio))
251-
tonic_frequency <- 440 * 2 ^ ((tonic_note_number - 69) / 12)
252-
frequency <- ratio * tonic_frequency
253-
bent_midi <- 0.01 * ratio_cents + tonic_note_number
258+
ratio_frac <- cents2frac(ratio_cents)
259+
frequency <- cents2ratio(ratio_cents) * root_freq
254260
scale_table <- data.table::data.table(
255-
ratio,
256-
ratio_frac,
261+
degree,
257262
ratio_cents,
258-
frequency,
259-
bent_midi
263+
ratio_frac,
264+
frequency
260265
)
261-
data.table::setkey(scale_table, ratio)
266+
data.table::setkey(scale_table, ratio_cents)
262267
scale_table <- scale_table[, `:=`(
263-
interval_cents = ratio_cents - data.table::shift(ratio_cents),
264-
degree = .I - 1
268+
interval_cents = ratio_cents - data.table::shift(ratio_cents)
269+
)]
270+
scale_table <- scale_table[, `:=`(
271+
interval_frac = cents2frac(interval_cents)
265272
)]
266273
scale_table$degree[divisions + 1] <- 0
267274
return(scale_table)
@@ -273,55 +280,52 @@ et_scale_table <- function(
273280
#' @importFrom data.table data.table
274281
#' @importFrom data.table setkey
275282
#' @importFrom data.table ":="
276-
#' @importFrom data.table ".I"
277283
#' @importFrom data.table "shift"
278-
#' @importFrom fractional fractional
279284
#' @importFrom utils globalVariables
280285
#' @export sclfile_scale_table
281286
#' @param sclfile_path The path to a valid Scala `.scl` file
282-
#' @param tonic_note_number MIDI note number of the tonic for the scale -
283-
#' - default is middle C = 60
284-
#' @returns a `data.table` with seven columns:
287+
#' @param root_freq root frequency of the scale - default is middle C:
288+
#' 440 / (2 ^ (9 / 12))
289+
#' @returns a list with two or three items:
285290
#' \itemize{
286-
#' \item `ratio`: the ratio that defines the note, as a number between 1 and
287-
#' `period`
288-
#' \item `ratio_frac`: the ratio as a vulgar fraction (character). The ratios
289-
#' for this type of scale are usually irrational, so this is an approximation,
290-
#' computed by `fractional::fractional`.
291-
#' \item `ratio_cents`: the ratio in cents (hundredths of a semitone)
292-
#' \item `frequency`: frequency of the note given the `tonic_note_number`
293-
#' parameter
294-
#' \item `bent_midi`: the MIDI note number as an integer plus a fraction. For
295-
#' example, middle C is MIDI note number 60 and middle C sharp is 61. The
296-
#' quarter-tone half-way between C and C sharp would have a `bent_midi` value
297-
#' of 60.5. The name `bent_midi` comes from the fact that a MIDI sequencer
298-
#' can convert the value to a regular integer MIDI note number message and
299-
#' a pitch bend message.
300-
#' \item `interval_cents`: interval between this note and the previous note
301-
#' \item `degree`: scale degree from zero to (number of notes) - 1
291+
#' \item `status` (character): "Oll Korrect" if the results are valid,
292+
#' otherwise an error message
293+
#' \item `file_contents` (character vector): the contents read from the file
294+
#' \item `scale_table` (data.table): if everything worked, the scale table
302295
#' }
303296
#' @examples
304297
#'
305298
#' # a file with ratios specified in cents
306-
#' cents <- sclfile_scale_table(system.file(
299+
#' alpha <- sclfile_scale_table(system.file(
307300
#' "test_scl_files/carlos_alpha.scl",
308301
#' package = "consonaR"
309302
#' ))
310-
#' if (cents$status == "Oll Korrect") {
311-
#' print(cents$scale_table)
303+
#' if (alpha$status == "Oll Korrect") {
304+
#' print(alpha$scale_table)
312305
#' } else {
313-
#' print(cents$status)
306+
#' print(alpha$status)
314307
#' }
315308
#'
316309
#' # a file with ratios specified as vulgar fractions
317-
#' ratios <- sclfile_scale_table(system.file(
310+
#' harm <- sclfile_scale_table(system.file(
318311
#' "test_scl_files/carlos_harm.scl",
319312
#' package = "consonaR"
320313
#' ))
321-
#' if (ratios$status == "Oll Korrect") {
322-
#' print(ratios$scale_table)
314+
#' if (harm$status == "Oll Korrect") {
315+
#' print(harm$scale_table)
323316
#' } else {
324-
#' print(ratios$status)
317+
#' print(harm$status)
318+
#' }
319+
#'
320+
#' # another file with ratios specified as vulgar fractions
321+
#' super <- sclfile_scale_table(system.file(
322+
#' "test_scl_files/carlos_super.scl",
323+
#' package = "consonaR"
324+
#' ))
325+
#' if (super$status == "Oll Korrect") {
326+
#' print(super$scale_table)
327+
#' } else {
328+
#' print(super$status)
325329
#' }
326330
#'
327331
#' # a file that doesn't exist
@@ -336,7 +340,10 @@ et_scale_table <- function(
336340
#' }
337341
#'
338342

339-
sclfile_scale_table <- function(sclfile_path, tonic_note_number = 60) {
343+
sclfile_scale_table <- function(
344+
sclfile_path,
345+
root_freq = 440 / (2 ^ (9 / 12))
346+
) {
340347

341348
# bail if the file can't be opened for reading text
342349
previous_warn_option <- as.integer(options(warn = 2))
@@ -406,21 +413,20 @@ sclfile_scale_table <- function(sclfile_path, tonic_note_number = 60) {
406413
}
407414

408415
# finish up
409-
ratio_frac <- as.character(fractional::fractional(ratio))
410-
tonic_frequency <- 440 * 2 ^ ((tonic_note_number - 69) / 12)
411-
frequency <- ratio * tonic_frequency
412-
bent_midi <- 0.01 * ratio_cents + tonic_note_number
416+
ratio_frac <- cents2frac(ratio_cents)
417+
frequency <- ratio * root_freq
413418
scale_table <- data.table::data.table(
414-
ratio,
415-
ratio_frac,
419+
degree,
416420
ratio_cents,
417-
frequency,
418-
bent_midi
421+
ratio_frac,
422+
frequency
419423
)
420-
data.table::setkey(scale_table, ratio)
424+
data.table::setkey(scale_table, ratio_cents)
421425
scale_table <- scale_table[, `:=`(
422-
interval_cents = ratio_cents - data.table::shift(ratio_cents),
423-
degree = .I - 1
426+
interval_cents = ratio_cents - data.table::shift(ratio_cents)
427+
)]
428+
scale_table <- scale_table[, `:=`(
429+
interval_frac = cents2frac(interval_cents)
424430
)]
425431
scale_table$degree[degrees + 1] <- 0
426432

@@ -510,3 +516,7 @@ prodset_scale_table <- function(
510516
scale_table$degree[degrees + 1] <- 0
511517
return(scale_table)
512518
}
519+
520+
utils::globalVariables(c(
521+
"interval_cents"
522+
))

consonaR.Rproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
Version: 1.0
22
ProjectId: fefaf73e-7bca-4c60-a3bd-d7eb1de6e744
33

4-
RestoreWorkspace: No
5-
SaveWorkspace: No
6-
AlwaysSaveHistory: No
4+
RestoreWorkspace: Default
5+
SaveWorkspace: Default
6+
AlwaysSaveHistory: Default
77

88
EnableCodeIndexing: Yes
99
UseSpacesForTab: Yes

man/MIDI2freq.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/cents2frac.Rd

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/cents2ratio.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/et_scale_table.Rd

Lines changed: 11 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/freq2MIDI.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/period_reduce.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/prodset_scale_table.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)