Wow that was a lot of work put into 4 days (problem solving)
So this last stretch is gonna be two posts, one explaining the problems I encountered while doing the respective patches and how I solved them and the other one explaining what the patch is doing to create the textures.
For starters, let's discuss the problems I had during the development of the patch, The first one and as I mentioned before at the beginning of my exploration of VCV, since the changes are travelling through the clock of Spyder with my program, every signal that I send immediately arrives to the patch, and can generate changes that appear too sudden and unpleasant. After trying it for a while I realized that the changes felt too sudden in 2 occasions, first when changing from one progression to the other (M to m or viceversa) and second, when changing bpm and not resetting the clock, so to fix this I did a couple things.
I developed a function within the program by the name of ProgChange, that checks which progression is being played at the moment, when triggered, this function will grab the slider of whichever progression is being used at the time, and over the course of 9 seconds, reduce its volume, remain silent for a moment and raise the volume of the progression to be played.
duration1 = 3.0
duration2 = 3.0
print("M volume:",M)
print("m volume:",m)
if (M>m):
Activate(14)
start_time = time.time()
while (time.time() - start_time) < duration1:
# Calculate the current value based on the elapsed time
newM = int(M - (M * (time.time() - start_time) / duration1))
M_mix_volume = mido.Message('control_change', control=0, value=newM, channel=1)
outport.send(M_mix_volume)
time.sleep(0.01)
else:
Activate(12)
start_time = time.time()
while (time.time() - start_time) < duration1:
# Calculate the current value based on the elapsed time
newm = int(m - (m * (time.time() - start_time) / duration1))
m_mix_volume = mido.Message('control_change', control=1, value=newm, channel=1)
outport.send(m_mix_volume)
time.sleep(0.01)
time.sleep(2)
Activate(3)
if (M>m):
start_time = time.time()
while (time.time() - start_time) < duration2:
# Calculate the current value based on the elapsed time for the second variable
newm = int(128 * (time.time() - start_time) / duration2)
m_mix_volume = mido.Message('control_change', control=1, value=newm, channel=1)
outport.send(m_mix_volume)
time.sleep(0.01) # Wait for a short period to slow down the loop
else:
start_time = time.time()
while (time.time() - start_time) < duration2:
# Calculate the current value based on the elapsed time for the second variable
newM = int(128 * (time.time() - start_time) / duration2)
M_mix_volume = mido.Message('control_change', control=0, value=newM, channel=1)
outport.send(M_mix_volume)
time.sleep(0.01) # Wait for a short period to slow down the loop
if (newM>newm):
Activate(15)
else:
Activate(13)
print("M new volume:",newM)
print("m new volume:",newm)
return(newM,newm)
In this code, the function Activate is also a custom made function that sends a trigger to a parameter, with the number inside it being the MIDI channel to be used, it is the solution to a problem to be discussed next. At the same time, in this configuration. channel 3 is sending a trigger information to the Reset function in the general clock at the patch, meaning it can reset into position to avoid the bpm discrepancy I mentioned earlier.
Another problem I had to tackle came in the form of CPU usage, and I will discuss this a little more on the next post but, the way I designed the patch made it so multiple signals travelling at the same time, even when turned off, were corrupting the audio output. In looking for ways to better the program's performance, I stumbled into this video by Omri Cohen (god bless his soul) talking about different techniques that could help, in them I found a handy module called STRIP that would allow me to disable a whole section of the patch with the click of a button, although this was in theory designed for live performances, I managed to track it using voltage changes through MIDI, so that in the prog change sequence, different parts of the patch are made available when needed, practically cutting down processing in half and clearing my output.


Comments
Post a Comment