I have developed a method and python script: https://github.com/githubuser1983/algorithmic_python_music which allows the user to input a midi file and then chose a few numbers as parameters, and the user of the script will get a similar sounding yet different midi file as a result. The method is more math- / statistics related than AI (with neural nets) but has the advantage to produce similar pieces with only one input file in contrast to neural nets which need many midi files.
Here are the scores of some pieces I have done this way:
(original) https://musescore.com/user/37663311/scores/6919248
(algorithmic mix, Gymnopedie no 1) https://musescore.com/user/37663311/scores/6917919
(für Elise, algorithmic interpretation) https://musescore.com/user/37663311/scores/6917155
https://musescore.com/user/37663311/scores/6919824 A cover of some known piece...
More can be found here:
https://soundcloud.com/user-919775337/sets/algorithmic-reinterpretation
First I read the midi file, note per note: note = (pitch, duration, volume, isPause), Then based on the song, I will create a positive definite matrix M (which is based on kernels defined on the atomic unit note = (pitch, duration, volume, isPause) ) and then I do Cholesky factorization of this song matrix. In the next step I will do PCA to reduce the dimension of the Cholesky factorization. After this step I train a vector autoregression model, and then apply it to the original song to forecast the next note. Having this note in vector form I choose via nearest neighbor, the one note in the original song and collect those note to produce a new algorithmic version of the song.
Depending on the parameters, this sometimes works well, meaning that it sounds good, sometimes not.
My mathematical question is, how could I "combine" to distinct songs to produce one song. One idea was to train the var model on one song and do the forecast on the other song.
Do you see any problems in using this method, or would you do another method?
Thanks for your help.
Edit
Let $\alpha = 2^{1/12}, k(a,b) = \gcd(a,b)^2/(ab), q(r) \equiv a/b$ where $r$ is a real number and $a/b$ is a rational approximation. Each of the 88 keys on piano can be numbered from 0 to 87. A voice in a piece can be (without rests) given as a sequence of numbers $n_1,\cdots,n_r$ each $0 \le n_i \le 87$.
Let $H(a/b) := k(a,b)$ for a,b natural numbers. This is well defined, since $k(ac,bc) = k(a,b)$. For pitches $x,y$ we can define the kernel on the pitches:
$$s(x,y) = H(q(\alpha^{x-y}))$$
The rationale behind this is that pitches which are interpreted as nice by the brain tend to have "simpler" qutioents. The simplicity of the quotient is measured by the similarity / kernel s.
Now if we do the same for duration and volume after normalizing both to lie in the range $0< d, v \le 1$ we could define the kernel:
$$k_{2}(a,b) = \log(a) \log(b)$$
(I am not sure however that this function is positive semidefinite, so this is my first question:)
- Is $k_{2}$ positive definite?
For the rests we define the kernel $k(r,s) = 1$ if $r = s$, otherwise $=0$.
Then for the "atomic unit" note = (pitch, duration, volume, isRest) we have kernels, which we can add to:
$$k(n_1,n_2) := k_{p}(p_1,p_2)+k_d(d_1,d_2)+k_v(v_1,v_2)+k_r(r_1,r_2)$$
Since music songs are very repetetive, the resulting gramian matrix:
$$M = (k(n_i,n_j))_{i,j}$$
will be positive semidefinte, and not positive definite in general.
To overcome this problem, we might want to look at sequences of notes of fixed length $l$ and define a kernel on the sequence space as the sum of the kernels $k$.
So this new kernel measures the similarity of sequence of notes in the given song. We can create a sliding window of lenght $l$ called n-grams for these sequence.
Another approach to get a positive definite matrix is simply to add $\epsilon I$ to the matrix $M$.
In the next step I will do Cholesky decomposition:
$$M = CC^T$$
My goal is to predict new notes based on previously seen notes. For this vector autoregression could be an option, so I will reduce the dimension with principal component analysis of the matrix $C$ to get the matrix $X$.
Now I apply vector autoregression on $X$ and have a model $r$. I will go throug each vector of the matrix $X$ which corresponds to a sequence of notes and then with $r$ I will predict a new vector. To get from this vector a sequence of notes, I suggest using the nearest neighbor of $X$. This way there will be build a sequence of notes (not quite notes but a sequence of sequences of notes from which we can take for instance the middle note) which gives us the new processed piece.
The nice thing using nearest neighbor is that in this way, we get only original material from the song: note = (pitch, duration, volume, isRest) and it will sound most of the time nice.
My second question is:
- How do I combine two songs using the procedure above?