Esempio n. 1
0
 def init_piano(self):
     keymap_filename = 'pianoeletronico.kmp'
     notes_manager = NotesManager()
     notes_manager.load_file(util.app_file_path(os.path.join('keymaps', keymap_filename)))
     self.midi = midi.Midi()
     self.midi_output = midi.Output(self.midi.get_default_output_id(), 0)
     self.piano = Piano(notes_manager, self.midi_output)
     self.piano.set_instrument(0, 0)
Esempio n. 2
0
    def __init__(self, ui=None, track=None, width=None, height=None, x=0, y=0):
        self.ui = ui
        # Offset on left side, leaving space for timestamps
        self.offset = len("00:00.000 ")
        if self.ui != None:
            logger.log("Using ui")
            self.height, self.width = list(map(int, self.ui.size()))
            self.width -= self.offset
        else:
            logger.log("Not using ui")
            self.height, self.width = 10, 10
        self.cursorY = self.height / 2
        self.cursorX = 44
        self.track = track
        self.bpm = self.track.beatsPerMinute
        self.tpb = self.track.ticksPerBeat
        self.seconds = 60.0 / self.tpb / self.bpm

        #Begin and end using real time
        #self.length = self.track.getLengthInSec()
        #self.begin = 0.0
        #self.end = (self.height-1) * 60.0 / self.bpm
        #self.step = 60.0 / self.bpm
        #Begin and end using beats
        self.length = self.track.getLengthInBeats()
        self.begin = 0
        self.end = self.height - 1
        self.step = 1

        logger.log("Track's length: %.2f beats" % self.length)

        self.beats = []
        for i in range(int(self.track.getLengthInBeats() + 1)):
            self.beats.append([])
        logger.log("width = %d" % self.width)
        ## Create display window
        if self.width > KEYS:
            displayWidth = KEYS + self.offset
        else:
            displayWidth = self.width + self.offset
            MIN = (KEYS - self.width) / 2
            MAX = (KEYS - self.width) / 2 + self.width
        if self.ui != None:
            self.display = self.ui.newWindow(self.height, displayWidth,
                                             "display", x, y)
            self.ui.setWindow(self.display)

        ## Connect to Piano
        self.piano = Piano()
        self.player = Player()
        self.player.start()
        self.player.setPiano(self.piano)
        self.piano.autoconnect()
        self.playing = False

        ## Create metronome
        beatLength = 60.0 / self.bpm
        self.metronome = Metronome(self.down, beatLength)
Esempio n. 3
0
 def __init__(self):
     self.screen_size = (1366, 768)  # (width, height)
     self.camera_size = (640, 480)  # (width, height)
     self.key_quit = 'q'
     self.aruco_dict = cv2.aruco.getPredefinedDictionary(
         cv2.aruco.DICT_ARUCO_ORIGINAL)
     self.update_piano_corners_freq = 5  # Number of frames to update piano corners
     self.img_to_project = np.zeros(
         (self.camera_size[1], self.camera_size[0], 3), np.uint8)
     # self.display = Display(screen_width=self.screen_size[0])
     self.piano = Piano()
     self.cam_to_proj = None  # Transformation from camera to projector coordinates
     self.song = [
         "C#4", "C4", "F#5", "B4", "G5", "E5", "E5", "br", "F5", "D5", "D5",
         "br", "C5", "D5", "E5", "F5", "G5", "G5", "G5", "br", "G5", "E5",
         "E5", "br", "F5", "D5", "D5", "br", "C5", "E5", "G5", "G5", "C5"
     ]
Esempio n. 4
0
    def __init__(self):
        pygame.init()
        self.screen = glblit.initializeDisplay(*WINSIZE)
        self.screen_rect = self.screen.get_rect()
        pygame.display.set_caption('Piano Center')

        screen = pygame.Surface(WINSIZE)
        # menu
        MenuSystem.init(screen)
        MenuSystem.BGCOLOR = Color(200,200,200, 255)
        MenuSystem.FGCOLOR = Color(0, 0, 0, 0)
        MenuSystem.BGHIGHTLIGHT = Color(40,40,40,40)
        MenuSystem.BORDER_HL = Color(200,200,200,200)

        self.track_button_height = 20
        self.track_button_width = 30
        self.piano_info_bar_gap = 2

        self.menu_bar = MenuSystem.MenuBar(top=5)
        menus_in_bar, self.midi_filename_data = get_menu_data()
        self.menu_bar.set(menus_in_bar)
        self.menu_bar_info = MenuSystem.MenuBar(top=self.screen_rect.height - self.menu_bar.lineheigth)
        self.piano = Piano(screen, WINSIZE,
                           top=self.menu_bar_info.top - self.piano_info_bar_gap)

        self.piano.init_piano()
        self.piano.draw_vertical_staff_lines(self.screen_rect.height * 0.618)

        self.staff_top = self.menu_bar.top + self.menu_bar.lineheigth + self.track_button_height

        self.sounds = {}
        self.enabled_tracks_switch = {}

        self.midi_filename_idx = 0
        if len(self.midi_filename_data) > 0:
            self.midi_filename = self.midi_filename_data[self.midi_filename_idx]

        self.load_resource(self.midi_filename)
