Permalink
Browse files

Move Piano config to dedicated file, support 88 keys and 3 pedals

  • Loading branch information...
coox committed Sep 4, 2016
1 parent 8d8b179 commit ae87fa6152d07f33e56044c4467ed8e9fafd2af6
Showing with 152 additions and 27 deletions.
  1. +43 −0 config/piano.ini
  2. +0 −4 config/street-fighter-alpha-3.ini
  3. +1 −1 main.py
  4. +4 −4 pianette/Pianette.py
  5. +104 −18 pianette/PianoState.py
@@ -0,0 +1,43 @@
[Piano]

supported-notes = A0, B♭0, B0, C1, D♭1, D1, E♭1, E1, F1, G♭1, G1, A♭1, A1, B♭1, B1, C2, D♭2, D2, E♭2, E2, F2, G♭2, G2, A♭2, A2, B♭2, B2, C3, D♭3, D3, E♭3, E3, F3, G♭3, G3, A♭3, A3, B♭3, B3, C4, D♭4, D4, E♭4, E4, F4, G♭4, G4, A♭4, A4, B♭4, B4, C5, D♭5, D5, E♭5, E5, F5, G♭5, G5, A♭5, A5, B♭5, B5, C6, D♭6, D6, E♭6, E6, F6, G♭6, G6, A♭6, A6, B♭6, B6, C7, D♭7, D7, E♭7, E7, F7, G♭7, G7, A♭7, A7, B♭7, B7, C8
supported-pedals = soft, sostenuto, sustain

[[Aliases]]

A♯0 = B♭0
C♯1 = D♭1
D♯1 = E♭1
F♯1 = G♭1
G♯1 = A♭1
A♯1 = B♭1
C♯2 = D♭2
D♯2 = E♭2
F♯2 = G♭2
G♯2 = A♭2
A♯2 = B♭2
C♯3 = D♭3
D♯3 = E♭3
F♯3 = G♭3
G♯3 = A♭3
A♯3 = B♭3
C♯4 = D♭4
D♯4 = E♭4
F♯4 = G♭4
G♯4 = A♭4
A♯4 = B♭4
C♯5 = D♭5
D♯5 = E♭5
F♯5 = G♭5
G♯5 = A♭5
A♯5 = B♭5
C♯6 = D♭6
D♯6 = E♭6
F♯6 = G♭6
G♯6 = A♭6
A♯6 = B♭6
C♯7 = D♭7
D♯7 = E♭7
F♯7 = G♭7
G♯7 = A♭7
A♯7 = B♭7
@@ -51,10 +51,6 @@ GPIO4 = piano.play B♭3
GPIO17 = piano.play B3
GPIO27 = piano.play C4

[Piano]

supported-notes = C1, G1, B♭1, C2, C3, D♭3, D3, E♭3, E3, F3, G♭3, G3, A♭3, A3, B♭3, B3, C4

[Console]

supported-controls = ↑, ↓, ←, →, □, △, ✕, ◯, L1, R1, L2, R2, SELECT, START
@@ -25,7 +25,7 @@
Debug.println("INFO", " ")

# FIX ME - introduce sys.argv[1] to choose player AND game?
configobj = pianette.config.get_configobj('pianette', 'street-fighter-alpha-3', 'player1')
configobj = pianette.config.get_configobj('piano', 'pianette', 'street-fighter-alpha-3', 'player1')

parser = PianetteArgumentParser(configobj=configobj)
args = parser.parse_args()
@@ -225,7 +225,7 @@ def push_console_controls(self, controls_string, duration_cycles = None):

def push_piano_notes(self, notes_string):
for note in notes_string.replace("+", " ").split():
self.piano_state.raise_note(note)
self.piano_state.switch_note_on(note)

# Timer Methods

@@ -246,11 +246,11 @@ def stop_timer(self):

def cycle_buffered_states(self):
# Input Piano Notes to Piano Buffered States
for piano_note in self.piano_state.get_notes_keys():
if self.piano_state.is_note_raised(piano_note):
for piano_note in self.piano_state.get_supported_notes():
if self.piano_state.is_note_on(piano_note):
Debug.println("INFO", "Processing Piano Note %s" % (piano_note))
self.piano_buffered_states[piano_note].append({ "cycles_remaining": PIANETTE_PROCESSING_CYCLES })
self.piano_state.clear_note(piano_note)
self.piano_state.switch_note_off(piano_note)

