THE CYBER INFORMANT

Articles/ Variablity & Perfectionism in Music

3.Variablity & Perfectionism in Music

1/20/2024

Allow me to start by laying down a logical truth that has grounds in both statistics and art: The more non-constant (variable) components we have in a system, the higher the entropy, the higher the probability for flaws & imperfections". I would like to make it clear that the previous statement is not to be interpreted in a vaccum, as "flaws" and "imperfections" do not exist statiscally and are ways for us to interpret data, in this context, art.

The above can be shortly summarized by the term "entropy". As the variables (musical instruments, musical keys, tempo, dynamics, tonality, timbre, texture, melody, harmony, form, rhythm, etc..) increase, the less chance of being "perfect" there is. I have went over the orchestra class I atteneded (at the time of writing this on paper before publishing it here, 1/2/2022) and I have surveyed my classmates, all of whom were musically skilled enough to philosophize on what sounds "good" and what doesn't sound "good" in musical theory, how to improve musical passages, and play well on other string instruments. I showed them multiple musical passage samples I wrote: The 1st was a whole note on the open-D string, the 2nd was 4-qarter notes on open-D string, the 3rd was 2-half notes on open-D string and E on the othe D-string; the other samples were of varying diversity of dynamics, note lenghts, and flats and sharps.

I had asked them "which sample was the most "perfect"", and after reading an argument, stating that "perfect" meant "needing the least amount of improvements", the overwhelming concensus went to the 1st sample, the simple whole note on open-D string. When asked about the most the most beautiful, the majority answered that the sample featuring descnending quarter notes was the most complex without sacrificing a beauty of a comforting pattern that is easy to process.

Synthesizing Music with MATLAB

In an effort to explore the balance between simplicity and complexity in music, I developed a program using MATLAB. The program generates and plays musical notes sequentially, incorporating varying elements such as different waveforms, volumes, and durations. This allows for the creation of both simple and complex musical passages, providing a platform to experiment with and analyze musical variability and perceived perfection.

The program starts by asking the user for the number of notes to generate, then randomly selects musical notes and waveforms, creating a series of notes with diverse characteristics. It smoothly transitions between notes to ensure a continuous and harmonious sound, demonstrating how variability in musical elements affects the overall perception of the music.

The simplified version of the program generates a sequence of a single musical note (D) at a fixed volume and duration, ensuring a continuous and harmonious sound. Below is an overview of the program's functionality:
  1. User Input: The user specifies the duration of the generated music.
  2. Note Generation: The program generates the note D with a specific frequency.
  3. Waveform Creation: The program creates a sine waveform for the note.
  4. Playback and Saving: The program plays the generated note and saves it as a WAV file.
function generateAndPlayNotesSequentially()
% Define the musical note 'D' and its corresponding frequency
note = 'D';
frequency = 293.66;  % Frequency for note D4

% Fixed volume
volume = 10;

% Note and rest durations
note_duration = 4;  % 4 seconds
rest_duration = 1;  % 1 second

% Number of notes
num_notes = 3;

% Sampling frequency (44.1 kHz)
fs = 44100;

% Generate the waveform for the note 'D'
t_note = linspace(0, note_duration, round(note_duration * fs));
waveform_note = volume * sin(2 * pi * frequency * t_note);

% Generate the waveform for the rest (silence)
t_rest = linspace(0, rest_duration, round(rest_duration * fs));
waveform_rest = zeros(1, length(t_rest));

    % Combine notes and rests
    combined_waveform = [];
    for i = 1:num_notes
        combined_waveform = [combined_waveform, waveform_note, waveform_rest];
    end

    % Normalize the combined waveform
    combined_waveform = combined_waveform / max(abs(combined_waveform));

    % Save the combined waveform as a WAV file
    filename = 'generated_music.wav';
    audiowrite(filename, combined_waveform, fs);
    fprintf('The generated music has been saved as %s\n', filename);

    % Play the combined waveform
    soundsc(combined_waveform, fs);

    % Display the generated notes information
    fprintf('Generated Note: %s\n', note);
    fprintf('Note Duration: %.2f sec\n', note_duration);
    fprintf('Rest Duration: %.2f sec\n', rest_duration);
    fprintf('Volume: %d\n', volume);
    fprintf('Number of Notes: %d\n', num_notes);

    fprintf('\n');