Esempio n. 5
0
 def init_piano(self):
     self.create_midi_driver()
     self.piano = Piano(self.config.get_keymap_file_path('pianoeletronico.kmp'), self.midi_output)
     self.active_channels.append(0)
     self.piano.set_instrument(0, 0)
Esempio n. 6
0
class PianoApp(wx.App):
    config = None
    functions_keymap = {}
    multi_voice = False
    active_channels = []
    current_channel = 0

    def OnInit(self):
        try:
            self.load_config()
            self.init_piano()
            self.init_ui()
            return True
        except UserError as user_error:
            wx.MessageBox(str(user_error), 'Erro', wx.OK | wx.ICON_ERROR)
            return False

    def load_config(self):
        self.config = Config(app.config_file_path())

    def init_piano(self):
        self.create_midi_driver()
        self.piano = Piano(self.config.get_keymap_file_path('pianoeletronico.kmp'), self.midi_output)
        self.active_channels.append(0)
        self.piano.set_instrument(0, 0)

    def create_midi_driver(self):
        midi_output_factory = MidiOutputFactory()
        midi_output_driver = self.config.get_midi_output_driver(constants.MIDI_OUTPUT_DEFAULT_DRIVER)
        if midi_output_driver >= constants.MIDI_OUTPUT_DEFAULT_DRIVER:
            self.midi_output = midi_output_factory.factory_pygame(midi_output_driver )
        elif midi_output_driver == constants.MIDI_OUTPUT_FLUIDSYNTH_DRIVER:
            self.midi_output = midi_output_factory.factory_fluidsynth(self.config.get_soundfont_file_path())
        else:
            raise UserError('Erro de configuração: MIDI driver inexistente')

    def init_ui(self):
        self.mainFrame = wx.Frame(parent = None, id = -1, title = 'Virtual Piano')
        self.mainFrame.Bind(wx.EVT_KEY_DOWN, self.on_key_down)
        self.mainFrame.Bind(wx.EVT_KEY_UP, self.on_key_up)
        self.functions_keymap = {
            wx.WXK_RIGHT: lambda evt: self.piano.next_instrument(self.current_channel),
            wx.WXK_LEFT: lambda evt: self.piano.previous_instrument(self.current_channel),
            wx.WXK_UP: lambda evt: self.tone_change_up(evt),
            wx.WXK_DOWN: lambda evt: self.tone_change_down(evt),
            wx.WXK_PAGEUP: lambda evt: self.next_channel(),
            wx.WXK_PAGEDOWN: lambda evt: self.previous_channel(),
            wx.WXK_DELETE: lambda evt: self.delete_current_channel(),
            wx.WXK_F2: lambda evt: self.select_instrument_by_number(self.current_channel),
            wx.WXK_F8: lambda evt: self.piano.volume_down(self.current_channel),
            wx.WXK_F9: lambda evt: self.piano.volume_up(self.current_channel),
            wx.WXK_BACK: self.toggle_multi_voice,
            wx.WXK_TAB: self.pan,
        }
        self.mainFrame.Show(True)

    def on_key_down(self, evt):
        key = evt.GetKeyCode()
        if key in self.functions_keymap:
            self.functions_keymap[key](evt)
        if self.multi_voice:
            for channel_number in self.active_channels:
                note = self.get_note_from_key_event(evt, channel_number)
                if note is not None:
                    self.piano.note_on(note, channel_number)
        else:
            note = self.get_note_from_key_event(evt, self.current_channel)
            if note is not None:
                self.piano.note_on(note, self.current_channel)

    def on_key_up(self, evt):
        if self.multi_voice:
            for channel_number in self.active_channels:
                note = self.get_note_from_key_event(evt, channel_number)
                if note is not None:
                    self.piano.note_off(note, channel_number)
        else:
            note = self.get_note_from_key_event(evt, self.current_channel)
            if note is not None:
                self.piano.note_off(note, self.current_channel)

    def get_note_from_key_event(self, evt, channel_number):
        key = evt.GetUnicodeKey()
        if key != wx.WXK_NONE:
            if key > 127:
                key = char.unicode_workaround(chr(key).encode('utf-8'))
            return self.piano.get_note(key, channel_number)

    def toggle_multi_voice(self, evt):
        self.piano.all_notes_off()
        self.multi_voice = not self.multi_voice

    def pan(self, evt):
        back = True if evt.GetModifiers() == wx.MOD_SHIFT else False
        self.piano.pan(back, self.current_channel)

    def next_channel(self):
        if self.current_channel == 15:
            return
        self.piano.all_notes_off()
        self.current_channel += 1
        if not self.current_channel in self.active_channels:
            self.active_channels.append(self.current_channel)
            self.piano.get_channel(self.current_channel)

    def previous_channel(self):
        if self.current_channel == 0:
            return
        self.piano.all_notes_off()
        self.current_channel -= 1

    def delete_current_channel(self):
        self.piano.delete_channel(self.current_channel)
        self.active_channels.remove(self.current_channel)
        self.current_channel -= 1

    def tone_change_up(self, evt):
        key_modifier = evt.GetModifiers()
        if key_modifier ==  wx.MOD_SHIFT:
            self.piano.semitone_up(1, self.current_channel)
        else:
            self.piano.octave_up(self.current_channel)

    def tone_change_down(self, evt):
        key_modifier = evt.GetModifiers()
        if key_modifier ==  wx.MOD_SHIFT:
            self.piano.semitone_down(1, self.current_channel)
        else:
            self.piano.octave_down(self.current_channel)

    def select_instrument_by_number(self, target_channel):
        current_instrument = str(self.piano.get_instrument_for_channel(target_channel) + 1)
        pressed_ok, selected_instrument = edit_dialog(self.mainFrame, "Instrument", "Enter instrument number for channel %d (from 1 to 128):" % target_channel, current_instrument)
        if pressed_ok:
            try:
                instrument_number = int(selected_instrument) - 1
            except ValueError:
                message_dialog(self.mainFrame, "Error", "Instrument not a number")
                return
            if instrument_number < 0 or instrument_number > 127:
                message_dialog(self.mainFrame, "Error", "Instrument number not in range from 1 to 128")
                return
            self.piano.set_instrument(instrument_number, target_channel)
