PizzaToppingsCombo
For the Sixth Decibels Challenge, the prompt was Data Around Us. In this sonification named PizzaToppingsCombo, I have taken the top 10 Pizza Toppings ( from the following link https://www.hungryhowies.com/article/10-most-popular-pizza-toppings-united-states and sonify them based on the most popular combos in a three-topping per pizza limit. This works with the Data around me as I was eating a three-topping pizza at the time.
Using a mixture of Sonic Pi, Python, Boolean Algebra and other mathematical concepts to compose the sonification.
Sonification/Audio
https://soundcloud.com/llestreacha/sets/pizzatoppingscombo
IllestPreacha · PIzzaToppingsCOmbo
Python Code
In the Python code, the combinations function from the itertools library was used to get the right amount of possible toppings to be calculated. Follow by having the sounds communicate to SonicPi via a timer that was sending the combos through the OSC protocol.
#external code borrowed for timer: -https://www.geeksforgeeks.org/how-to-create-a-countdown-timer-using-python/
#itertools for comibnations and osc
from itertools import combinations
from pythonosc import osc_message_builder
from pythonosc import udp_client
# import the time module
import time
toppings = []
# Get all combinations of the top ten toppings
# and a max of 3
comb = combinations(['Pepperoni','Extra Cheese','Mushrooms','Onions','Sausage','Black Olives','Green Peppers','Pineapple', 'Spinach','Cheese'], 3) #10 total toppings, 3 toppings allowed for pizza
# Print the obtained combinations
# print the list into an array
counter = 0
for i in list(comb):
print (i)
counter +=1
toppings.append(i)
print (counter) #prints the total counter
#using the length of the toppings to be the timer but going to times it by two, so the call to sonic pi
#is slower
t = len(toppings) * 2
# define the countdown func.
while t:
mins, secs = divmod(t, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
print(timer, end="\r")
time.sleep(1.5) #alter the time that to slow down or speed up the osc call
#Combinations being sent to SonicPi
if t % 2 == 0:
t -= 2
sender = udp_client.SimpleUDPClient('127.0.0.1', 4560)
sender.send_message('/pattern1', [toppings[int(t/2)][0], toppings[int(t/2)][1], toppings[int(t/2)][2]])
Sorting Data
The Categories of the Toppings
Meat: Pepperoni, Sausage, Extra Cheese (Did this grouping for sonic Purposes)
Vegetables: Mushrooms, Onions, Black Olives, Spinach, Cheese
Fruit: Green Peppers, Pineapple
Logic Table for the Set of Toppings
The following is a logic table for when the pizza toppings contain any combination of the above categories
To be a Vegetarian based pizza, All Toppings must be Vegetarian or Fruit, which equates to
Vegeterian = veggies | fruit #union if vegeterian.include? a and vegeterian.include? b and vegeterian.include? c
Meat & Dairy Toppings | Veggie Toppings | Fruit Toppings | Output |
F | F | F | None |
F | T | F | Vegetarian |
F | F | T | Vegetarian,Fruit |
F | T | T | Vegetarian,Fruit |
T | F | F | Meat Lovers |
T | T | F | Meat Based |
T | F | T | Meat Based |
T | T | T | All Dressed |
SonicPi Code
Sorting Sounds
Then In the SonicPi Code, we translated this into different auditory outputs. The Following Sounds were attributed to specific combos:
Loop (Amen, Electric and Garzul) For toppings that included a veggie mix, with Amen being if it contains any fruits
The meat & fruit & meat & veggie combos in the first sonification consisted of Sounds that were represented by either Guitars(Em9, Harmonics and E_slide), Drums(Bass_Hard, Bass_Soft and Snare_Hard) or Percussion(Snap2, Swash and Swoosh) sounds
The meat & veggie combos in the second sonification consisted of Sounds that were represented by either Tabla(Dhec, Ghe2 and Ghe3), Elec(Blip, Beep and Flip) or Ambi(Drone,Glass_hum or Glass_rub) sounds
#setting the conditionals rules of what is recieved from the Python Code
meat_ = ['Pepperoni','Extra Cheese','Sausage']
fruit = ['Green Peppers','Pineapple']
veggies = ['Mushrooms','Onions','Black Olives','Spinach']
#Potential Combo outputs
#Vegetarian
#Vegetarian&Fruit
#Vegetarian&Fruit
#MeatLovers
#MeatBased = meat_.include? a or meat_.include? b or meat_.include? c
#MeatBased
#AllDressed
#checking for one ingredient
vegeterian = veggies | fruit #union
live_loop :veggiegroup do
use_real_time
a, b, c, = sync "/osc*/pattern1"
toppings = [a,b,c] #from what was call via osc
with_fx :flanger, mix: rrand(0.1,0.9) do
if vegeterian.include? a and vegeterian.include? b and vegeterian.include? c
sample :loop_garzul, beat_stretch: 3
end
if fruit.include? a or fruit.include? b or fruit.include? c
sample :loop_amen, pitch: dice(10), sustain: 2
end
if veggies.include? a and fruit.include? b and fruit.include? c
sample :loop_electric, pitch: dice(10), sustain: 4
end
end
sleep [0.25,0.5,0.75].choose
end
live_loop :meatfruitgroup do
use_real_time
a, b, c, = sync "/osc*/pattern1"
toppings = [a,b,c] #from what was call via osc
with_fx :flanger, mix: rrand(0.1,0.9) do
if meat_.include? a or meat_.include? b or meat_.include? c
sample [:guit_em9,:guit_harmonics,:guit_e_slide].choose, beat_stretch: 12 if spread(9,12).tick
end
if meat_.include? a and meat_.include? b and fruit.include? c
sample [:drum_bass_hard,:drum_bass_soft,:drum_snare_hard].choose, pitch: dice(10), sustain: 2
end
if fruit.include? a and fruit.include? b and meat_.include? c
sample [:perc_snap2,:perc_swash,:perc_swoosh].choose, pitch: dice(10), sustain: 4
end
end
sleep [0.25,0.5,0.75].choose
end
live_loop :meatveggiegroup do
use_real_time
a, b, c, = sync "/osc*/pattern1"
toppings = [a,b,c] #from what was call via osc
with_fx :flanger, mix: rrand(0.1,0.9) do
if meat_.include? a or meat_.include? b and vegeterian.include? c
sample [:guit_em9,:guit_harmonics,:guit_e_slide].choose, beat_stretch: 12 if spread(9,12).tick
end
end
with_fx :ping_pong, mix: rrand(0.3,0.75) do
if meat_.include? a or meat_.include? c or vegeterian.include? b
sample [:drum_bass_hard,:drum_bass_soft,:drum_snare_hard].choose, pitch: dice(10), sustain: 2
end
end
with_fx :echo, mix: rrand(0.4,0.8) do
if veggies.include? a and meat_.include? b or meat_.include? c
sample [:perc_snap2,:perc_swash,:perc_swoosh].choose, pitch: dice(10), sustain: 4
end
end
sleep [0.25,0.5,0.75].choose
end
#Begin
In One Version Used
#Baseline
with_fx :distortion do
live_loop :damage do
with_fx :echo , mix: 0.7 do
use_bpm 15
sample :perc_snap if spread(5,12).tick
play_pattern_timed chord(:E3, :minor), [0.4, 0.7]
end
sleep 2
end
end
#End
live_loop :meatveggiegroup do
use_real_time
a, b, c, = sync "/osc*/pattern1"
toppings = [a,b,c] #from what was call via osc
with_fx :flanger, mix: rrand(0.1,0.9) do
if meat_.include? a or meat_.include? b and vegeterian.include? c
sample [:tabla_dhec, :table_ghe2, :tabla_ghe3].choose, beat_stretch: 12 if spread(9,12).tick
end
end
with_fx :ping_pong, mix: rrand(0.3,0.75) do
if meat_.include? a or meat_.include? c or vegeterian.include? b
sample [:elec_blip, :elec_beep,:elec_flip].choose, pitch: dice(10), sustain: 2
end
end
with_fx :echo, mix: rrand(0.4,0.8) do
if veggies.include? a and meat_.include? b or meat_.include? c
sample [:ambi_drone,:ambi_glass_hum, :ambi_glass_rub].choose, pitch: dice(10), sustain: 4
end
end
sleep [0.25,0.5,0.75].choose
end