# Copyright 2009 Simon Schampijer # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA from gi.repository import Gtk from gi.repository import Gdk import logging from gettext import gettext as _ from sugar3.activity import activity from sugar3.graphics.toolbarbox import ToolbarBox from sugar3.activity.widgets import ActivityToolbarButton from sugar3.graphics.radiotoolbutton import RadioToolButton from sugar3.graphics import style from sugar3.activity.widgets import StopButton from draw_piano import PianoKeyboard import math import time import common.Util.Instruments from common.Util import InstrumentDB from common.Util.CSoundClient import new_csound_client from KeyboardStandAlone import KeyboardStandAlone from MiniSequencer import MiniSequencer from Loop import Loop import common.Config as Config class SimplePianoActivity(activity.Activity): """SimplePianoActivity class as specified in activity.info""" def __init__(self, handle): """Set up the HelloWorld activity.""" activity.Activity.__init__(self, handle) # we do not have collaboration features # make the share option insensitive self.max_participants = 1 # toolbar with the new toolbar redesign toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbar_box.toolbar.insert(activity_button, 0) toolbar_box.toolbar.insert(Gtk.SeparatorToolItem(), -1) keybord_labels = RadioToolButton() keybord_labels.props.icon_name = 'q_key' keybord_labels.props.group = keybord_labels keybord_labels.connect('clicked', self.set_keyboard_labels_cb) toolbar_box.toolbar.insert(keybord_labels, -1) notes_labels = RadioToolButton() notes_labels.props.icon_name = 'do_key' notes_labels.props.group = keybord_labels notes_labels.connect('clicked', self.set_notes_labels_cb) toolbar_box.toolbar.insert(notes_labels, -1) german_labels = RadioToolButton() german_labels.props.icon_name = 'c_key' german_labels.props.group = keybord_labels german_labels.connect('clicked', self.set_german_labels_cb) toolbar_box.toolbar.insert(german_labels, -1) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbar_box.toolbar.insert(separator, -1) stop_button = StopButton(self) toolbar_box.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbar_box(toolbar_box) toolbar_box.show_all() self.keyboard_letters = ['ZSXDCVGBHNJM', 'Q2W3ER5T6Y7U', 'I'] notes = ['DO', 'DO#', 'RE', 'RE#', 'MI', 'FA', 'FA#', 'SOL', 'SOL#', 'LA', 'LA#', 'SI'] self.notes_labels = [notes, notes, ['DO']] german_notes = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] self.german_labels = [german_notes, german_notes, ['C']] self.piano = PianoKeyboard(octaves=2, add_c=True, labels=self.keyboard_letters) # init csound self.instrumentDB = InstrumentDB.getRef() self.firstTime = False self.playing = False self.csnd = new_csound_client() self.timeout_ms = 50 self.instVolume = 50 self.drumVolume = 0.5 self.instrument = 'piano' self.regularity = 0.75 self.beat = 4 self.reverb = 0.1 self.tempo = Config.PLAYER_TEMPO self.beatDuration = 60.0 / self.tempo self.ticksPerSecond = Config.TICKS_PER_BEAT * self.tempo / 60.0 #self.rythmInstrument = 'drum1kit' #self.csnd.load_drumkit(self.rythmInstrument) self.sequencer = MiniSequencer(self.recordStateButton, self.recordOverSensitivity) self.loop = Loop(self.beat, math.sqrt(self.instVolume * 0.01)) self.muteInst = False self.csnd.setTempo(self.tempo) self.noteList = [] time.sleep(0.001) # why? for i in range(21): self.csnd.setTrackVolume(100, i) for i in range(10): r = str(i + 1) self.csnd.load_instrument('guidice' + r) self.volume = 100 self.csnd.setMasterVolume(self.volume) self.enableKeyboard() self.setInstrument(self.instrument) self.connect('key-press-event', self.onKeyPress) self.connect('key-release-event', self.onKeyRelease) # finish csount init self.piano.connect('key_pressed', self.__key_pressed_cb) self.piano.connect('key_released', self.__key_released_cb) vbox = Gtk.VBox() vbox.set_homogeneous(False) label = Gtk.Label('') vbox.pack_end(self.piano, True, True, 0) vbox.pack_start(label, False, False, 0) vbox.show_all() self.set_canvas(vbox) piano_height = Gdk.Screen.width() / 2 label.set_size_request(-1, Gdk.Screen.height() - piano_height - style.GRID_CELL_SIZE) def set_notes_labels_cb(self, widget): self.piano.font_size = 14 self.piano.set_labels(self.notes_labels) def set_keyboard_labels_cb(self, widget): self.piano.font_size = 20 self.piano.set_labels(self.keyboard_letters) def set_german_labels_cb(self, widget): self.piano.font_size = 20 self.piano.set_labels(self.german_labels) def enableKeyboard(self): self.keyboardStandAlone = KeyboardStandAlone(self.sequencer.recording, self.sequencer.adjustDuration, self.csnd.loopGetTick, self.sequencer.getPlayState, self.loop) self.add_events(Gdk.EventMask.BUTTON_PRESS_MASK) def setInstrument(self, instrument): self.instrument = instrument self.keyboardStandAlone.setInstrument(instrument) self.csnd.load_instrument(instrument) def recordStateButton(self, button, state): pass # if button == 1: # self._recordToolbar.keyboardRecButton.set_active( state ) # else: # self._recordToolbar.keyboardRecOverButton.set_active( state ) def recordOverSensitivity(self, state): pass #self._recordToolbar.keyboardRecOverButton.set_sensitive( state ) def __key_pressed_cb(self, widget, octave_clicked, key_clicked, letter): logging.error('Pressed Octave: %d Key: %d Letter: %s' % (octave_clicked, key_clicked, letter)) if letter in Config.LETTERS_MAP_PIANO.keys(): self.keyboardStandAlone.do_key_press( Config.LETTERS_MAP_PIANO[letter], None, math.sqrt(self.instVolume * 0.01)) def __key_released_cb(self, widget, octave_clicked, key_clicked, letter): if letter in Config.LETTERS_MAP_PIANO.keys(): self.keyboardStandAlone.do_key_release( Config.LETTERS_MAP_PIANO[letter]) def onKeyPress(self, widget, event): if event.hardware_keycode == 37: if self.muteInst: self.muteInst = False else: self.muteInst = True self.keyboardStandAlone.onKeyPress(widget, event, math.sqrt(self.instVolume * 0.01)) def onKeyRelease(self, widget, event): self.keyboardStandAlone.onKeyRelease(widget, event)