Esempio n. 7
0
from sys import argv

import mido
from piano import Piano
from recorder import Recorder
from player import Player
from button import Button

## Setup Piano
piano = Piano()
[ins, outs] = piano.listDevices()
if "-i" in argv:
    print("[+] List of input devices")
    for i in range(len(ins)):
        print("%d: %s" % (i + 1, ins[i]))
    inDev = ins[int(input("Select input device: ")) - 1]
else:
    inDev = mido.get_input_names()[0]

if "-o" in argv:
    print("[+] List of output devices")
    for i in range(len(outs)):
        print("%d: %s" % (i + 1, outs[i]))
    outDev = ins[int(input("Select output device: ")) - 1]
else:
    outDev = mido.get_output_names()[0]
piano.connect(inDev, outDev)

## Setup Recorder
rec = Recorder()
if not rec.setPiano(piano):
"""
Generates wav file using PySynth:
https://mdoege.github.io/PySynth/#s
"""
import os
import pysynth
from piano import Piano

output_folder = "wav"

key_list = Piano().key_list

if not os.path.exists(output_folder):
    os.makedirs(output_folder)

for key in key_list:
    print("Generating %s" % key['note'])
    note_str = key['note'].lower()
    pysynth.make_wav([[note_str, 4]],
                     fn=os.path.join(output_folder, "%s.wav" % key['note']))
Esempio n. 9
0
import cv2
from piano import Piano
from threading import Thread

piano = Piano()

def playMusic(event, x, y, flags, params):
  if event == cv2.EVENT_MOUSEMOVE:
    Thread(target=piano.press, args=(x,y,)).start()
    # key = piano.press(x, y)
    # if key is not None:
    #   print(key+1)


