123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- from pygame import mixer
- import time
- import digitalio
- import board
- import adafruit_matrixkeypad
- import pygame
- from PIL import Image, ImageDraw, ImageFont
- import adafruit_rgb_display.st7789 as st7789
- import digitalio
- import board
- from adafruit_rgb_display.rgb import color565
- import adafruit_rgb_display.st7789 as st7789
- import lib.FSM
- from itertools import cycle
- import lib.observer
- from scikits.samplerate import resample
- from lib.configobj import ConfigObj
- #from configobj import ConfigObj
-
-
-
- cols = [digitalio.DigitalInOut(x) for x in (board.D21, board.D20, board.D16, board.D12)]
- rows = [digitalio.DigitalInOut(x) for x in (board.D26, board.D13, board.D6, board.D5)]
- # keys = ((3, 2, 1, 0),
- # (7, 6, 5, 4),
- # (11, 10, 9, 8),
- # (15, 14, 13, 12))
-
- keys = ((15, 14, 13, 12),
- (11, 10, 9, 8),
- (7, 6, 5, 4),
- (3, 2, 1, 0))
-
-
- keypad = adafruit_matrixkeypad.Matrix_Keypad(rows, cols, keys)
-
- # while True:
- # keys = keypad.pressed_keys
- # if keys:
- # print("Pressed: ", keys)
- # time.sleep(0.1)
-
-
-
-
- pygame.init()
- mixer.init()
- done = False
- clock = pygame.time.Clock()
- TIMER = pygame.USEREVENT + 1
- #pygame.time.set_timer(pygame.USEREVENT + 1, 444)
- #pygame.time.set_timer(TIMER, 161)
- playhead = 0
-
- timer = pygame.time.get_ticks
- start = now = timer()
-
- cs_pin = digitalio.DigitalInOut(board.CE0)
- dc_pin = digitalio.DigitalInOut(board.D25)
- reset_pin = None
- BAUDRATE = 64000000 # The pi can be very fast!
- # display = st7789.ST7789(
- # board.SPI(),
- # cs=cs_pin,
- # dc=dc_pin,
- # rst=reset_pin,
- # baudrate=BAUDRATE,
- # width=135,
- # height=240,
- # x_offset=53,
- # y_offset=40,
- # )
-
- backlight = digitalio.DigitalInOut(board.D22)
- backlight.switch_to_output()
- backlight.value = True
- buttonA = digitalio.DigitalInOut(board.D23)
- buttonB = digitalio.DigitalInOut(board.D24)
- buttonA.switch_to_input()
- buttonB.switch_to_input()
-
- spi = board.SPI()
-
-
-
- # Create blank image for drawing.
- # Make sure to create image with mode 'RGB' for full color.
-
- # Get drawing object to draw on image.
-
-
- # Draw a black filled box to clear the image.
- #draw.rectangle((0, 0, width, height), outline=0, fill=(0, 0, 0))
- #disp.image(image, rotation)
- # Draw some shapes.
- # First define some constants to allow easy resizing of shapes.
-
- # Move left to right keeping track of the current x position for drawing shapes.
- x = 0
-
-
-
- # Turn on the backlight
- backlight = digitalio.DigitalInOut(board.D22)
- backlight.switch_to_output()
- backlight.value = True
-
-
- class Prog:
- def __init__(self):
- self.FSM = FSM.ProgFSM(self)
- self.font = ImageFont.truetype("/home/pi/examples/HLM.ttf", 64)
- #self.h1 = ImageFont.truetype("/home/pi/examples/HLM.ttf", 26)
- self.h1 = ImageFont.truetype("/home/pi/Pixellari.ttf", 30)
- self.h2 = ImageFont.truetype("/home/pi/Pixellari.ttf", 20)
- self.h3 = ImageFont.truetype("/home/pi/Pixellari.ttf", 54)
-
- self.disp = st7789.ST7789(
- spi,
- cs=cs_pin,
- dc=dc_pin,
- rst=reset_pin,
- baudrate=BAUDRATE,
- width=135,
- height=240,
- x_offset=53,
- y_offset=40,
- )
-
- self.height = self.disp.width # we swap height/width to rotate it to landscape!
- self.width = self.disp.height
-
- self.rotation = 270
- self.padding = -2
- self.top = self.padding
- self.bottom = self.height - self.padding
-
- self.image = Image.new("RGB", (self.width, self.height))
- self.draw = ImageDraw.Draw(self.image)
- self.playhead = 0
- self.playing = False
- self.bpm = 90
- self.bpm_inc = 1
- self.note_bank = 0
- self.volume = 10
- self.note_vol = 16
- self.note_pitch = 0.0
- self.soundSlots = []
- self.keys = []
- self.keyState = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
- #self.song = [2, 3, 0, 1, 0, 1, 0, 1, 0, 1]
- self.song = [0]
- self.songCycle = cycle(self.song)
- self.curPattern = next(self.songCycle)
- self.songStart = self.curPattern
- self.eSound = 0
- self.ePattern = 0
- self.black = "#000000"
- self.bg_color = "#336699"
- self.color_a = "#FFFFFF"
- self.color_b = "#929230"
- self.color_c = "#FFFF00"
- self.dark_grey = "#404040"
- self.grey = "#808080"
- self.light_grey = "#D3D3D3"
- self.blue = "#2A80D5"
- self.dark_blue = "#2A2AD5"
- self.pink = "#D52A80"
- self.red = "#D52A2A"
- self.olive = "#80D52A"
- self.green = "#2AD52A"
-
- self.pub = observer.Publisher(['beat', 'the joint'])
-
- self.song_file_name = "default.sng"
- self.config = ConfigObj("config.txt")
- self.config['title'] = "default"
- self.config['bpm'] = self.bpm
- self.config['volume'] = self.volume
- self.config.write()
-
- #self.save_song()
-
- class SoundSlot:
- def __init__(self, file, obj_id, o):
- self.file = file
- self.id = obj_id
- self.o = o
- self.mixerSound = pygame.mixer.Sound(self.file)
- self.pattern = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]
- self.notes = self.init_notes()
- self.pitch = 0.0
- self.volume = 16
-
-
- def play(self, vol, pitch):
- # snd_array = pygame.sndarray.array(self.mixerSound)
- # snd_resample = resample(snd_array, 2.5, "sinc_fastest").astype(snd_array.dtype)
- # snd_out = pygame.sndarray.make_sound(snd_resample)
- # snd_out.play()
-
- if vol != 0:
- vol = (vol / 16) * (self.volume / 16) * (self.o.volume / 16)
- self.mixerSound.set_volume(vol)
-
- pygame.mixer.Sound.play(self.mixerSound)
-
-
- def init_notes(self):
- outp = []
- _id = 0
- while _id < 64:
- outp2 = []
- _id2 = 0
- while _id2 < 64:
- outp2.append([0,16,0])
- _id2 += 1
- outp.append(outp2)
- _id += 1
-
- # for n in outp:
- # print('sound ', self.id, ' ', n)
- #print(outp)
-
- return outp
-
-
- def Execute(self):
- #print('doing the thing')
- #self.check_buttons()
- self.keys = keypad.pressed_keys
- #self.key_flip()
- self.update_keys()
- self.FSM.Execute()
- #self.disp.image(self.image, self.rotation)
-
- def update_keys(self):
- _id = 0
- for k in self.keyState:
- if k == 0:
- if _id in self.keys:
- self.keyState[_id] = 1
-
- elif k == 1:
- if _id in self.keys:
- self.keyState[_id] = 2
- else:
- self.keyState[_id] = 3
-
- elif k == 2:
- if _id in self.keys:
- self.keyState[_id] = 2
- else:
- self.keyState[_id] = 3
-
- else:
- self.keyState[_id] = 0
-
-
- _id += 1
-
- if buttonA.value == 0:
- #print('a on `', self.keyState[16])
- if self.keyState[16] == 0:
- self.keyState[16] = 1
- elif self.keyState[16] == 1:
- self.keyState[16] = 2
- else:
- self.keyState[16] = 2
- else:
- if self.keyState[16] == 3:
- self.keyState[16] = 4
- elif self.keyState[16] == 2:
- self.keyState[16] = 3
- elif self.keyState[16] == 4:
- self.keyState[16] = 0
-
- if buttonB.value == 0:
- #print('a on `', self.keyState[16])
- if self.keyState[17] == 0:
- self.keyState[17] = 1
- elif self.keyState[17] == 1:
- self.keyState[17] = 2
- else:
- self.keyState[17] = 2
- else:
- if self.keyState[17] == 3:
- self.keyState[17] = 4
- elif self.keyState[17] == 2:
- self.keyState[17] = 3
- elif self.keyState[17] == 4:
- self.keyState[17] = 0
-
- # if buttonB.value == 0:
- # #print('b on')
- # if self.keyState[17] == 0 or self.keyState[17] == 1:
- # self.keyState[17] += 1
- # else:
- # if self.keyState[17] == 2:
- # self.keyState[17] += 1
- # else:
- # self.keyState[17] = 0
-
- def update_bpm(self):
- bpm = (60000 / self.bpm) / 4
- pygame.time.set_timer(TIMER, int(bpm))
-
- def start_playback(self):
- self.playing = True
- self.playhead = -1
- self.curPattern = self.songStart
- bpm = (60000 / self.bpm) / 4
- pygame.time.set_timer(TIMER, int(bpm))
-
-
- def stop_playback(self):
- self.playing = False
- self.playhead = -1
- self.curPattern = self.songStart
- pygame.time.set_timer(TIMER, 0)
-
- def center_text(self, text, font, width, y, color):
- w,h = font.getsize(text)
- self.draw.text(((width-w)/2,(y-h)/2), text, font=font, fill=color)
-
- def center_block(self, message, font, bounding_box, color):
- x1, y1, x2, y2 = bounding_box # For easy reading
- w, h = self.draw.textsize(message, font=font)
- x = (x2 - x1 - w)/2 + x1
- y = (y2 - y1 - h)/2 + y1
- self.draw.text((x, y), message, align='center', font=font, fill=color)
-
-
- def save_song(self):
- base_dir = "/home/pi/zpc_ct/user/songs/"
- #self.song_file_name
- #file1 = open(base_dir + self.song_file_name,"w")#write mode
- #file1.write("Tomorrow \n")
- #file1.close()
- self.config = ConfigObj(base_dir + self.song_file_name)
- self.config['title'] = "default"
- self.config['bpm'] = self.bpm
- self.config['volume'] = self.volume
- sounds = []
- notes = []
- for x in self.soundSlots:
- sounds.append(x.file)
- notes.append(x.notes)
- self.config['sounds'] = sounds
- self.config['notes'] = notes
- self.config['volumes'] = ['this', 'that', 'the other']
- self.config.write()
-
- def load_song(self):
- base_dir = "/home/pi/zpc_ct/user/songs/"
- self.config = ConfigObj(base_dir + 'r100.sng')
- #self.config = ConfigObj(base_dir + self.song_file_name)
- #print('these sounds should get loaded ', self.config['sounds'])
-
-
- p = Prog()
-
- #while True:
-
- while not done:
- p.Execute()
- if pygame.event.get(pygame.USEREVENT + 1):
- p.playhead += 1
-
- if p.playhead == 16:
- p.playhead = 0
- #self.draw.text((0, 0), str(self.playhead), font=font, fill="#FFFFFF")
-
- #self.disp.image(self.image, self.rotation)
- p.curPattern = next(p.songCycle)
- print('pattern ', p.curPattern)
- p.pub.dispatch('beat', [p.curPattern, p.playhead])
- #clock.tick(240)
- clock.tick_busy_loop()
- #print(clock.get_fps())
-
- pygame.quit()
-
- # 1 main
- # 2 select pattern
- # 3 note edit
- # 6 song edit
- # 7 program load
- # 8 song load
- # 10 utility
- # 11 bpm+
- # 12 bpm-
- # 13 play
- # 14 stop
- # 15 vol+
- # 16 vol-
|