diff --git a/Architectural_Spike.png b/Architectural_Spike.png new file mode 100644 index 00000000..cc639ecf Binary files /dev/null and b/Architectural_Spike.png differ diff --git a/api.py b/api.py index 08c22c1d..07a3d4b6 100644 --- a/api.py +++ b/api.py @@ -15,6 +15,7 @@ from config import Config from coderbotTestUnit import run_test as runCoderbotTestUnit import pigpio +from musicPackages import MusicPackageManager BUTTON_PIN = 16 @@ -179,6 +180,25 @@ def updateFromPackage(): os.system('sudo reboot') return 200 +def updatePackages(): + """ + Add a musical package an save the list of available packages on disk + also add sounds and directory + """ + """zipName = request.args.get("zipname") + """ + file_to_upload = connexion.request.files['file_to_upload'] + print("adding " +str(file_to_upload)) + print("adding " + file_to_upload.filename) + file_to_upload.save(os.path.join('./updatePackages/', file_to_upload.filename)) + musicPkg = MusicPackageManager.get_instance() + response = musicPkg.addPackage(file_to_upload.filename) + if response == 1: + return 200 + elif response == 2: + return 2 + elif response == 3: + return 3 ## Programs @@ -252,4 +272,4 @@ def reset(): def testCoderbot(data): # taking first JSON key value (varargin) tests_state = runCoderbotTestUnit(data[list(data.keys())[0]]) - return tests_state \ No newline at end of file + return tests_state diff --git a/audioControls.py b/audioControls.py new file mode 100644 index 00000000..b98fc36f --- /dev/null +++ b/audioControls.py @@ -0,0 +1,54 @@ +# CoderBot, a didactical programmable robot. +# Copyright (C) 2014, 2015 Roberto Previtera +# +# 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. +############################################################################ +# CoderBot, a didactical programmable robot. +# Copyright (C) 2014, 2015 Roberto Previtera +# +# MUSICAL EXTENTION for CoderBot +# This extention is develop by: +# Michele Carbonera - miki_992@hotmail.it - m.carbonera@campus.unimib.it - michele.carbonera@unimib.it +# Antonino Tramontana - a.tramontana1@campus.unimib.it +# Copyright (C) 2020 +############################################################################ + +import os +import alsaaudio + +class AudioCtrl: + mixer = None + _instance = None + + @classmethod + def get_instance(cls): + if cls._instance is None: + cls._instance = AudioCtrl() + return cls._instance + + def __init__(self): + self.mixer = alsaaudio.Mixer('PCM', cardindex=1) + #self.mixer = alsaaudio.PCM(device='numid=1', cardindex=1) + + def getVolume(self): + print(self.mixer.getvolume()) + + def setVolume(self,valueVolume): + self.mixer.setvolume(valueVolume) +''' +if __name__ == "__main__": + a = AudioCtrl() + a.setVolume(20) + #a.setVolume(100)''' diff --git a/coderbot.cfg b/coderbot.cfg index 949bf3a2..fdd23ec5 100644 --- a/coderbot.cfg +++ b/coderbot.cfg @@ -1 +1,40 @@ -{"move_power_angle_3": "60", "cnn_default_model": "generic_fast_low", "prog_maxblocks": "-1", "camera_jpeg_quality": "5", "show_page_control": "true", "camera_framerate": "30", "prog_scrollbars": "true", "move_fw_speed": "100", "prog_level": "adv", "move_motor_trim": "1", "move_motor_mode": "dc", "cv_image_factor": "2", "move_power_angle_1": "45", "camera_path_object_size_min": "4000", "button_func": "none", "camera_color_object_size_min": "4000", "camera_jpeg_bitrate": "1000000", "move_fw_elapse": "1", "show_control_move_commands": "true", "camera_color_object_size_max": "160000", "show_page_prefs": "true", "camera_exposure_mode": "auto", "ctrl_tr_elapse": "-1", "show_page_program": "true", "move_tr_elapse": "0.5", "camera_path_object_size_max": "160000", "sound_shutter": "$shutter.mp3", "ctrl_fw_elapse": "-1", "sound_stop": "$shutdown.mp3", "ctrl_tr_speed": "80", "ctrl_fw_speed": "100", "move_tr_speed": "85", "move_power_angle_2": "60", "ctrl_hud_image": "", "load_at_start": "", "sound_start": "$startup.mp3", "encoder": "True"} \ No newline at end of file +{ + "move_power_angle_3":"60", + "cnn_default_model":"generic_fast_low", + "prog_maxblocks":"-1", + "camera_jpeg_quality":"5", + "show_page_control":"true", + "camera_framerate":"30", + "prog_scrollbars":"true", + "move_fw_speed":"100", + "prog_level":"adv", + "move_motor_trim":"1", + "move_motor_mode":"dc", + "cv_image_factor":"2", + "move_power_angle_1":"45", + "camera_path_object_size_min":"4000", + "button_func":"none", + "camera_color_object_size_min":"4000", + "camera_jpeg_bitrate":"1000000", + "move_fw_elapse":"1", + "show_control_move_commands":"true", + "camera_color_object_size_max":"160000", + "show_page_prefs":"true", + "camera_exposure_mode":"auto", + "ctrl_tr_elapse":"-1", + "show_page_program":"true", + "move_tr_elapse":"0.5", + "camera_path_object_size_max":"160000", + "sound_shutter":"$shutter.mp3", + "ctrl_fw_elapse":"-1", + "sound_stop":"$shutdown.mp3", + "ctrl_tr_speed":"80", + "ctrl_fw_speed":"100", + "move_tr_speed":"85", + "move_power_angle_2":"60", + "ctrl_hud_image":"", + "load_at_start":"", + "sound_start":"$startup.mp3", + "encoder":"True", + "audio_volume_level":"100" +} \ No newline at end of file diff --git a/dist/static/music_package.json b/dist/static/music_package.json new file mode 100755 index 00000000..5a2076f5 --- /dev/null +++ b/dist/static/music_package.json @@ -0,0 +1,172 @@ +{ + "packages": { + "cat": { + "category": "animal", + "name_IT": "gatto", + "name_EN": "cat", + "version": "0.1", + "date": "2020-04-08", + "interface": { + "base": { + "available": "TRUE", + "icon": "cat.png" + }, + "intermediate": { + "available": "TRUE", + "icon": "cat.png" + }, + "advanced": { + "available": "TRUE", + "icon": "cat.png" + } + } + }, + "dog": { + "category": "animal", + "name_IT": "cane", + "name_EN": "dog", + "version": "0.1", + "date": "2020-04-08", + "interface": { + "base": { + "available": "TRUE", + "icon": "dog.png" + }, + "intermediate": { + "available": "TRUE", + "icon": "dog.png" + }, + "advanced": { + "available": "TRUE", + "icon": "dog.png" + } + } + }, + "piano": { + "category": "instrument", + "name_IT": "pianoforte", + "name_EN": "piano", + "version": "0.1", + "date": "2020-04-08", + "interface": { + "base": { + "available": "TRUE", + "icon": "piano.png" + }, + "intermediate": { + "available": "TRUE", + "icon": "piano.png" + }, + "advanced": { + "available": "TRUE", + "icon": "piano.png" + } + } + }, + "guitar": { + "category": "instrument", + "name_IT": "chitarra", + "name_EN": "guitar", + "version": "0.1", + "date": "2020-04-08", + "interface": { + "base": { + "available": "TRUE", + "icon": "guitar.png" + }, + "intermediate": { + "available": "TRUE", + "icon": "guitar.png" + }, + "advanced": { + "available": "TRUE", + "icon": "guitar.png" + } + } + }, + "flute": { + "category": "instrument", + "name_IT": "flauto", + "name_EN": "flute", + "version": "0.1", + "date": "2020-04-08", + "interface": { + "base": { + "available": "TRUE", + "icon": "flute.png" + }, + "intermediate": { + "available": "TRUE", + "icon": "flute.png" + }, + "advanced": { + "available": "TRUE", + "icon": "flute.png" + } + } + }, + "pig": { + "category": "animal", + "name_IT": "maiale", + "name_EN": "pig", + "version": "0.1", + "date": "2020-06-01", + "interface": { + "base": { + "available": "TRUE", + "icon": "pig.png" + }, + "intermediate": { + "available": "TRUE", + "icon": "pig.png" + }, + "advanced": { + "available": "TRUE", + "icon": "pig.png" + } + } + }, + "elephant": { + "category": "animal", + "name_IT": "elefante", + "name_EN": "elephant", + "version": "0.1", + "date": "2020-06-01", + "interface": { + "base": { + "available": "TRUE", + "icon": "elephant.png" + }, + "intermediate": { + "available": "TRUE", + "icon": "elephant.png" + }, + "advanced": { + "available": "TRUE", + "icon": "elephant.png" + } + } + }, + "snake": { + "category": "animal", + "name_IT": "serpente", + "name_EN": "snake", + "version": "0.1", + "date": "2020-06-01", + "interface": { + "base": { + "available": "TRUE", + "icon": "snake.png" + }, + "intermediate": { + "available": "TRUE", + "icon": "snake.png" + }, + "advanced": { + "available": "TRUE", + "icon": "snake.png" + } + } + } + } +} diff --git a/main.py b/main.py index fa80e5bf..08ce0cf2 100644 --- a/main.py +++ b/main.py @@ -30,7 +30,8 @@ from config import Config from cnn_manager import CNNManager from event import EventManager - +from audioControls import AudioCtrl +from musicPackages import MusicPackageManager # Logging configuration logger = logging.getLogger() logger.setLevel(logging.INFO) @@ -59,6 +60,8 @@ app.prog = None app.shutdown_requested = False + + ## New API and web application # API v2 is defined in v2.yml and its methods are in api.py @@ -153,10 +156,23 @@ def handle_config(): """ Overwrite configuration file on disk and reload it """ + audioCtrl = AudioCtrl.get_instance() + audioCtrl.setVolume(int(request.form['audio_volume_level'])) Config.write(updateDict(app.bot_config, request.form)) app.bot_config = Config.get() return "ok" +@app.route("/deletepkg", methods=["POST"]) +def handle_packages(): + """ + Delete a musical package an save the list of available packages on disk + also delete package sounds and directory + """ + packageName = request.form.get("nameID") + musicPkg = MusicPackageManager.get_instance() + musicPkg.deletePackage(packageName) + return "package deleted" + @app.route("/config", methods=["GET"]) def returnConfig(): """ @@ -468,6 +484,10 @@ def run_server(): encoder=bool(app.bot_config.get('encoder'))) audio = Audio.get_instance() audio.say(app.bot_config.get("sound_start")) + + audioCtrl = AudioCtrl.get_instance() + audioCtrl.setVolume(int(app.bot_config.get['audio_volume_level'])) + try: cam = Camera.get_instance() Motion.get_instance() diff --git a/music.py b/music.py new file mode 100644 index 00000000..0544b468 --- /dev/null +++ b/music.py @@ -0,0 +1,152 @@ +############################################################################ +# CoderBot, a didactical programmable robot. +# Copyright (C) 2014, 2015 Roberto Previtera +# +# 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. +############################################################################ +# CoderBot, a didactical programmable robot. +# Copyright (C) 2014, 2015 Roberto Previtera +# +# MUSICAL EXTENTION for CoderBot +# This extention is develop by: +# Michele Carbonera - miki_992@hotmail.it - m.carbonera@campus.unimib.it - michele.carbonera@unimib.it +# Antonino Tramontana - a.tramontana1@campus.unimib.it +# Copyright (C) 2020 +############################################################################ + +import os +import sox +import time + +class Music: + _instance = None + managerPackage = None + + noteDict = { + 'C2': -7.0, 'D2' : -5.0, 'E2' : -3.0, 'F2' : -2.0, 'F#2' : -1.0, 'G2' : 0.0, + 'A2' : 2.0, 'Bb2' : 3.0, 'B2' : 4.0, 'C3' : 5.0, 'D3' : 7.0, 'E3' : 9.0, + 'F3' : 10.0, 'G3' : 12.0 + } + + + @classmethod + def get_instance(cls,managerPackage): + if cls._instance is None: + cls._instance = Music(managerPackage) + return cls._instance + + def __init__(self,managerPackage): + + #os.putenv('AUDIODRIVER', 'alsa') + #os.putenv('AUDIODEV', 'hw:1,0') + self.managerPackage = managerPackage + print("We have create a class: MUSICAL") + + def test(self): + tfm = sox.Transformer() + tfm.preview('cat.wav') + tfm.build('cat.wav', 'outMusicDemo.wav') + + #play a pause + # @param duration: duration of the pause in seconds + def play_pause(self, duration): + duration = float(duration) + time.sleep(duration) + + #play a given note for a given instrument + # @param instrument: name of the instrument to be used + # @param note: name of the note in the following format "A2" + # @para alteration: if it is a diesis or a bemolle + # @param time: duration of the note in seconds + def play_note(self, note, instrument='piano', alteration='none', duration=1.0): + print(note) + tfm = sox.Transformer() + + duration = float(duration) + + alt = 0.0 + if alteration == 'bmolle': + alt = -1.0 + elif alteration == 'diesis': + alt = 1.0 + + if note in self.noteDict : + shift = self.noteDict[note]+ alt + else: + print('note not exist') + return + + tfm.pitch(shift, quick=False) + tfm.trim(0.0, end_time=0.5*duration) + if self.managerPackage.isPackageAvailable(instrument): + tfm.preview('./sounds/notes/' + instrument + '/audio.wav') + else: + print("no instrument:"+str(instrument)+" present in this coderbot!") + + def play_animal(self, instrument, note='G2', alteration='none', duration=1.0): + tfm = sox.Transformer() + + duration = float(duration) + + alt = 0.0 + if alteration == 'bmolle': + alt = -1.0 + elif alteration == 'diesis': + alt = 1.0 + + if note == 'C2': + shift = -7.0 + alt + elif note == 'D2': + shift = -5.0 + alt + elif note == 'E2': + shift = -3.0 + alt + elif note == 'F2': + shift = -2.0 + alt + elif note == 'F#2': + shift = -1.0 + alt + elif note == 'G2': + shift = 0.0 + alt + elif note == 'A2': + shift = 2.0 + alt + elif note == 'Bb2': + shift = 3.0 + alt + elif note == 'B2': + shift = 4.0 + alt + elif note == 'C3': + shift = 5.0 + alt + elif note == 'D3': + shift = 7.0 + alt + elif note == 'E3': + shift = 9.0 + alt + elif note == 'F3': + shift = 10.0 + alt + elif note == 'G3': + shift = 12.0 + alt + + if note in self.noteDict : + shift = self.noteDict[note]+ alt + else: + print('note not exist') + return + + if self.managerPackage.isPackageAvailable(instrument): + tfm.preview('./sounds/notes/' + instrument + '/audio.wav') + else: + print("no animal verse:"+str(instrument)+" present in this coderbot!") + return + tfm.pitch(shift, quick=False) + tfm.trim(0.0, end_time=0.5*duration) + #tfm.stretch(time, window=20) + tfm.preview('./sounds/notes/' + instrument + '/audio.wav') diff --git a/musicPackages.py b/musicPackages.py new file mode 100644 index 00000000..bffccdd2 --- /dev/null +++ b/musicPackages.py @@ -0,0 +1,214 @@ +############################################################################ +# CoderBot, a didactical programmable robot. +# Copyright (C) 2014, 2015 Roberto Previtera +# +# 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. +############################################################################ +# CoderBot, a didactical programmable robot. +# Copyright (C) 2014, 2015 Roberto Previtera +# +# MUSICAL EXTENTION for CoderBot +# This extention is develop by: +# Michele Carbonera - miki_992@hotmail.it - m.carbonera@campus.unimib.it - michele.carbonera@unimib.it +# Antonino Tramontana - a.tramontana1@campus.unimib.it +# Copyright (C) 2020 +############################################################################ + +import json +import os + +class MusicPackage: + name_IT = None + name_EN = None + category = None + version = None + date = None + interfaces = None + nameID = None + + def __init__(self,nameID,category,name_IT,name_EN,version,date): + self.nameID = nameID + self.category = category + self.name_IT = name_IT + self.name_EN = name_EN + self.version = version + self.date = date + self.interfaces = list() + + def getNameID(self): + return self.nameID + def getCategory(self): + return self.category + def getNameIT(self): + return self.name_IT + def getNameEN(self): + return self.name_EN + def getVersion(self): + return self.version + def getDate(self): + return self.date + def getInterfaces(self): + return self.interfaces + + def addInterface(self,musicPackageInterface): + self.interfaces.append(musicPackageInterface) + +class MusicPackageInterface: + interfaceName = None + available = None + icon = None + + def __init__(self,interfaceName,available,icon): + self.interfaceName = interfaceName + self.available = available + self.icon = icon + + def getInterfaceName(self): + return self.interfaceName + + def getAvailable(self): + return self.available + + def getIcon(self): + return self.icon + +class MusicPackageManager: + _instance = None + packages = None + + @classmethod + def get_instance(cls): + if cls._instance is None: + cls._instance = MusicPackageManager() + print("make MusicPackageManager") + return cls._instance + + def __init__(self): + self.packages = dict() + with open('./sounds/notes/music_package.json') as json_file: + data = json.load(json_file) + for p in data['packages']: + + package = data['packages'][p] + mp = MusicPackage(p,package['category'],package['name_IT'],package['name_EN'],package['version'],package['date']) + for i in package['interface']: + interfaceItem = package['interface'][i] + mpi = MusicPackageInterface(i,interfaceItem['available'],interfaceItem['icon']) + mp.addInterface(mpi) + + if p not in self.packages: + self.packages[p] = mp + + def updatePackages(self): + newdict = { 'packages': {} } + for element in self.packages: + nameID = self.packages[element].getNameID() + newdict['packages'][nameID] = { } + newdict['packages'][nameID]['category']= self.packages[element].getCategory() + newdict['packages'][nameID]['name_IT']= self.packages[element].getNameIT() + newdict['packages'][nameID]['name_EN']= self.packages[element].getNameEN() + newdict['packages'][nameID]['version']= self.packages[element].getVersion() + newdict['packages'][nameID]['date']= self.packages[element].getDate() + newdict['packages'][nameID]['interface']= {'base':{}, 'intermediate':{}, 'advanced': {}} + newdict['packages'][nameID]['interface']['base']['available'] = self.packages[element].getInterfaces()[0].getAvailable() + newdict['packages'][nameID]['interface']['base']['icon'] = self.packages[element].getInterfaces()[0].getIcon() + newdict['packages'][nameID]['interface']['intermediate']['available'] = self.packages[element].getInterfaces()[1].getAvailable() + newdict['packages'][nameID]['interface']['intermediate']['icon'] = self.packages[element].getInterfaces()[1].getIcon() + newdict['packages'][nameID]['interface']['advanced']['available'] = self.packages[element].getInterfaces()[2].getAvailable() + newdict['packages'][nameID]['interface']['advanced']['icon'] = self.packages[element].getInterfaces()[2].getIcon() + + #json_packages = json.dumps(newdict) + with open('./dist/static/music_package.json', 'w', encoding='utf-8') as json_file: + json.dump(newdict, json_file, ensure_ascii=False, indent=4) + + + def deletePackage(self, packageName): + if packageName in self.packages: + del self.packages[packageName] + self.updatePackages() + else: + print("errore, il pacchetto " + packageName + " non รจ stato trovato") + return 2 + + if os.path.exists('./sounds/notes/' + packageName): + os.system('rm -rf ./sounds/notes/' + packageName) + return 1 + + + def verifyVersion(self, packageName, version): + print("verifica pacchetto") + #newversionList = version.split('.') + if packageName not in self.packages: + return True + + newVersionList = [int(x) for x in version.split('.')] + #for i in ragen(0,len(newversionList) -1): + #newversionList[i] = int(newLversionList[i]) + + oldVersion = self.packages[packageName].getVersion() + oldVersionList = [int(x) for x in oldVersion.split('.')] + + for i in range(0,len(newVersionList) -1): + if(newVersionList[i] > oldVersionList[i] ): + return True + elif(newVersionList[i] < oldVersionList[i] ): + return False + + return False + + def addPackage(self, filename): + pkgnames = filename.split('_') + version = pkgnames[1].replace('.zip', '') + print(version) + pkgname = pkgnames[0] + pkgpath = './sounds/notes/' + pkgname + if not self.verifyVersion(pkgname, version): + if (version == self.packages[pkgname].getVersion()): + print("errore, il pacchetto " + pkgname + " ha versione identica a quello attualmente installato") + return 3 + else: + print("errore, il pacchetto " + pkgname + " ha versione precendente a quello attualmente installato") + return 2 + else: + + os.system('unzip -o ' + './updatePackages/' + filename + " -d ./updatePackages") + + os.system('mkdir ' + pkgpath) + os.system('mv ./updatePackages/' + pkgname + "/" + 'audio.wav ' + pkgpath + '/') + + with open('./updatePackages/' + pkgname + '/' + pkgname + '.json') as json_file: + print("adding " + pkgname + " package") + data = json.load(json_file) + for p in data['packages']: + package = data['packages'][p] + mp = MusicPackage(p,package['category'],package['name_IT'],package['name_EN'],package['version'],package['date']) + for i in package['interface']: + interfaceItem = package['interface'][i] + mpi = MusicPackageInterface(i,interfaceItem['available'],interfaceItem['icon']) + mp.addInterface(mpi) + + self.packages[p] = mp + + self.updatePackages() + + os.system('rm -rf ./updatePackages/' + pkgname) + return 1 + + + def isPackageAvailable(self,namePackage): + if namePackage in self.packages: + return True + else: + return False diff --git a/program.py b/program.py index b66efde9..350ea603 100644 --- a/program.py +++ b/program.py @@ -31,13 +31,16 @@ import config import audio import event - +import music +import musicPackages PROGRAM_PATH = "./data/" PROGRAM_PREFIX = "program_" PROGRAM_SUFFIX = ".json" +musicPackageManager = musicPackages.MusicPackageManager.get_instance() + def get_cam(): return camera.Camera.get_instance() @@ -56,6 +59,9 @@ def get_prog_eng(): def get_event(): return event.EventManager.get_instance() +def get_music(): + return music.Music.get_instance(musicPackageManager) + class ProgramEngine: # pylint: disable=exec-used diff --git a/requirements_stub.txt b/requirements_stub.txt index e8301ef3..9e3e06d3 100644 --- a/requirements_stub.txt +++ b/requirements_stub.txt @@ -44,4 +44,6 @@ setuptools==42.0.1 smbus2==0.3.0 spidev==3.4 cachetools==3.0.0 +sox==1.3.7 +pyalsaaudio==0.8.4 pytesseract==0.3.4 diff --git a/sounds/notes/cat/audio.wav b/sounds/notes/cat/audio.wav new file mode 100644 index 00000000..eb20db75 Binary files /dev/null and b/sounds/notes/cat/audio.wav differ diff --git a/sounds/notes/dinosaur.wav b/sounds/notes/dinosaur.wav new file mode 100644 index 00000000..4fe28f48 Binary files /dev/null and b/sounds/notes/dinosaur.wav differ diff --git a/sounds/notes/dog/audio.wav b/sounds/notes/dog/audio.wav new file mode 100644 index 00000000..652c1e24 Binary files /dev/null and b/sounds/notes/dog/audio.wav differ diff --git a/sounds/notes/duck/audio.wav b/sounds/notes/duck/audio.wav new file mode 100644 index 00000000..ee416bc0 Binary files /dev/null and b/sounds/notes/duck/audio.wav differ diff --git a/sounds/notes/elephant/audio.wav b/sounds/notes/elephant/audio.wav new file mode 100644 index 00000000..7d313846 Binary files /dev/null and b/sounds/notes/elephant/audio.wav differ diff --git a/sounds/notes/flute/audio.wav b/sounds/notes/flute/audio.wav new file mode 100644 index 00000000..1e14fa57 Binary files /dev/null and b/sounds/notes/flute/audio.wav differ diff --git a/sounds/notes/guitar/audio.wav b/sounds/notes/guitar/audio.wav new file mode 100644 index 00000000..673b5127 Binary files /dev/null and b/sounds/notes/guitar/audio.wav differ diff --git a/sounds/notes/music_package.json b/sounds/notes/music_package.json new file mode 100644 index 00000000..9cf31dcf --- /dev/null +++ b/sounds/notes/music_package.json @@ -0,0 +1,138 @@ +{ + "packages":{ + "cat":{ + "category":"animal", + "name_IT":"gatto", + "name_EN":"cat", + "version":"0.1", + "date":"2020-04-08", + "interface":{ + "base":{ + "available":"TRUE", + "icon":"cat.png" + }, + "intermediate":{ + "available":"TRUE", + "icon":"cat.png" + }, + "advanced":{ + "available":"TRUE", + "icon":"cat.png" + } + } + }, + "dog":{ + "category":"animal", + "name_IT":"cane", + "name_EN":"dog", + "version":"0.1", + "date":"2020-04-08", + "interface":{ + "base":{ + "available":"TRUE", + "icon":"dog.png" + }, + "intermediate":{ + "available":"TRUE", + "icon":"dog.png" + }, + "advanced":{ + "available":"TRUE", + "icon":"dog.png" + } + } + }, + + "piano":{ + "category":"instrument", + "name_IT":"pianoforte", + "name_EN":"piano", + "version":"0.1", + "date":"2020-04-08", + "interface":{ + "base":{ + "available":"TRUE", + "icon":"piano.png" + }, + "intermediate":{ + "available":"TRUE", + "icon":"piano.png" + }, + "advanced":{ + "available":"TRUE", + "icon":"piano.png" + } + } + }, + "piano":{ + "category":"instrument", + "name_IT":"pianoforte", + "name_EN":"piano", + "version":"0.1", + "date":"2020-04-08", + "interface":{ + "base":{ + "available":"TRUE", + "icon":"piano.png" + }, + "intermediate":{ + "available":"TRUE", + "icon":"piano.png" + }, + "advanced":{ + "available":"TRUE", + "icon":"piano.png" + } + } + }, + "guitar":{ + "category":"instrument", + "name_IT":"chitarra", + "name_EN":"guitar", + "version":"0.1", + "date":"2020-04-08", + "interface":{ + "base":{ + "available":"TRUE", + "icon":"guitar.png" + }, + "intermediate":{ + "available":"TRUE", + "icon":"guitar.png" + }, + "advanced":{ + "available":"TRUE", + "icon":"guitar.png" + } + } + }, + "flute":{ + "category":"instrument", + "name_IT":"flauto", + "name_EN":"flute", + "version":"0.1", + "date":"2020-04-08", + "interface":{ + "base":{ + "available":"TRUE", + "icon":"flute.png" + }, + "intermediate":{ + "available":"TRUE", + "icon":"flute.png" + }, + "advanced":{ + "available":"TRUE", + "icon":"flute.png" + } + } + } + + + + + + + + } +} diff --git a/sounds/notes/piano/audio.wav b/sounds/notes/piano/audio.wav new file mode 100644 index 00000000..5eaabb67 Binary files /dev/null and b/sounds/notes/piano/audio.wav differ diff --git a/sounds/notes/pig/audio.wav b/sounds/notes/pig/audio.wav new file mode 100644 index 00000000..63ddcf4c Binary files /dev/null and b/sounds/notes/pig/audio.wav differ diff --git a/sounds/notes/snake/audio.wav b/sounds/notes/snake/audio.wav new file mode 100644 index 00000000..39775e14 Binary files /dev/null and b/sounds/notes/snake/audio.wav differ diff --git a/start.sh b/start.sh index a8ab92dd..22c1db66 100755 --- a/start.sh +++ b/start.sh @@ -1,2 +1,2 @@ #!/bin/bash -LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/libatomic.so.1.2.0 python3 init.py +AUDIODEV=hw:1 LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/libatomic.so.1.2.0 python3 init.py diff --git a/test/musicPackage_test.py b/test/musicPackage_test.py new file mode 100644 index 00000000..65f4823f --- /dev/null +++ b/test/musicPackage_test.py @@ -0,0 +1,41 @@ +#__import__("../musicPackages") +import json +import sys +sys.path.insert(0, './') +import musicPackages +class MusicPackage_test: + + def test_musicPackage(self): + print("sample Music Package: ") + print(" name_IT = name_it, name_EN = name_en , category = sample_category, version = sample_version, date = sample_date, interfaces = sample_interfaces, nameID = sample_id") + + mpkg = musicPackages.MusicPackage(name_IT = "name_it", name_EN = "name_en", category= "sample_category", version= "sample_version", date="sample_date", nameID="sample_id") + print("name_IT : ", mpkg.getNameIT()) + print("name_EN : ", mpkg.getNameEN()) + print("nameID : ", mpkg.getNameID()) + print("version : ", mpkg.getVersion()) + print("date : ", mpkg.getDate()) + print("category : ", mpkg.getCategory()) + print("interfaces : ", mpkg.getInterfaces()) + + def test_isPackageAvaible(self): + pkg_manager = musicPackages.MusicPackageManager() + for package_name in pkg_manager.packages: + print("Test if " + package_name + " package is available") + result = pkg_manager.isPackageAvailable(package_name) + if(result): + print(package_name + " package is available") + else: + print(package_name + " package is not available") + + print("Test if NONE package is available" ) + result = pkg_manager.isPackageAvailable("NONE") + if(result): + print("NONE package is available") + else: + print("NONE package is not available") + +test = MusicPackage_test() +test.test_musicPackage() +test.test_isPackageAvaible() + diff --git a/test/music_test.py b/test/music_test.py new file mode 100644 index 00000000..b73a6b1b --- /dev/null +++ b/test/music_test.py @@ -0,0 +1,116 @@ +import sys +import sox +import time +import os +sys.path.insert(0, './') +from musicPackages import MusicPackageManager +from music import Music + +class Music_test: + + def test_library(self): + print("testing sound playback:...") + tfm = sox.Transformer() + tfm.preview('cat.wav') + tfm.build('cat.wav', 'outMusicDemo.wav') + +# test each parametr of the function play_note + def test_play_note(self): + musicPkg = MusicPackageManager() + m = Music(musicPkg) + print('test Music.play_note') + print("m.play_note(note='C2')") + m.play_note(note='C2') + print("m.play_note(note='C2',duration=2.0)") + m.play_note(note='C2',duration=2.0) + print("m.play_note(note='C2',instrument='guitar')") + m.play_note(note='C2',instrument='guitar') + print("m.play_note(note='C2',alteration='bmolle')") + m.play_note(note='C2',alteration='bmolle') + print("m.play_note(note='C2',alteration='diesis')") + m.play_note(note='C2',alteration='diesis') + print("m.play_note(note='C2',instrument='guitar')") + m.play_note(note='C2',instrument='guitar') + print("m.play_note(note='C2',alteration='bmolle')") + m.play_note(note='C2',alteration='bmolle') + print("m.play_note(note='C2',instrument='guitar',alteration='diesis')") + m.play_note(note='C2',instrument='guitar',alteration='diesis') + print("m.play_note(note='C2',instrument='guitar',alteration='diesis',duration=2.0)") + m.play_note(note='C2',instrument='guitar',alteration='diesis',duration=2.0) + print("m.play_note(note='G3',duration=2.0)") + m.play_note(note='G3',duration=2.0) + print("m.play_note(note='G3',instrument='guitar')") + m.play_note(note='G3',instrument='guitar') + print("m.play_note(note='G3',alteration='bmolle')") + m.play_note(note='G3',alteration='bmolle') + print("m.play_note(note='G3',alteration='diesis')") + m.play_note(note='G3',alteration='diesis') + print("m.play_note(note='G3',instrument='guitar')") + m.play_note(note='G3',instrument='guitar') + print("m.play_note(note='G3',alteration='bmolle')") + m.play_note(note='G3',alteration='bmolle') + print("m.play_note(note='G3',instrument='guitar',alteration='diesis')") + m.play_note(note='G3',instrument='guitar',alteration='diesis') + print("m.play_note(note='G3',instrument='guitar',alteration='diesis',duration=2.0)") + m.play_note(note='G3',instrument='guitar',alteration='diesis',duration=2.0) + print("it's ok if print: no instrument: coderInstrument present in this coderbot!") + m.play_note(note='C2',instrument='coderInstrument',alteration='diesis',duration=2.0) + print("it's ok if print: note: coderNote not exist") + m.play_note(note='coderNote',instrument='piano',alteration='diesis',duration=2.0) + + +# test each parametr of the function play_note + def test_play_animal(self): + print('test Music.play_animal') + musicPkg = MusicPackageManager() + m = Music(musicPkg) + print("(note='C2',instrument='cat', duration=2.0)") + m.play_animal(note='C2',instrument='cat', duration=2.0) + print("m.play_animal(note='C2',instrument='dog')") + m.play_animal(note='C2',instrument='dog') + print("m.play_animal(note='C2',instrument='dog', alteration='bmolle')") + m.play_animal(note='C2',instrument='dog', alteration='bmolle') + print("m.play_animal(note='C2',instrument='cat', alteration='diesis')") + m.play_animal(note='C2',instrument='cat', alteration='diesis') + print("m.play_animal(note='C2',instrument='dinosaur')") + m.play_animal(note='C2',instrument='dinosaur') + print("m.play_animal(note='C2',alteration='bmolle')") + m.play_animal(note='C2',instrument="dinosaur", alteration='bmolle') + print("m.play_animal(note='C2',instrument='cat',alteration='diesis')") + m.play_animal(note='C2',instrument='cat',alteration='diesis') + print("m.play_animal(note='C2',instrument='cat',alteration='diesis',duration=2.0)") + m.play_animal(note='C2',instrument='cat',alteration='diesis',duration=2.0) + print("m.play_note(note='G3',duration=2.0)") + m.play_note(note='G3',duration=2.0) + print("m.play_note(note='G3',instrument='dinosaur',alteration='bmolle')") + m.play_note(note='G3',instrument='dinosaur',alteration='bmolle') + print("m.play_note(note='G3',instrument='dinosaur',alteration='diesis')") + m.play_note(note='G3',instrument='dinosaur',alteration='diesis') + print("m.play_note(note='G3',alteration='bmolle', instrument= 'cat')") + m.play_note(note='G3',alteration='bmolle', instrument= 'cat') + print("m.play_note(note='G3',instrument='cat',alteration='diesis')") + m.play_note(note='G3',instrument='cat',alteration='diesis') + print("m.play_note(note='G3',instrument='cat',alteration='diesis',duration=2.0)") + m.play_note(note='G3',instrument='cat',alteration='diesis',duration=2.0) + print("it's ok if print: no instrument: coderInstrument present in this coderbot!") + m.play_animal(note='C2',instrument='coderInstrument',alteration='diesis',duration=2.0) + print("it's ok if print: note: coderNote not exist") + m.play_animal(note='coderNote',instrument='cat',alteration='diesis',duration=2.0) + print('test Music.play_note: ENDED') + + + def test_play_pause(self): + print('test Music.play_pause') + musicPkg = MusicPackageManager() + m = Music() + prrint("play pause") + m.play_pause(1.0) + prrint("play pause and note") + m.play_note(note='C2',instrument='guitar') + m.play_pause(2.0) + m.play_note(note='C2',instrument='guitar') + +test = Music_test() +test.test_play_note() +test.test_play_animal() +