diff options
author | florent <florent.pigout@gmail.com> | 2011-02-10 15:37:04 (GMT) |
---|---|---|
committer | florent <florent.pigout@gmail.com> | 2011-02-10 15:37:04 (GMT) |
commit | 1229ea068cba7a91b1459cc4ebd0cb638b33b68a (patch) | |
tree | d1231c16d8fcf8fcd9fe7c6500acad928d14b1b5 | |
parent | 0a99d76d34c9d98ad226cb5bef0243fa3aeec334 (diff) |
add some sound use samples
-rw-r--r-- | atoidepoc/tools/__init__.py | 0 | ||||
-rw-r--r-- | atoidepoc/tools/sound.py | 83 | ||||
-rw-r--r-- | atoidepoc/tools/storage.py | 137 | ||||
-rw-r--r-- | atoidepoc/ui/screens.py | 93 | ||||
-rw-r--r-- | atoidepoc/ui/toolbar.py | 21 | ||||
-rw-r--r-- | static/graphics/demo.png | bin | 0 -> 1196 bytes | |||
-rw-r--r-- | static/graphics/demo.svg | 232 |
7 files changed, 545 insertions, 21 deletions
diff --git a/atoidepoc/tools/__init__.py b/atoidepoc/tools/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/atoidepoc/tools/__init__.py diff --git a/atoidepoc/tools/sound.py b/atoidepoc/tools/sound.py new file mode 100644 index 0000000..be9c8c5 --- /dev/null +++ b/atoidepoc/tools/sound.py @@ -0,0 +1,83 @@ + +# python import +import gst, logging +from datetime import timedelta + +# get application logger +logger = logging.getLogger('atoidepoc') + + +class Player(object): + + def __init__(self, soundfile=None, loop=False): + # playing flag + self.playing = False + self.loop = loop + # player object + self.player = None + self._init_player() + # file to play + self._soundfile = soundfile + self.load() + + def _reload_cb(self, bus, message): + if slef.loop is True: + self.player.set_state(gst.STATE_READY) + self.player.set_state(gst.STATE_PLAYING) + else: + pass + + def _error_cb(self, bus, message): + self.player.set_state(gst.STATE_NULL) + + def _init_player(self): + # make player + self.player = gst.element_factory_make("playbin", "player") + # video fake + _fakesink = gst.element_factory_make('fakesink', "my-fakesink") + self.player.set_property("video-sink", _fakesink) + # bus .. + bus = self.player.get_bus() + bus.add_signal_watch() + bus.connect('message::eos', self._reload_cb) + bus.connect('message::error', self._error_cb) + + def serialize(self): + return file(self._soundfile, 'r').read() + + def load(self): + # little check + if self._soundfile is not None: + # load sound file + self.player.set_state(gst.STATE_NULL) + self.player.set_property('uri', 'file://' + self._soundfile) + else: + pass + + def get_duration(self): + # little check + if self._soundfile is not None: + # .. + _parser = gst.parse_launch("filesrc name=source ! decodebin2 ! fakesink") + # .. + _source = _parser.get_by_name("source") + _source.set_property("location", self._soundfile) + # .. + _parser.set_state(gst.STATE_PLAYING) + _parser.get_state() + # .. + _format = gst.Format(gst.FORMAT_TIME) + _duration = _parser.query_duration(_format)[0] + _parser.set_state(gst.STATE_NULL) + return timedelta(seconds=(_duration / gst.SECOND)) + else: + return None + + def play(self): + self.playing = True + self.player.set_state(gst.STATE_PLAYING) + + def pause(): + self.playing = False + self.player.set_state(gst.STATE_PAUSED) + diff --git a/atoidepoc/tools/storage.py b/atoidepoc/tools/storage.py new file mode 100644 index 0000000..83b812f --- /dev/null +++ b/atoidepoc/tools/storage.py @@ -0,0 +1,137 @@ + +# python import +import logging, os, time + +# gtk import +import gtk + +# sugar import +from sugar.activity import activity +from sugar.datastore import datastore + +# get application logger +logger = logging.getLogger('atoidepoc') + +ACTIVITY_NAMES = { + 'paint': 'org.laptop.Oficina', + 'record': 'org.laptop.RecordActivity', + } + + +def get_pixbuf_from_data(data, image_type=None, size=None): + # load it + if image_type: + _loader = gtk.gdk.PixbufLoader(image_type=image_type) + else: + _loader = gtk.gdk.PixbufLoader() + # size check + if size is None: + pass + else: + # parse size + _w, _h = size + # set loader size + _loader.set_size(_w, _h) + # load date + _loader.write(data) + # close loader + _loader.close() + # pix it + return _loader.get_pixbuf() + + +def get_journal_objects(activity_name): + # prepare query + _query = {'activity': ACTIVITY_NAMES[activity_name]} + # find in ds + _results, _count = datastore.find(_query, sorting='timestamp') + # return it + return _results + + +def list_info_from_journal(activity_name): + # get objects first + _objs = get_journal_objects(activity_name) + # make unique titles + _titles = {} + # return infos + for _o in _objs: + # get meta + _m = _o.get_metadata() + # get title + _t = _m['title'] + # ensure description + _d = _m['description'] if 'description' in _m else '' + # little check + if _t in _titles: + # udpate reg + _titles[_t] += 1 + # update value to show + _t = '%s (%s)' % (_t, _titles[_t]) + # init title reg + else: + _titles[_t] = 1 + + # DEBUG + logger.debug('[utils] _info_from_jnl - activity_id: %s' % _m['activity_id']) + logger.debug('[utils] _info_from_jnl - timestamp: %s' % _m['timestamp']) + # DEBUG + + # ensure info + yield { + 'activity_id' : _m['activity_id'], + 'description' : _d, + 'timestamp' : _m['timestamp'], + 'preview' : _m['preview'], + 'title' : _t, + } + + +def list_files_from_journal(activity_name): + # get objects first + _objs = get_journal_objects(activity_name) + # return paths + for _o in _objs: + # TODO open the files + yield _o.get_file_path() + + +def get_file_from_journal(activity_name, activity_id, timestamp): + # prepare query + _query = { + 'activity': ACTIVITY_NAMES[activity_name], + 'activity_id': activity_id, + 'timestamp': timestamp, + } + # find in ds + _results, _count = datastore.find(_query) + if _count == 1: + # get path + _path = _results[0].get_file_path() + else: + return None + + # ... + _temp = os.path.join('/home', 'florent', '%s.tmp' % activity_name) + + # DEBUG + logger.debug('[utils] _file_from_jnl - _temp: %s' % _temp) + # DEBUG + + # ... + os.link(_path, _temp) + + # DEBUG + logger.debug('[utils] _file_from_jnl - _path: %s' % _path) + # DEBUG + + _f = open(_temp) + + # DEBUG + logger.debug('[utils] _file_from_jnl - _len: %s' % len(_f.read())) + # DEBUG + + _f.close() + + # return it + return _results diff --git a/atoidepoc/ui/screens.py b/atoidepoc/ui/screens.py index eccafcc..2db1f99 100644 --- a/atoidepoc/ui/screens.py +++ b/atoidepoc/ui/screens.py @@ -11,7 +11,7 @@ from sugar.activity import activity from sugar.graphics import style # atoidepoc import -from atoidepoc.storage import utils +from atoidepoc.tools import sound, storage # get application logger logger = logging.getLogger('atoidepoc') @@ -19,11 +19,13 @@ logger = logging.getLogger('atoidepoc') class ScreenBrowser(gtk.HBox): - def __init__(self, toolbar, title=None): + def __init__(self, toolbar, title=None, _type=None): # init parent gtk.HBox.__init__(self) # keep toolbar self.toolbar = toolbar + # keep name + self._type = _type # add viewer self._add_viewer() self._add_list(title) @@ -41,12 +43,22 @@ class ScreenBrowser(gtk.HBox): def _get_store(self): # model: preview - description - activity_id - timestamp - return gtk.ListStore( + _store = gtk.ListStore( gtk.gdk.Pixbuf, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT ) + # app to get the journal entries + _app_name = 'paint' if self._type=='graphic' else 'record' + # update store + for _i in storage.list_info_from_journal(_app_name): + # prepare preview + _p = storage.get_pixbuf_from_data(_i['preview'], size=(64, 48)) + # do update + _store.append([_p, _i['title'], _i['activity_id'], _i['timestamp']]) + # return it + return _store def _add_list(self, title): # prepare colums @@ -82,26 +94,16 @@ class ScreenBrowserGraphics(ScreenBrowser): def __init__(self, toolbar): # init parent - ScreenBrowser.__init__(self, toolbar, title=_('Graphics')) - - def _get_store(self): - # get empty store - _store = ScreenBrowser._get_store(self) - # update store - for _i in utils.list_info_from_journal('paint'): - # prepare preview - _p = utils.get_pixbuf_from_data(_i['preview'], size=(64, 48)) - # do update - _store.append([_p, _i['title'], _i['activity_id'], _i['timestamp']]) - # return it - return _store + ScreenBrowser.__init__(self, toolbar, title=_('Graphics'), + _type='graphic') class ScreenBrowserSounds(ScreenBrowser): def __init__(self, toolbar): # init parent - ScreenBrowser.__init__(self, toolbar, title=_('Sounds')) + ScreenBrowser.__init__(self, toolbar, title=_('Sounds'), + _type='sound') class ScreenStory(gtk.Fixed): @@ -161,3 +163,60 @@ class ScreenStory(gtk.Fixed): self.show() # update toolbar self.toolbar.activity.set_canvas(self) + + +class ScreenPlayer(gtk.Fixed): + + def __init__(self, toolbar): + # init parent + gtk.Fixed.__init__(self) + # keep toolbar + self.toolbar = toolbar + # render + self.render() + # and show + self._show() + + def render(self): + pass + + def _show(self): + # show self + self.show() + # update toolbar + self.toolbar.activity.set_canvas(self) + + +class ScreenPlayerGraphics(ScreenPlayer): + + def __init__(self, toolbar): + # init parent + ScreenPlayer.__init__(self, toolbar) + + +class ScreenPlayerSounds(ScreenPlayer): + + def __init__(self, toolbar): + # init parent + ScreenPlayer.__init__(self, toolbar) + + def render(self): + # init 2 players + _s_player_1 = sound.Player(soundfile='/home/florent/shared/demo1.ogg') + _s_player_2 = sound.Player(soundfile='/home/florent/shared/demo2.ogg') + # get duration + _d1 = _s_player_1.get_duration() + + # DEBUG + logger.debug('[player_sound] render - _d1: %s' % _d1) + # DEBUG + + _d2 = _s_player_2.get_duration() + + # DEBUG + logger.debug('[player_sound] render - _d2: %s' % _d2) + # DEBUG + + # play together + _s_player_1.play() + _s_player_2.play() diff --git a/atoidepoc/ui/toolbar.py b/atoidepoc/ui/toolbar.py index 9d063fc..5caf66f 100644 --- a/atoidepoc/ui/toolbar.py +++ b/atoidepoc/ui/toolbar.py @@ -10,7 +10,6 @@ import gtk from sugar.graphics.toolbutton import ToolButton # atoidepoc import -from atoidepoc.storage import utils from atoidepoc.ui import screens # get application logger @@ -48,9 +47,9 @@ BUTTONS = { } TOOLBARS = { - 'graphic' : ['add'], - 'sound' : ['add'], - 'story' : ['open', 'play', ], + 'graphic' : ['add',], + 'sound' : ['add', 'play',], + 'story' : ['open', 'play',], } TITLES = { @@ -64,6 +63,7 @@ TITLES = { 'toolbar': _('Sound'), 'buttons': { 'add': _('Add Sound'), + 'play': _('Play Sound'), } }, 'story' : { @@ -91,9 +91,22 @@ class Toolbar(gtk.Toolbar): # add to parent _toolbox = self.activity.get_toolbox() _toolbox.add_toolbar(TITLES[self.name]['toolbar'], self) + # connect focus event + self.connect('focus', self._on_focus) # show self.show() + def _on_focus(self, widget, direction): + # screen factory + if self.name == 'graphic': + _cls = screens.ScreenPlayerGraphics + elif self.name == 'sound': + _cls = screens.ScreenPlayerSounds + elif self.name == 'story': + _cls = screens.ScreenStory + # do switch + _cls(self) + def _add_button(self, button_id): # little check if button_id in BUTTONS: diff --git a/static/graphics/demo.png b/static/graphics/demo.png Binary files differnew file mode 100644 index 0000000..af96edc --- /dev/null +++ b/static/graphics/demo.png diff --git a/static/graphics/demo.svg b/static/graphics/demo.svg new file mode 100644 index 0000000..bdfad6f --- /dev/null +++ b/static/graphics/demo.svg @@ -0,0 +1,232 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.0" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.47 r22583" + sodipodi:docname="activity-atoidepoc.svg" + width="55" + height="55" + inkscape:output_extension="org.inkscape.output.svg.inkscape"> + <metadata + id="metadata371"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + inkscape:window-height="882" + inkscape:window-width="1233" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + guidetolerance="10.0" + gridtolerance="10.0" + objecttolerance="10.0" + borderopacity="1.0" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" + inkscape:zoom="4.2923284" + inkscape:cx="63.342591" + inkscape:cy="51.710699" + inkscape:window-x="168" + inkscape:window-y="24" + inkscape:current-layer="svg2" + width="210mm" + height="40mm" + units="mm" + showgrid="false" + inkscape:window-maximized="0" /> + <defs + id="defs4"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 71.887497 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="486.04999 : 71.887497 : 1" + inkscape:persp3d-origin="243.02499 : 47.924998 : 1" + id="perspective46" /> + <linearGradient + id="linearGradient2795"> + <stop + style="stop-color: rgb(184, 184, 184); stop-opacity: 0.498039;" + offset="0" + id="stop2797" /> + <stop + style="stop-color: rgb(127, 127, 127); stop-opacity: 0;" + offset="1" + id="stop2799" /> + </linearGradient> + <linearGradient + id="linearGradient2787"> + <stop + style="stop-color: rgb(127, 127, 127); stop-opacity: 0.5;" + offset="0" + id="stop2789" /> + <stop + style="stop-color: rgb(127, 127, 127); stop-opacity: 0;" + offset="1" + id="stop2791" /> + </linearGradient> + <linearGradient + id="linearGradient3676"> + <stop + style="stop-color: rgb(178, 178, 178); stop-opacity: 0.5;" + offset="0" + id="stop3678" /> + <stop + style="stop-color: rgb(179, 179, 179); stop-opacity: 0;" + offset="1" + id="stop3680" /> + </linearGradient> + <linearGradient + id="linearGradient3236"> + <stop + style="stop-color: rgb(244, 244, 244); stop-opacity: 1;" + offset="0" + id="stop3244" /> + <stop + style="stop-color: white; stop-opacity: 1;" + offset="1" + id="stop3240" /> + </linearGradient> + <linearGradient + id="linearGradient4671"> + <stop + style="stop-color: rgb(255, 212, 59); stop-opacity: 1;" + offset="0" + id="stop4673" /> + <stop + style="stop-color: rgb(255, 232, 115); stop-opacity: 1;" + offset="1" + id="stop4675" /> + </linearGradient> + <linearGradient + id="linearGradient4689"> + <stop + style="stop-color: rgb(90, 159, 212); stop-opacity: 1;" + offset="0" + id="stop4691" /> + <stop + style="stop-color: rgb(48, 105, 152); stop-opacity: 1;" + offset="1" + id="stop4693" /> + </linearGradient> + <linearGradient + x1="224.23996" + y1="144.75717" + x2="-65.308502" + y2="144.75717" + id="linearGradient2987" + xlink:href="#linearGradient4671" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(100.27,99.6112)" /> + <linearGradient + x1="172.94208" + y1="77.475983" + x2="26.670298" + y2="76.313133" + id="linearGradient2990" + xlink:href="#linearGradient4689" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(100.27,99.6112)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4689" + id="linearGradient2587" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(100.27,99.6112)" + x1="172.94208" + y1="77.475983" + x2="26.670298" + y2="76.313133" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4671" + id="linearGradient2589" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(100.27,99.6112)" + x1="224.23996" + y1="144.75717" + x2="-65.308502" + y2="144.75717" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4689" + id="linearGradient2248" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(100.27,99.6112)" + x1="172.94208" + y1="77.475983" + x2="26.670298" + y2="76.313133" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4671" + id="linearGradient2250" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(100.27,99.6112)" + x1="224.23996" + y1="144.75717" + x2="-65.308502" + y2="144.75717" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4671" + id="linearGradient2255" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.562541,0,0,0.567972,-11.5974,-7.60954)" + x1="224.23996" + y1="144.75717" + x2="-65.308502" + y2="144.75717" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4689" + id="linearGradient2258" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.562541,0,0,0.567972,-11.5974,-7.60954)" + x1="172.94208" + y1="76.176224" + x2="26.670298" + y2="76.313133" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient2795" + id="radialGradient2801" + cx="61.518883" + cy="132.28575" + fx="61.518883" + fy="132.28575" + r="29.036913" + gradientTransform="matrix(1,0,0,0.177966,0,108.743)" + gradientUnits="userSpaceOnUse" /> + </defs> + <g + id="g2847" + transform="matrix(0.46766264,0,0,0.46766264,-1.1078811,-1.5517981)"> + <path + id="path1948" + d="m 60.510156,6.3979729 c -4.583653,0.021298 -8.960939,0.4122177 -12.8125,1.09375 C 36.35144,9.4962267 34.291407,13.691825 34.291406,21.429223 l 0,10.21875 26.8125,0 0,3.40625 -26.8125,0 -10.0625,0 c -7.792459,0 -14.6157592,4.683717 -16.7500002,13.59375 -2.46182,10.212966 -2.5710151,16.586023 0,27.25 1.9059283,7.937852 6.4575432,13.593748 14.2500002,13.59375 l 9.21875,0 0,-12.25 c 0,-8.849902 7.657144,-16.656248 16.75,-16.65625 l 26.78125,0 c 7.454951,0 13.406253,-6.138164 13.40625,-13.625 l 0,-25.53125 c 0,-7.266339 -6.12998,-12.7247775 -13.40625,-13.9375001 -4.605987,-0.7667253 -9.385097,-1.1150483 -13.96875,-1.09375 z m -14.5,8.2187501 c 2.769547,0 5.03125,2.298646 5.03125,5.125 -2e-6,2.816336 -2.261703,5.09375 -5.03125,5.09375 -2.779476,-1e-6 -5.03125,-2.277415 -5.03125,-5.09375 -1e-6,-2.826353 2.251774,-5.125 5.03125,-5.125 z" + style="fill:#000000;fill-opacity:1" /> + <path + id="path1950" + d="m 91.228906,35.054223 0,11.90625 c 0,9.230755 -7.825895,16.999999 -16.75,17 l -26.78125,0 c -7.335833,0 -13.406249,6.278483 -13.40625,13.625 l 0,25.531247 c 0,7.26634 6.318588,11.54032 13.40625,13.625 8.487331,2.49561 16.626237,2.94663 26.78125,0 6.750155,-1.95439 13.406253,-5.88761 13.40625,-13.625 l 0,-10.218747 -26.78125,0 0,-3.40625 26.78125,0 13.406254,0 c 7.79246,0 10.69625,-5.435408 13.40624,-13.59375 2.79933,-8.398886 2.68022,-16.475776 0,-27.25 -1.92578,-7.757441 -5.60387,-13.59375 -13.40624,-13.59375 l -10.062504,0 z m -15.0625,64.65625 c 2.779478,3e-6 5.03125,2.277417 5.03125,5.093747 -2e-6,2.82635 -2.251775,5.125 -5.03125,5.125 -2.76955,0 -5.03125,-2.29865 -5.03125,-5.125 2e-6,-2.81633 2.261697,-5.093747 5.03125,-5.093747 z" + style="fill:#000000;fill-opacity:1" /> + </g> +</svg> |