Harmonicity Metrics
Harmonicity Metrics#
- compute_consonance(ratio, limit=1000)[source]#
Compute metric of consonance from a single ratio of frequencies in the form (a+b)/(a*b).
- Parameters
ratio (float) – The ratio of frequencies.
limit (int, optional (default=1000)) – The maximum value of the denominator of the fraction representing the ratio.
- Returns
cons (float) – The consonance value.
Examples
>>> compute_consonance(3/2, limit=1000) 0.8333333333333334 >>> compute_consonance(16/9, limit=1000) 0.1736111111111111
- euler(*numbers)[source]#
Euler’s “gradus suavitatis” (degree of sweetness) function Return the “degree of sweetness” of a musical interval or chord expressed as a ratio of frequencies a:b:c, according to Euler’s formula Greater values indicate more dissonance.
- Parameters
*numbers (List or Array of int) – Frequencies
- Returns
euler (int) – Euler Gradus Suavitatis.
Examples
>>> peaks = [3, 7, 13, 19] >>> euler(*peaks) 39 >>> peaks = [3, 9, 11, 27] >>> euler(*peaks) 17
- tenneyHeight(peaks, avg=True)[source]#
Tenney Height is a measure of inharmonicity calculated on two frequencies (a/b) reduced in their simplest form. It can also be called the log product complexity of a given interval. This function computes the Tenney Height pairwise across a list of peaks. Higher values represents higher dissonance.
- Parameters
peaks (List (float)) – frequencies
avg (bool (default=True)) – When set to True, all tenney heights are averaged.
- Returns
tenney (float) – Tenney Height
Examples
>>> peaks = [3, 7, 13, 19] >>> tenneyHeight(peaks) 6.170342327181719 >>> peaks = [3, 9, 11, 27] >>> tenneyHeight(peaks) 4.371319977187242
- metric_denom(ratio)[source]#
Function that computes the denominator of the normalized ratio. Higher value represents higher dissoance.
- Parameters
ratio (float) – frequency ratio
- Returns
y (float) – denominator of the normalized ratio
Examples
>>> metric_denom(1.50) 2 >>> metric_denom(1.51) 100
- dyad_similarity(ratio)[source]#
This function computes the similarity between a dyad of frequencies and the natural harmonic series. Higher value represents higher harmonicity. Implemented from Gill and Purves (2009)
- Parameters
ratio (float) – frequency ratio
- Returns
z (float) – dyad similarity
Examples
>>> dyad_similarity(3/2) 66.66666666666666 >>> dyad_similarity(16/9) 16.666666666666664
- ratios2harmsim(ratios)[source]#
Metric of harmonic similarity represents the degree of similarity between a tuning and the natural harmonic series. This function uses the dyad_similarity function on a set of ratios. Implemented from Gill and Purves (2009)
- Parameters
ratios (List (float)) – list of frequency ratios (forming a tuning)
- Returns
similarity (List (float)) – list of percentage of similarity for each ratios
Examples
>>> ratios = [3/2, 4/3, 16/9] >>> ratios2harmsim(ratios) array([66.66666667, 50. , 16.66666667])
References
Gill, K. Z., & Purves, D. (2009). A biological rationale for musical consonance. Proceedings of the National Academy of Sciences, 106(29), 12174-12179.
- tuning_cons_matrix(tuning, function, ratio_type='pos_harm')[source]#
This function gives a tuning metric corresponding to the averaged metric for each pairs of ratios
- Parameters
tuning (List (float)) – List of tuning steps (classically between 1 (unison) and 2 (octave))
function (function) – {‘dyad_similarity’, ‘compute_consonance’, ‘metric_denom’}
ratio_type (str (default=’pos_harm’)) –
- choice:
‘pos_harm’ : a/b when a>b
‘sub_harm’ : a/b when a<b
‘all’: pos_harm + sub_harm
- Returns
metric_values (List) – list of the size of input corresponding to the averaged harmonicity between a step and all other steps.
metric_avg (float) – metric value averaged across all steps
Examples
>>> tuning = [1, 1.13, 1.25, 1.33, 1.5, 1.67, 1.75, 1.89] >>> function = dyad_similarity >>> tuning_cons_matrix(tuning, function, ratio_type="pos_harm") ([nan, 1.8761061946902655, 14.517994100294985, 8.079064918934504, 15.143364606205779, 10.567105885817467, 12.66150677394233, 10.398481038234042], 10.398481038234042)
>>> tuning = [1, 1.13, 1.25, 1.33, 1.5, 1.67, 1.75, 1.89] >>> function = compute_consonance >>> tuning_cons_matrix(tuning, function, ratio_type="pos_harm") ([nan, 0.018849557522123892, 0.1618997050147493, 0.08918417725730254, 0.17648067513917537, 0.1223854594889003, 0.1428532247343695, 0.11630349967694496], 0.11630349967694496)
- tuning_to_metrics(tuning, maxdenom=1000)[source]#
This function computes the tuning metrics of the PyTuning library (https://pytuning.readthedocs.io/en/0.7.2/metrics.html) and other tuning metrics
- Parameters
tuning (List (float)) – List of ratios corresponding to tuning steps
maxdenom (int (default=1000)) – Maximum denominator of the fraction representing each tuning step.
- Returns
tuning_metrics (dictionary) – keys correspond to metrics names
tuning_metrics_list (List (float)) – List of values corresponding to all computed metrics (in the same order as dictionary)
Examples
>>> tuning = [1, 1.13, 1.25, 1.33, 1.5, 1.67, 1.75, 1.89] >>> tuning_to_metrics(tuning, maxdenom=1000) {'sum_p_q': 1029, 'sum_distinct_intervals': 56, 'metric_3': 20.6720768749949, 'sum_p_q_for_all_intervals': 10794, 'sum_q_for_all_intervals': 5244, 'harm_sim': 31.14, 'matrix_harm_sim': 10.398481038234042, 'matrix_cons': 0.11630349967694496, 'matrix_denom': 83.64285714285714}
- timepoint_consonance(data, method='cons', limit=0.2, min_notes=3, graph=False)[source]#
Function that keeps moments of consonance from multiple time series of peak frequencies. Can be used with the
biotuner.biotuner_object.compute_spectromorph()
function to compute timepoint consonance across the time series of spectral centroïd (or other spectromorphological metrics) derived from each Intrinsic Mode Function (IMF) using Empirical Mode Decomposition. This function can also be used of the instantaneous frequencies associated with each IMF.- Parameters
data (List of lists (float)) – Axis 0 represents moments in time Axis 1 represents the sets of frequencies
method (str, default=’cons’) –
- ‘cons’:
will compute pairwise consonance between frequency peaks in the form of (a+b)/(a*b)
- ‘euler’:
will compute Euler’s gradus suavitatis
- ‘harmsim’:
will compute harmonic similarity using dyad_similarity function.
limit (float, default=0.2) –
limit of consonance under which the set of frequencies are not retained
- When method = ‘cons’
–> See
biotuner.metrics.compute_consonance()
to refer to consonance values to common intervals- When method = ‘euler’
Major (4:5:6) = 9
Minor (10:12:15) = 9
Major 7th (8:10:12:15) = 10
Minor 7th (10:12:15:18) = 11
Diminish (20:24:29) = 38
min_notes (int, default=3) – Minimal number of consonant frequencies in the chords.
Only relevant when method is set to ‘cons’.
- Returns
chords (List of lists (float)) – Axis 0 represents moments in time Axis 1 represents the sets of consonant frequencies
positions (List (int)) – positions on Axis 0
Examples
>>> 'USING RANDOM DATA' >>> # Set the number of time series and the number of samples per time series >>> n_time_series = 5 >>> n_samples = 1000 >>> >>> # Define the frequency range >>> min_freq = 1 >>> max_freq = 10 >>> precision = 0.1 >>> >>> # Generate the random time series >>> rand_integers = np.random.randint(min_freq * 10 / precision, max_freq * 10 / precision, size=(n_time_series, n_samples)) >>> time_series = rand_integers / 10 >>> >>> tc, _ = timepoint_consonance(time_series, method="cons", limit=0.2, min_notes=3, graph=False) >>> tc [[23.1, 84.7, 74.8, 81.6], [30.0, 75.0, 42.0], [10.0, 24.0, 32.5], [93.6, 83.2, 33.8], [67.6, 91.0, 18.2], [72.8, 11.7, 49.5, 89.1], [95.4, 53.0, 52.0, 64.0], [37.0, 44.4, 37.8, 69.3], [19.8, 50.4, 32.4], [21.5, 43.0, 17.2], [15.0, 54.0, 29.0, 92.8], [55.9, 30.1, 99.0, 40.5], [55.8, 21.7, 99.2], [30.5, 22.4, 12.6, 91.5]]
>>> 'USING THE BIOTUNER OBJECT' >>> # Load data >>> data = np.load('data_examples/EEG_pareidolia/parei_occi_L.npy') >>> # Keep a single time series. >>> data = data[0] >>> # Initialize biotuner object >>> bt = compute_biotuner(sf=1200, peaks_function='EMD') >>> # Extract spectral peaks >>> bt.peaks_extraction(data) >>> # Compute timepoint consonance using Spectral Centroid on IMFs. >>> bt.compute_spectromorph( method="SpectralCentroid", overlap=1, comp_chords=True, min_notes=4, cons_limit=0.2, cons_chord_method="cons", graph=False, ) >>> bt.spectro_chords [[15.47, 6.63, 31.68, 2.42], [5.72, 12.71, 26.64, 2.59], [15.31, 6.38, 2.53, 64.77], [67.59, 2.7, 33.79, 16.8]]
- compute_subharmonics(chord, n_harmonics, delta_lim)[source]#
Compute subharmonics of a chord and find the common subharmonics within a given delta limit.
- Parameters
chord (list of int) – A list of integers representing the chord.
n_harmonics (int) – The number of harmonics to compute.
delta_lim (float) – The limit of delta between two subharmonics to be considered common. This value is in milliseconds (ms).
- Returns
subharms (list of list of float) – A list of lists of subharmonics for each element in the chord.
common_subs (list of list of float) – A list of lists of common subharmonics within the delta limit.
delta_t (list of float) – A list of delta values for the common subharmonics.
Examples
>>> chord = [3, 5, 7] >>> subharms, common_subharms, delta_t = compute_subharmonics(chord, 5, 20) >>> print('subharms', subharms) >>> print('common_subharms', common_subharms) >>> print('delta_t', delta_t) subharms [[333.3333333333333, 666.6666666666666, 1000.0, 1333.3333333333333, 1666.6666666666667], [200.0, 400.0, 600.0, 800.0, 1000.0], [142.85714285714286, 285.7142857142857, 428.57142857142856, 571.4285714285714, 714.2857142857143]] common_subharms [[1000.0, 1000.0]] delta_t [0.0]
- compute_subharmonic_tension(chord, n_harmonics, delta_lim, min_notes=2)[source]#
Computes the subharmonic tension for a set of frequencies, based on the common subharmonics of a minimum of 2 or 3 frequencies. This metric has been adapted from Chan et al. (2019).
- Parameters
chord (numpy array, shape (n,)) – Array containing the frequencies to compute subharmonic tension on.
n_harmonics (int) – Number of subharmonics to compute for each frequency.
delta_lim (float) – Maximal distance between subharmonics of different frequencies to consider them as common subharmonics.
min_notes (int, {2, 3}, default=2) – Minimal number of notes to consider common subharmonics.
- Returns
common_subs (numpy array, shape (m,)) – Array containing the common subharmonics.
delta_t (numpy array, shape (m,)) – Array containing the subharmonic distances.
subharm_tension (float or str) – The subharmonic tension value, calculated as the average of the product of the subharmonic distance and the subharmonic frequency over all subharmonic pairs. Returns “NaN” if no valid subharmonic pairs are found.
harm_temp (numpy array, shape (m,)) – Array containing the subharmonic harmonic values.
Examples
>>> chord = [3, 5, 7] >>> _, _, subharm_tension, _ = compute_subharmonic_tension(chord, 5, 20, min_notes=2) >>> subharm_tension [0.0] >>> chord = [31, 51, 71] >>> _, _, subharm_tension, _ = compute_subharmonic_tension(chord, 5, 20, min_notes=2) >>> subharm_tension [0.23539483720429924]
Notes
The subharmonic tension is a measure of the perceived stability of a musical chord. The subharmonic tension is calculated as the average of the product of the subharmonic distance and the subharmonic frequency over all subharmonic pairs. A subharmonic is a frequency that is an integer divisor of another frequency. Common subharmonics are defined as subharmonics that are shared by at least min_notes notes in the chord.
References
Chan, P. Y., Dong, M., & Li, H. (2019). The science of harmony:A psychophysical basis for perceptual tensions and resolutions in music. Research, 2019.
- compute_subharmonics_2lists(list1, list2, n_harmonics, delta_lim, c=2.1)[source]#
Compute the subharmonic tension (Chan et al., 2019) for pairs of frequencies from two different lists, based on the common subharmonics of each pair.
- Parameters
list1 (list of floats) – Values of the first set of frequencies to compute subharmonic tension on.
list2 (list of floats) – Values of the second set of frequencies to compute subharmonic tension on.
n_harmonics (int) – Number of subharmonics to compute for each frequency.
delta_lim (float) – Maximal distance between subharmonics of different frequencies to consider them as common subharmonics.
c (float, default=2.1) – Constant parameter for computing subharmonic tension.
- Returns
tuple –
- common_subslist of lists (floats)
List of common subharmonics found for each pair of frequencies.
- delta_tlist of lists (floats)
List of the smallest differences between common subharmonics found for each pair of frequencies.
- sub_tension_finalfloat
The overall subharmonic tension value computed by averaging across all pairs of frequencies.
- harm_templist of floats
List of harmonic tensions for each subharmonic tension computed.
- pair_melodylist of floats
List containing the pair of frequency with the lowest subharmonic tension. Could be used in transitional harmony to derive subharmonic melodies.
Examples
>>> list1 = [5, 9] >>> list2 = [13, 20, 7] >>> n_harms = 5 >>> delta_lim = 30 >>> _, _, sub_tension, _, pair_melody = compute_subharmonics_2lists(list1, list2, n_harms, delta_lim, c=2.1) >>> subtension, pair_melody (0.05213398154647142,(5, 20))
- consonant_ratios(data, limit, sub=False, input_type='peaks', metric='cons', set_rebound=True)[source]#
Function that computes integer ratios from peaks with higher consonance
- Parameters
data (List (float)) – Data can whether be frequency values or frequency ratios
limit (float) – minimum consonance value to keep associated pairs of peaks
sub (boolean, default=False) – When set to True, include ratios a/b when a < b.
input_type (str, default=’peaks’) – Choose between: - ‘peaks’ - ‘ratios’
metric (str, default=’cons’) – Choose between: - ‘cons’ - ‘harmsim’
set_rebound (bool, default=True) – Defines if the ratios are rebounded between 1 and 2. Only valid when input_type = ‘peaks’.
- Returns
cons_ratios (List (float)) – list of consonant ratios
consonance (List (float)) – list of associated consonance values
Examples
>>> ratios = [1, 1.25, 1.34, 1.5, 1.67, 1.86] >>> cons_ratios, metrics = consonant_ratios(ratios, >>> 0.2, >>> sub=False, >>> input_type="ratios", >>> metric="cons") >>> cons_ratios, metrics (array([1. , 1.25, 1.5 ]), [2.0, 0.45, 0.8333333333333334])
>>> freqs = [3, 4.5, 11, 17] >>> ratios, metrics = consonant_ratios(freqs, >>> 0.2, >>> sub=False, >>> input_type="ratios", >>> metric="cons") >>> ratios, metrics (array([1.222, 1.5 , 1.833]), [0.20202020202020202, 0.8333333333333334, 0.25757575757575757])
- consonance_peaks(peaks, limit, limit_pairs=True)[source]#
This function computes consonance (for a given ratio a/b, when a < 2b), consonance corresponds to (a+b)/(a*b)) between peaks.
- Parameters
peaks (list of floats) – Peaks represent local maximum in a spectrum.
limit (float) –
Minimum consonance value to keep associated pairs of peaks.
Comparisons with familiar ratios: Unison-frequency ratio 1:1 yields a value of 2
Octave-frequency ratio 2:1 yields a value of 1.5
Perfect 5th-frequency ratio 3:2 yields a value of 0.833
Perfect 4th-frequency ratio 4:3 yields a value of 0.583
Major 6th-frequency ratio 5:3 yields a value of 0.533
Major 3rd-frequency ratio 5:4 yields a value of 0.45
Minor 3rd-frequency ratio 5:6 yields a value of 0.366
Minor 6th-frequency ratio 5:8 yields a value of 0.325
Major 2nd-frequency ratio 8:9 yields a value of 0.236
Major 7th-frequency ratio 8:15 yields a value of 0.192
Minor 7th-frequency ratio 9:16 yields a value of 0.174
Minor 2nd-frequency ratio 15:16 yields a value of 0.129
- limit_pairsbool, default=True
Whether to compute consonance only for ratios where a > b. If False, also use ratios where a < b by dividing b iteratively.
- Returns
consonance (list of floats) – Consonance scores for each pair of consonant peaks.
cons_pairs (list of lists of floats) – List of lists of each pair of consonant peaks.
cons_peaks (list of floats) – List of consonant peaks (no duplicates).
cons_tot (float) – Averaged consonance value for each pair of peaks.
Examples
>>> peaks = [3, 9, 11, 21] >>> consonance, cons_pairs, cons_peaks, cons_tot = consonance_peaks(peaks, limit=0.5, limit_pairs=True) >>> consonance, cons_pairs, cons_peaks, cons_tot ([1.3333333333333333, 1.1428571428571428], [[3, 9], [3, 21]], [9, 3, 21], 0.31024531024531027)
- spectral_flatness(harmonicity_values)[source]#
Calculate the spectral flatness of a signal.
- Parameters
harmonicity_values (ndarray) – Harmonicity values of the signal.
- Returns
float – Spectral flatness of the signal.
- spectral_entropy(harmonicity_values)[source]#
Calculate the spectral entropy of a signal.
- Parameters
harmonicity_values (ndarray) – Harmonicity values of the signal.
- Returns
float – Spectral entropy of the signal.