end


The script above produces the audio file below:



This is perhaps as simple as it gets. The least amount of variables ever. Perhaps one could argue that shorter rest times, shorter than the 1 second used, would be better, although without the rests in between it would just be 1, continous sound. Perhaps that is the most basic sound isn't it? But this is it, one constant frequency (note), one constant volume, and a non-changing waveform. It is arguably perfect. There is nothing to change, nothing to improve, it has no flaws. A perfect circle is a perfect circle because it has no squiggly lines, whenever we see a circle we compare it to the pefect form of circle that we have in our minds. A perfect circle is a bad square. A perfect square is a bad circle. Our recording above is not attempting anything it wasn't made for. Is there any other way for it to produce the same frequency-note 4 times? I would argue no.

No matter how many times you run the script above, it will produce the same results. That is what makes it perfect for what it is.

Adding Notes & Their corresponding Frequencies

Upping the variablity now, therefore upping the amount of entropy, or increasing the states of possible non-perfect combinations to perhaps the 1 perfect combination, we can predict that if surveyed, people will have more varrying opinions of what sounds "perfect" to them.

To illustrate this, let’s modify our program to include multiple notes and their corresponding frequencies. This will introduce variability and allow us to explore how different elements interact to create music that may be perceived as either more or less perfect.
function generateRandomNotes()
% Define the musical notes and their corresponding frequencies
notes = {'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B', 'Rest'};
frequencies = [261.63, 277.18, 293.66, 311.13, 329.63, 349.23, 369.99, 392.00, 415.30, 440.00, 466.16, 493.88, 0]; % 0 Hz for rest
    
% Ask user for the number of notes
num_notes = input('Enter the number of notes to generate: ');

% Initialize arrays for the frequencies and note names
chosen_frequencies = zeros(1, num_notes);
chosen_notes = cell(1, num_notes);

% Randomly choose notes and their frequencies
for i = 1:num_notes
    note_index = randi(length(notes));
    chosen_frequencies(i) = frequencies(note_index);
    chosen_notes{i} = notes{note_index};
end
    
% Set constant duration and volume
duration = 1; % 1 second
volume = 10; % 10 decibels
amplitude = 10^(volume / 20); % Convert dB to linear amplitude
    
% Sampling frequency
fs = 44100;

% Generate and combine waveforms for each note
combined_waveform = [];
for i = 1:num_notes
    t = linspace(0, duration, duration * fs);
    if chosen_frequencies(i) == 0
        waveform = zeros(1, length(t)); % Rest note
    else
        waveform = amplitude * sin(2 * pi * chosen_frequencies(i) * t);
    end
    combined_waveform = [combined_waveform, waveform];
end

% Normalize the combined waveform
combined_waveform = combined_waveform / max(abs(combined_waveform));

% Save the combined waveform as a WAV file
filename = 'generated_notes.wav';
audiowrite(filename, combined_waveform, fs);
fprintf('The generated music has been saved as %s\n', filename);
    
% Automatically play the saved WAV file
[y, fs] = audioread(filename);
sound(y, fs);
end
                

Now the script above is interesting, as you can set the number of generated notes to however many you want, therefore hypothetically, given enough stringed notes, you can generate all the songs & musical pieces in existence that use the preset notes that we have, to some accurate replay quality that is. I ran the script twice to get varrying generated notes:





A continuation to the above, due to hardware limitations you might face, you will not be able to set the number of generated notes to a million, although you will be able to generate a .wav file containing a 1000 notes, run the script 1000 times, generating a 1000 files, each containing 1000 notes, that's 1 million notes. Then using python or C/C++ you can have a program/script string those files and play them one after the other. You will have a pretty good chance of getting a measure or 2 of the Twinkle Twinkle piece. Another thing to mention is the preset tones and frequencies we have, you can practically have an infinite number of frequencies to play, although for practical purposes, you are better off stopping at a maximum of 20 thousand Herts. For the C note that we have, we have assigned the standard frequency of 261.63 Hz, but we could also have a new note, a viariant of C, that is tuned to 255 Hz, or even a note that is 261.00 Hz. To us it wouldn't be of noticable or important difference, but technically speaking it would be a different sounding note. We can include microtonals, and microtonals of microtonal notes, and so on until we get sick of convincing ourselves that 255.546 Hz doesn't sound the same as 255.530 Hz. You can add a section in the program above that picks the frequency to be a random float-number anywhere from 20 Hz to 20000 Hz. And of course this would even increase the entropy in the musical system that we have more than the preset 13 notes that we have. Reducing the propabaility of scoring a composition where everything plays well together and sounds "perfect".

Variable Volume Values

It does take a while for an individual to reach a meta-musical understanding of how lowering or increasing the volume (loudness) of a note can have an impact on how a passage forms, progresses, and concludes. Low-volume notes can introduce a sense of subtle-importance, pulling in whoever listens closer, attempting to hear what the notes are, they cause a mysterious buildup if they continue low, or if not then they give a sense of something wanting to unfold and spread it's news around. While high-volume notes can force themselves and establish a dominance over low-volume ones, build a sense of aggresiveness and quick progressiveness across the passages and measures, as well as echo an important event across the themes of the composition. To go along our script, we can add a variable of volume between 3 and 50 decibels, and then pick a random value from that range:
function generateRandomNotes()
% Define the musical notes and their corresponding frequencies
notes = {'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B', 'Rest'};
frequencies = [261.63, 277.18, 293.66, 311.13, 329.63, 349.23, 369.99, 392.00, 415.30, 440.00, 466.16, 493.88, 0]; % 0 Hz for rest
                    
% Ask user for the number of notes
num_notes = input('Enter the number of notes to generate: ');
                
% Initialize arrays for the frequencies, note names, and volumes
chosen_frequencies = zeros(1, num_notes);
chosen_notes = cell(1, num_notes);
volumes = 10.^((3 + rand(1, num_notes) * 47) / 20); % Random volumes between 3 dB and 50 dB
                
% Randomly choose notes and their frequencies
for i = 1:num_notes
    note_index = randi(length(notes));
    chosen_frequencies(i) = frequencies(note_index);
    chosen_notes{i} = notes{note_index};
end
                    
% Set constant duration
duration = 1; % 1 second
                    
% Sampling frequency
fs = 44100;
                
% Generate and combine waveforms for each note
combined_waveform = [];
for i = 1:num_notes
    t = linspace(0, duration, duration * fs);
    if chosen_frequencies(i) == 0
        waveform = zeros(1, length(t)); % Rest note
    else
        waveform = volumes(i) * sin(2 * pi * chosen_frequencies(i) * t);
end
combined_waveform = [combined_waveform, waveform];
                        
% Print note details
fprintf('Note: %s, Frequency: %.2f Hz, Duration: %.1f sec, Volume: %.2f dB\n', ...
chosen_notes{i}, chosen_frequencies(i), duration, 20*log10(volumes(i)));
end
                
% Normalize the combined waveform
combined_waveform = combined_waveform / max(abs(combined_waveform));
                
% Save the combined waveform as a WAV file
filename = 'generated_notes.wav';
audiowrite(filename, combined_waveform, fs);
fprintf('The generated music has been saved as %s\n', filename);
                    
% Automatically play the saved WAV file
[y, fs] = audioread(filename);
sound(y, fs);
end    
I picked the value range above (3 - 50 decibles) as it provides a huge contrast between the possible softness and the potential explosive volumes that can be generated.

After all what has been written above, I still wonder whatever people value conservative-yet-perfect music or experimental/liberal/non-deliberate music. And what leads someone to prefer one over the other.

Thank you for reading this far! Don't shy from sending suggestions or anything to the contacts listed in Whoami.

This website was made by me.
This page was made with only HTML & CSS. No JS