# Process Buffered States: Determine piano note or chord
# Notes that have reached their last cycle "lead" the chord determination
@@ -1,36 +1,122 @@
# coding: utf-8

from pianette.errors import PianetteConfigError
from pianette.utils import Debug

class PianoState:

def __init__(self, configobj=None):
# Private methods: Config

def __init_using_configobj(self, configobj=None):
if not configobj.__class__.__name__ == 'ConfigObj':
raise PianetteConfigError('Unsupported Piano config')

if not 'Piano' in configobj.dict().keys():
raise PianetteConfigError('Piano config not found')

self.configobj = configobj

self.__init_note_states()
self.__init_pedal_states()

# Private methods: Notes

def __init_note_states(self):
try:
supported_notes = self.configobj['Piano']['supported-notes']
except KeyError:
raise PianetteConfigError('Piano config must define supported-notes')

self.note_states = {}
for note in supported_notes:
self.__set_note_state(note, False)

Debug.println('SUCCESS', 'Piano note states initialized')

def __assert_supported_note(self, note):
if not note in self.note_states:
raise KeyError('Piano does not support note "%s"' % note)

def __get_note_state(self, note):
return self.note_states[note]

def __set_note_state(self, note, state):
self.note_states[note] = state

# Private methods: Pedals

def __init_pedal_states(self):
try:
self.note_states = { k: False for k in self.configobj['Piano']['supported-notes'] }
supported_pedals = self.configobj['Piano']['supported-pedals']
except KeyError:
pass
raise PianetteConfigError('Piano config must define supported-pedals')

self.pedal_states = {}
for pedal in supported_pedals:
self.__set_pedal_state(pedal, False)

Debug.println('SUCCESS', 'Piano pedal states initialized')

def __assert_supported_pedal(self, pedal):
if not pedal in self.pedal_states:
raise KeyError('Piano does not support pedal "%s"' % pedal)

def __str__(self):
state_string = ""
def __get_pedal_state(self, pedal):
return self.pedal_states[pedal]

def __set_pedal_state(self, pedal, state):
self.pedal_states[pedal] = state

# Constructor

def __init__(self, configobj=None):
self.__init_using_configobj(configobj)
Debug.println('SUCCESS', 'Piano initialized')

for note, cycles in self.note_states.items():
if (cycles > 0):
state_string += note + " "
# Public methods: Config

return state_string
def set_configobj(self, configobj=None):
self.__init_using_configobj(configobj)
Debug.println('SUCCESS', 'Piano config changed')

def get_notes_keys(self):
# Public methods: Notes

def switch_note_off(self, note):
self.__assert_supported_note(note)
self.__set_note_state(note, False)

def switch_note_on(self, note):
self.__assert_supported_note(note)
self.__set_note_state(note, True)

def is_note_off(self, note):
self.__assert_supported_note(note)
return self.__get_note_state(note) is False

def is_note_on(self, note):
self.__assert_supported_note(note)
return self.__get_note_state(note) is True

def get_supported_notes(self):
return self.note_states.keys()

def raise_note(self, note):
self.note_states[note] = True
# Public methods: Pedals

def switch_pedal_off(self, pedal):
self.__assert_supported_pedal(pedal)
self.__set_pedal_state(pedal, False)

def switch_pedal_on(self, pedal):
self.__assert_supported_pedal(pedal)
self.__set_pedal_state(pedal, True)

def is_note_raised(self, note):
return (self.note_states[note] is True)
def is_pedal_off(self, pedal):
self.__assert_supported_pedal(pedal)
return self.__get_pedal_state(pedal) is False

def clear_note(self, note):
self.note_states[note] = False
def is_pedal_on(self, pedal):
self.__assert_supported_pedal(pedal)
return self.__get_pedal_state(pedal) is True

def is_note_cleared(self, note):
return (self.note_states[note] is False)
def get_supported_pedals(self):
return self.pedal_states.keys()

2 comments on commit ae87fa6

@tchapi

This comment has been minimized.

Copy link
Owner

tchapi replied Sep 5, 2016

C'est dans ces moments de génie que je te retrouve mon bon @coox

@coox

This comment has been minimized.

Copy link
Collaborator

coox replied Sep 8, 2016

Toi même tu sais ❤

Please sign in to comment.