def main():
  vid = cv2.VideoCapture(0)

  while True:
    cv2.namedWindow("Piano")
    ret, frame = vid.read()
    piano.display(frame)
    frame = cv2.flip(frame, 1)
    cv2.setMouseCallback("Piano", playMusic)
    cv2.imshow("Piano", frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
      break

  vid.release()
  cv2.destroyAllWindows()
Esempio n. 10
0
from piano import Piano
from time import sleep
p = Piano()
[ins,outs] = p.listDevices()
print("[+] List of input devices")
for i in range(len(ins)):
    print("%d: %s"%(i+1,ins[i]))
inDev = ins[int(input("Select input device: "))-1]

print("[+] List of output devices")
for i in range(len(ins)):
    print("%d: %s"%(i+1,outs[i]))
outDev = ins[int(input("Select output device: "))-1]

print("Testing Send()")
if p.connect(inDev,outDev):
    p.send(50,80)
print("Testing Receive(). Press a key on the piano")
print(p.receive())
called = lambda x:exit()
p.setCallback(called)
print("Testing callback. Press a key on the piano")
while 1:
    sleep(0.1)
    pass
Esempio n. 11
0
class Display:
    def __init__(self, ui=None, track=None, width=None, height=None, x=0, y=0):
        self.ui = ui
        # Offset on left side, leaving space for timestamps
        self.offset = len("00:00.000 ")
        if self.ui != None:
            logger.log("Using ui")
            self.height, self.width = list(map(int, self.ui.size()))
            self.width -= self.offset
        else:
            logger.log("Not using ui")
            self.height, self.width = 10, 10
        self.cursorY = self.height / 2
        self.cursorX = 44
        self.track = track
        self.bpm = self.track.beatsPerMinute
        self.tpb = self.track.ticksPerBeat
        self.seconds = 60.0 / self.tpb / self.bpm

        #Begin and end using real time
        #self.length = self.track.getLengthInSec()
        #self.begin = 0.0
        #self.end = (self.height-1) * 60.0 / self.bpm
        #self.step = 60.0 / self.bpm
        #Begin and end using beats
        self.length = self.track.getLengthInBeats()
        self.begin = 0
        self.end = self.height - 1
        self.step = 1

        logger.log("Track's length: %.2f beats" % self.length)

        self.beats = []
        for i in range(int(self.track.getLengthInBeats() + 1)):
            self.beats.append([])
        logger.log("width = %d" % self.width)
        ## Create display window
        if self.width > KEYS:
            displayWidth = KEYS + self.offset
        else:
            displayWidth = self.width + self.offset
            MIN = (KEYS - self.width) / 2
            MAX = (KEYS - self.width) / 2 + self.width
        if self.ui != None:
            self.display = self.ui.newWindow(self.height, displayWidth,
                                             "display", x, y)
            self.ui.setWindow(self.display)

        ## Connect to Piano
        self.piano = Piano()
        self.player = Player()
        self.player.start()
        self.player.setPiano(self.piano)
        self.piano.autoconnect()
        self.playing = False

        ## Create metronome
        beatLength = 60.0 / self.bpm
        self.metronome = Metronome(self.down, beatLength)

    def createList(self):
        skip = []
        t = 0.0
        n = 0
        for i in range(len(self.track.track)):
            t += self.track.track[i].time * self.seconds
            if self.track.track[i].type == "note_on":
                if i in skip:
                    skip.remove(i)
                else:
                    msg = self.track.track[i]
                    note = msg.note
                    length = 0
                    j = i + 1
                    ## Find closing msg
                    while j != len(self.track.track):
                        ## accumulate times
                        length += self.track.track[j].time
                        if self.track.track[j].type == "note_on":
                            if self.track.track[j].note == note:
                                ## put on list to skip
                                skip.append(j)
                                break
                        j += 1
                    length *= self.seconds
                    beats = length * self.bpm / 60.0
                    beatZero = int(round(t / 60.0 * self.bpm))
                    for k in range(int(beats + 1)):
                        # Append a list [note, first beat of the note
                        self.beats[beatZero + k].append([i, k == 0])
        if self.ui == None:
            for beat in beats:
                print(list(map(beat, note2char)))

    ## Display notes with length
    def putStrXY(self, x, y, txt, colorPair=272):
        self.ui.setColorPair(colorPair)
        self.ui.putStrXY(self.offset + x, y, txt)

    def timeStamp(self, y, timeStamp):
        self.ui.setColorPair(50)
        self.ui.putStrXY(0, y, timeStamp)

    def update(self):
        self.putStrXY(0, self.cursorY - self.begin, " " * ((MAX - MIN) / 1))
        self.putStrXY(self.cursorX, self.cursorY - self.begin, "+", 2)
        for beat in range(self.begin, self.end + 1):
            y = beat - self.begin
            seconds = 60.0 * beat / self.bpm
            minutes = int(seconds / 60)
            seconds = seconds % 60
            milisec = int(1000 * (seconds - int(seconds)))
            self.timeStamp(y,
                           "%02d:%2d.%03d" % (minutes, int(seconds), milisec))
            for [idx, first] in self.beats[beat]:
                note = self.track.track[idx].note
                x = MIN if note < MIN else MAX if note > MAX else note
                x -= MIN
                if self.ui != None:
                    color = 262
                    if self.cursorY == y + self.begin and self.cursorX == x:
                        logger.log("update() - beat = %d" % beat)
                        logger.log("update() - cursorY = %d" % self.cursorY)
                        color = 282
                    if first:
                        self.putStrXY(x, y, "O", color)
                    else:
                        self.putStrXY(x, y, "|", color)
        self.ui.refresh()

    def quit(self):
        self.player.stop()
        self.metronome.stop()

    def enter(self):
        self.playing = self.playing == False
        ## Play
        if self.playing:
            logger.log("enter() - Play")
            beat = self.cursorY
            first = False
            while not first:
                for idx, first in self.beats[beat]:
                    if first:
                        break
                beat += 1
            track = self.track.subTrack(idx)
            self.player.setTrack(track)

            self.player.play()
            self.metronome.play()
        ## Stop
        else:
            logger.log("enter() - Pause")
            self.player.pause()
            self.metronome.pause()
            self.player.clearTrack()
        note = self.cursorX

    def up(self):
        self.cursorY = max(0, self.cursorY - 1)
        logger.log("Up. cursorY = %d" % self.cursorY)
        if self.cursorY < self.height / 2 + self.begin:
            self.begin -= self.step
            if self.begin < 0:
                self.begin += self.step
            else:
                self.end -= self.step

    def down(self):
        self.cursorY = min(self.length - 2, self.cursorY + 1)
        logger.log("Down. cursorY = %d" % self.cursorY)
        if self.cursorY > self.height / 2 + self.begin:
            self.end += self.step
            if self.end > self.length:
                self.end -= self.step
            else:
                self.begin += self.step

    def left(self):
        self.cursorX = max(0, self.cursorX - 1)

    def right(self):
        self.cursorX = min(87, self.cursorX + 1)

    def pgup(self):
        for i in range(10):
            self.up()

    def pgdown(self):
        for i in range(10):
            self.down()
Esempio n. 12
0
 def __init__(self, midi_brain):
     Piano.__init__(self, midi_brain)
     
     size = (200,200)
     self.screen = pygame.display.set_mode(size)
     self.screen.fill(black)
Esempio n. 13
0
class PlayCenter():
    def __init__(self):
        pygame.init()
        self.screen = glblit.initializeDisplay(*WINSIZE)
        self.screen_rect = self.screen.get_rect()
        pygame.display.set_caption('Piano Center')

        screen = pygame.Surface(WINSIZE)
        # menu
        MenuSystem.init(screen)
        MenuSystem.BGCOLOR = Color(200,200,200, 255)
        MenuSystem.FGCOLOR = Color(0, 0, 0, 0)
        MenuSystem.BGHIGHTLIGHT = Color(40,40,40,40)
        MenuSystem.BORDER_HL = Color(200,200,200,200)

        self.track_button_height = 20
        self.track_button_width = 30
        self.piano_info_bar_gap = 2

        self.menu_bar = MenuSystem.MenuBar(top=5)
        menus_in_bar, self.midi_filename_data = get_menu_data()
        self.menu_bar.set(menus_in_bar)
        self.menu_bar_info = MenuSystem.MenuBar(top=self.screen_rect.height - self.menu_bar.lineheigth)
        self.piano = Piano(screen, WINSIZE,
                           top=self.menu_bar_info.top - self.piano_info_bar_gap)

        self.piano.init_piano()
        self.piano.draw_vertical_staff_lines(self.screen_rect.height * 0.618)

        self.staff_top = self.menu_bar.top + self.menu_bar.lineheigth + self.track_button_height

        self.sounds = {}
        self.enabled_tracks_switch = {}

        self.midi_filename_idx = 0
        if len(self.midi_filename_data) > 0:
            self.midi_filename = self.midi_filename_data[self.midi_filename_idx]

        self.load_resource(self.midi_filename)


    def get_menus_info_bar(self):
        gen_menu_data = []
        # gen_menu_data += ["Metro: %.1f" % player.g_metronome_volume]
        gen_menu_data += ["Time: %d/%d" % (parse_midi.g_time_signature_n, parse_midi.g_time_signature_note)]
        gen_menu_data += ["Temp: %d" % (60000 / parse_midi.g_mseconds_per_quarter)]
        gen_menu_data += ["Playing: %s" % self.midi_filename.replace(".midi", "").replace(".mid", "")]

        return [MenuSystem.Menu(m, ()) for m in gen_menu_data]


    def load_resource(self, midi_filename):
        print midi_filename
        try:
            self.all_midi_lines, self.notes_in_all_staff, self.enabled_tracks, self.tracks_order_idx = parse_midi.load_midi(midi_filename)
            self.all_midi_lines_length = len(self.all_midi_lines)
        except Exception, e:
            print "midi error:", e
            if midi_filename in self.midi_filename_data:
                self.midi_filename_data.remove(midi_filename)
            return

        self.piano.timestamp_range = TIMESTAMP_RANGE * parse_midi.g_ticks_per_quarter / parse_midi.g_mseconds_per_quarter
        self.piano.timestamp_range = self.piano.timestamp_range * self.piano.staff_space_height_base / self.piano.staff_space_height

        if midi_filename in self.midi_filename_data:
            self.midi_filename_idx = self.midi_filename_data.index(midi_filename)
            self.midi_filename = midi_filename
        else:
            print "impossible: file not in menu list"
            return

        # draw track pick
        self.piano.screen.fill(self.piano.color_backgroud,
                               pygame.Rect(0, self.menu_bar.top + self.menu_bar.lineheigth,
                                           self.screen_rect.width, self.track_button_height-1))
        for track_idx, idx in self.tracks_order_idx.items():
            if track_idx in self.enabled_tracks_switch:
                sw = self.enabled_tracks_switch[track_idx]
                sw.left = idx * self.track_button_width
            else:
                sw = pygame.Rect(idx * self.track_button_width, self.menu_bar.top + self.menu_bar.lineheigth,
                                 self.track_button_width - 1, self.track_button_height-1)
                self.enabled_tracks_switch[track_idx] = sw

            note_color = self.piano.TRACK_COLORS[idx % len(self.piano.TRACK_COLORS)]
            self.piano.screen.fill(note_color, sw)

        # finish missing sounds
        player.load_sounds([(midi_data[1], midi_data[2]) for midi_data in self.all_midi_lines],
                           self.sounds)
        self.piano.reset_piano()
        self.chord_keys_bound = []
        self.play_commands = []
        self.midi_cmd_idx = 0
        self.staff_offset_x = 0
        self.midi_repeat_count = 0
        self.last_timestamp = -1
        self.is_pause = True
        self.play_one_timestamp_while_paused = False
        self.menu_bar_info.set(self.get_menus_info_bar())
Esempio n. 14
0
class PianoApp(wx.App):
    functions_keymap = {}
    multi_voice = False

    def OnInit(self):
        self.init_piano()
        self.init_ui()
        return True

    def init_piano(self):
        keymap_filename = 'pianoeletronico.kmp'
        notes_manager = NotesManager()
        notes_manager.load_file(util.app_file_path(os.path.join('keymaps', keymap_filename)))
        self.midi = midi.Midi()
        self.midi_output = midi.Output(self.midi.get_default_output_id(), 0)
        self.piano = Piano(notes_manager, self.midi_output)
        self.piano.set_instrument(0, 0)

    def init_ui(self):
        self.mainFrame = wx.Frame(parent = None, id = -1, title = 'Virtual Piano')
        self.Bind(wx.EVT_KEY_DOWN, self.on_key_down)
        self.Bind(wx.EVT_KEY_UP, self.on_key_up)
        self.functions_keymap = {
            wx.WXK_RIGHT: lambda evt: self.piano.next_instrument(),
            wx.WXK_LEFT: lambda evt: self.piano.previous_instrument(),
            wx.WXK_UP: lambda evt: self.piano.octave_up(),
            wx.WXK_DOWN: lambda evt: self.piano.octave_down(),
            wx.WXK_PAGEUP: lambda evt: self.piano.next_channel(),
            wx.WXK_PAGEDOWN: lambda evt: self.piano.previous_channel(),
            wx.WXK_DELETE: lambda evt: self.piano.delete_current_channel(),
            wx.WXK_F8: lambda evt: self.piano.volume_down(),
            wx.WXK_F9: lambda evt: self.piano.volume_up(),
            wx.WXK_BACK: self.toggle_multi_voice,
            wx.WXK_TAB: self.pan,
        }
        self.mainFrame.Show(True)

    def on_key_down(self, evt):
        note = self.get_note_from_key_event(evt)
        if note is None:
            key = evt.GetKeyCode()
            if key in self.functions_keymap:
                self.functions_keymap[key](evt)
        else:
            if self.multi_voice:
                self.piano.note_on_multi(note)
            else:
                self.piano.note_on(note)

    def on_key_up(self, evt):
        note = self.get_note_from_key_event(evt)
        if note is None:
            return
        if self.multi_voice:
            self.piano.note_off_multi(note)
        else:
            self.piano.note_off(note)

    def get_note_from_key_event(self, evt):
        key = evt.GetUnicodeKey()
        if key != wx.WXK_NONE:
            if key > 127:
                key = unicode_workaround(chr(key).encode('utf-8'))
            return self.piano.notes_manager[key] if key in self.piano.notes_manager else None

    def toggle_multi_voice(self, evt):
        self.piano.all_notes_off()
        self.multi_voice = not self.multi_voice

    def pan(self, evt):
        back = True if evt.GetModifiers() == wx.MOD_SHIFT else False
        self.piano.pan(back)
Esempio n. 15
0
import cv2
import time
import numpy as np
from piano import Piano
from threading import Thread

piano = Piano()

protoFile = "hand/pose_deploy.prototxt"
weightsFile = "hand/pose_iter_102000.caffemodel"
nPoints = 22

threshold = 0.2

input_source = "input.mp4"


def playMusic(x, y):
    Thread(target=piano.press, args=(
        x,
        y,
    )).start()


if __name__ == "__main__":
    cap = cv2.VideoCapture(input_source, cv2.CAP_FFMPEG)
    hasFrame, frame = cap.read()

    frameWidth = frame.shape[1]
    frameHeight = frame.shape[0]
Esempio n. 16
0
from piano import Piano
from recorder import Recorder
from logger import Logger
from sys import argv
import mido

### Call python test_recorder.py
##
## Options:
##      -i      Select input device
##      -o      Select output device

### Create instance of Piano and Recorder
p = Piano()
rec = Recorder()
log = Logger(p, rec)
### Options
verbose = "-v" in argv

### Select input and output devices
if "-i" in argv:
    [ins, outs] = p.listDevices()
    print("[+] List of input devices")
    for i in range(len(ins)):
        print("%d: %s" % (i + 1, ins[i]))
    inDev = ins[int(input("Select input device: ")) - 1]
else:
    inDev = mido.get_input_names()[0]

if "-o" in argv:
    print("[+] List of output devices")
Esempio n. 17
0
class Manager(object):
    def __init__(self):
        self.screen_size = (1366, 768)  # (width, height)
        self.camera_size = (640, 480)  # (width, height)
        self.key_quit = 'q'
        self.aruco_dict = cv2.aruco.getPredefinedDictionary(
            cv2.aruco.DICT_ARUCO_ORIGINAL)
        self.update_piano_corners_freq = 5  # Number of frames to update piano corners
        self.img_to_project = np.zeros(
            (self.camera_size[1], self.camera_size[0], 3), np.uint8)
        # self.display = Display(screen_width=self.screen_size[0])
        self.piano = Piano()
        self.cam_to_proj = None  # Transformation from camera to projector coordinates
        self.song = [
            "C#4", "C4", "F#5", "B4", "G5", "E5", "E5", "br", "F5", "D5", "D5",
            "br", "C5", "D5", "E5", "F5", "G5", "G5", "G5", "br", "G5", "E5",
            "E5", "br", "F5", "D5", "D5", "br", "C5", "E5", "G5", "G5", "C5"
        ]

    def calibrate_cam_to_proj(self):
        self.cam_to_proj = calibrate_projector(screen_size=self.screen_size,
                                               aruco_dict=self.aruco_dict)

    def run(self):
        self.calibrate_cam_to_proj()
        display = Display(screen_width=self.screen_size[0])
        sound = Sound(wav_directory="wav")
        cap = cv2.VideoCapture(1)
        frame_num = 0
        note_num = 0  # note index in the song
        is_initial_song_played = True  # Flag which indicate if we did first play of the song
        is_clicked = False  # Flag which indicate if user pressed on key
        history_frame_num = 10
        erode_kernel = np.ones((5, 5), np.uint8)
        history_pts = None
        aruco_detect_params = cv2.aruco.DetectorParameters_create()
        aruco_detect_params.doCornerRefinement = True
        fgbg = cv2.createBackgroundSubtractorMOG2(history=4,
                                                  varThreshold=50.0,
                                                  detectShadows=False)
        while True:
            # Get an image from camera
            img = self._get_image(cap_obj=cap)
            frame_num += 1
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            fgmask = fgbg.apply(gray)  # Add to background subtraction model

            # Find the piano board AruCo markers
            corners, ids, rejectedImgPoints = cv2.aruco.detectMarkers(
                gray, self.aruco_dict, parameters=aruco_detect_params)
            cv2.aruco.drawDetectedMarkers(img, corners, ids)

            # Display image for debug
            img_debug = img.copy()
            cv2.putText(img_debug, "%d" % frame_num, (8, 25),
                        cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0))
            cv2.imshow('camera', img_debug)

            # If no markers were found continue to next frame
            if ids is None:
                continue

            # If we found the piano markers
            if len(ids) > 0:
                if frame_num % self.update_piano_corners_freq == 0:
                    self.piano.update_coordinates(corners, ids)

            # Project a key
            self.img_to_project.fill(0)
            if self.piano.is_initialize():
                if self.song[note_num] != 'br':
                    # If note is not break
                    piano_key_ind = self.piano.get_key_index_by_name(
                        self.song[note_num])
                    pts = self.piano.get_key_polygon(piano_key_ind)
                    if not (is_initial_song_played):
                        color = self.piano.get_key_color(piano_key_ind)
                    else:
                        color = (0, 0, 255)
                    cv2.fillPoly(self.img_to_project, [pts], color,
                                 cv2.LINE_AA)
                    x = int((pts[0, 0, 0] + pts[1, 0, 0]) / 2.0 - 5)
                    y = int((pts[0, 0, 1] + pts[1, 0, 1]) / 2.0 - 10)

                    cv2.putText(self.img_to_project,
                                "%s" % self.song[note_num], (x, y),
                                cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 255, 0))

                    # cv2.putText(self.img_to_project, "%d" % piano_key_ind, tuple(pts[3, 0, :]),
                    #             cv2.FONT_HERSHEY_PLAIN, 1.5, (255, 0, 0))

                else:
                    if is_initial_song_played:
                        is_clicked = True

                # Play sound
                if not (is_initial_song_played):
                    # Play note sound
                    sound.play_note_sound(self.song[note_num])

                    # Advance to the next note
                    time.sleep(0.5)
                    note_num += 1
                    history_frame_num = frame_num
                else:
                    if is_clicked:
                        sound.play_note_sound(self.song[note_num])
                        time.sleep(0.5)
                        note_num += 1
                        is_clicked = False
                        history_frame_num = frame_num
                        # history_pts = pts

                # Check if song has ended
                if note_num >= len(self.song):
                    print("Song Finished!")
                    time.sleep(0.5)
                    if not (is_initial_song_played):
                        is_initial_song_played = True
                        note_num = 0
                    else:
                        break

            # Plot debug image
            # cv2.imshow('img_to_project', self.img_to_project)

            # Detect key press
            if frame_num > history_frame_num + 7:
                key_mask = cv2.cvtColor(self.img_to_project,
                                        cv2.COLOR_BGR2GRAY) > 5
                key_mask = np.uint8(key_mask) * 255
                key_mask = cv2.erode(key_mask, erode_kernel)
                key_mask = key_mask.astype(bool)
                fgmask[~key_mask] = 0
                num_pixels_in_key = np.sum(key_mask)
                num_pixels_changed = np.sum(fgmask > 0)
                frac_pixels_changed = float(num_pixels_changed) / float(
                    num_pixels_in_key)
                if frac_pixels_changed > 0.05:
                    print("Key clicked | Num pixels = %d | fraction = %.3f" %
                          (num_pixels_changed, frac_pixels_changed))
                    is_clicked = True
                cv2.imshow('background_mask', fgmask)
            else:
                if history_pts is not None:
                    cv2.fillPoly(self.img_to_project, [history_pts],
                                 (0, 255, 0), cv2.LINE_AA)

            # Transform image to projector coordinates
            dst = cv2.warpPerspective(self.img_to_project, self.cam_to_proj,
                                      self.screen_size)
            dst = cv2.cvtColor(dst, cv2.COLOR_BGR2RGB)
            display.show_array(dst)

            # Wait for key from user
            key = cv2.waitKey(1)
            if key & 0xFF == ord(self.key_quit):
                break

        # When everything done, release the capture
        cap.release()
        cv2.destroyAllWindows()
        display.close()

    def _get_image(self, cap_obj, debug_transformation=False):
        """ Get image from camera

        :param cap_obj: OpenCV's VideoCapture object
        :return: Image as NumPy array
        """
        # Capture frame-by-frame
        # This is a workaround to clean the buffer of the camera
        # We skip the first 5 frames
        # for w in range(1):
        #     cap_obj.grab()
        ret, img = cap_obj.read()

        # Test camera-to-projector transformation by projecting camera image
        # back through projector
        if debug_transformation:
            # Transform image to projector for debug
            dst = cv2.warpPerspective(img, self.cam_to_proj, self.screen_size)
            self.display.show_array(dst)
            cv2.imshow('debug', img)
        return img