Exemplo n.º 1
0
    def _setup_pipeline(self, fpath):
        fpathnz = fpath.replace(' ', '_')
        gst.debug('_setup_pipeline: %r' % (fpath,))

        self.ppl = gst.Pipeline('D-%s' % fpathnz)

        src = gst.element_make_from_uri(gst.URI_SRC, fpath, 'src-%s' % fpathnz)
        if not src:
            gst.warning('No element to access: %r' % fpath)
            self._finish(AnalysisError('No element to access the URI.'))
            return False

        dbin = gst.element_factory_make('decodebin2', 'dbin')
        self._connect(dbin, 'new-decoded-pad', self._cb_new_decoded_pad)
        self._connect(dbin, 'no-more-pads', self._cb_no_more_pads)
        self._connect(dbin, 'unknown-type', self._cb_unknown_type)

        tfind = dbin.get_by_name('typefind')
        self._connect(tfind, 'have-type', self._cb_have_type)
        self._connect(tfind.get_pad('src'),
                      'notify::caps', self._cb_notify_caps_tfind)

        self.ppl.add(src, dbin)
        src.link(dbin)

        gst.debug('pipeline created')

        self.bus = self.ppl.get_bus()
        self._connect(self.bus, 'message', self._cb_bus_message)

        self.bus.add_signal_watch()

        return True
def getInstallableCodecsUbuntu():
  import warnings
  warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning)
  import apt

  codecs = []

  try:
    apt_cache = apt.Cache()
  except:
    gst.warning('Failed to read APT cache')
    return []

  #import time
  #now = time.time()
  for pkg in apt_cache:
    # check only packages that are releated to gstreamer
    # this is a performance hack that brings this code from 30s
    # to 1s on cold cache
    if (not "gstreamer" in pkg.name or 
        pkg.isInstalled or 
        not pkg.candidateDownloadable):
      continue
    record = pkg.candidateRecord
    if not record:
      continue
    if not record.has_key("Gstreamer-Version"):
      continue
    if record.has_key("Gstreamer-Decoders"):
      codec_list = record["Gstreamer-Decoders"].split(";")
      codecs.extend([item.split(",")[0].strip() for item in codec_list])
  #print time.time() - now
    
  return codecs
Exemplo n.º 3
0
 def _dataProbeCb(self, pad, data):
     if isinstance(data, gst.Buffer):
         gst.warning("Saw buffer %s (dur:%s) => %s" % (gst.TIME_ARGS(data.timestamp),
                                                       gst.TIME_ARGS(data.duration),
                                                       gst.TIME_ARGS(data.timestamp+data.duration)))
         self._lastBuffer = data
     return GnlFileSourceTest._dataProbeCb(self, pad, data)
Exemplo n.º 4
0
 def timeout_cb(self):
     """
     Callback for timeout, used in case tag messages do not include
     all the information required by self.req_keys.
     """
     gst.warning('Timed out before getting tag for %s' % self.pbin.get_property('uri'))
     self.quit()
     return False
Exemplo n.º 5
0
    def queue_del(self,uri=None,pos=-1):
        """Remove an item from the queue. Item can be selected
        either by URI or by pos (position) in the queue.

        Removing the currently playing element will not stop playback.
        """
        ans = [200]
        ind = -1
        if uri:
            try:
                elem = self.queue_item_by_uri(uri)
                self.queue.index(elem)
                self.queue.remove(uri)
                ans.append('Removed element %s' % uri)
            except (ValueError, StopIteration) as e:
                err_msg = 'Exception:%s' % e.__str__()
                gst.warning(err_msg)
                ans = [400]
                ans.append(err_msg)
        elif pos >= 0:
            try:
                ind = pos
                del self.queue[pos]
                ans.append('Removed element at queue[%d]' % pos)
            except IndexError as e:
                err_msg = 'Failed to remove at %d. Exception:%s' % (pos,e.__str__())
                gst.warning(err_msg)
                ans = [400]
                ans.append(err_msg)
        try:
            if ans[0] == 200:
                if ind < self.queue_pos:
                    # update queue_pos to new queue size
                    self.queue_pos -= 1
                elif ind == self.queue_pos:
                    # check if currently selected item was deleted
                    if not ind and self.queue:
                        # special case, first element was removed and
                        # more are left, set queue_pos to head
                        self.queue_pos = 0
                    if self.queue_pos >= 0:
                        uri_new = self.queue[self.queue_pos]['uri']
                        get.debug('setting uri to %s' % uri_new)
                        self.player.set_location(uri_new)
                    else:
                        # queue is empty now
                        self.player.set_location(None)
        except Exception as e:
            print e
            err_msg = 'Problem near update queue_pos. Exception:%s' % e.__str__()
            gst.error(err_msg)
            ans = [400]
            ans.append(err_msg)
        if ans[0] == 200 and len(ans) > 1:
            # call to get debug output
            self.queue_get()
        return ans
Exemplo n.º 6
0
    def _notify_caps_cb(self, pad, args):
        caps = pad.get_negotiated_caps()
        if not caps:
            pad.info("no negotiated caps available")
            return
        pad.info("caps:%s" % caps.to_string())
        # the caps are fixed
        # We now get the total length of that stream
        q = gst.query_new_duration(gst.FORMAT_TIME)
        pad.info("sending position query")
        if pad.get_peer().query(q):
            format, length = q.parse_duration()
            pad.info("got position query answer : %d:%d" % (length, format))
        else:
            length = -1
            gst.warning("position query didn't work")

        # We store the caps and length in the proper location
        if "audio" in caps.to_string():
            self.audiocaps = caps
            self.audiolength = length
            try:
                pos = 0
                cap = caps[pos]
                while not cap.has_key("rate"):
                    pos += 1
                    cap = caps[pos]
                self.audiorate = cap["rate"]
                self.audiowidth = cap["width"]
                self.audiochannels = cap["channels"]
            except IndexError:
                pass
            if "x-raw-float" in caps.to_string():
                self.audiofloat = True
            else:
                self.audiodepth = caps[0]["depth"]
            if self._nomorepads and ((not self.is_video) or self.videocaps):
                _log.debug("called @1")
                self._finished(True)
        elif "video" in caps.to_string():
            self.videocaps = caps
            self.videolength = length
            try:
                pos = 0
                cap = caps[pos]
                while not cap.has_key("width"):
                    pos += 1
                    cap = caps[pos]
                self.videowidth = cap["width"]
                self.videoheight = cap["height"]
                self.videorate = cap["framerate"]
            except IndexError:
                pass
            if self._nomorepads and ((not self.is_audio) or self.audiocaps):
                _log.debug("called @2")
                self._finished(True)
Exemplo n.º 7
0
    def _notify_caps_cb(self, pad, args):
        caps = pad.get_negotiated_caps()
        if not caps:
            pad.info("no negotiated caps available")
            return
        pad.info("caps:%s" % caps.to_string())
        # the caps are fixed
        # We now get the total length of that stream
        q = gst.query_new_duration(gst.FORMAT_TIME)
        pad.info("sending position query")
        if pad.get_peer().query(q):
            format, length = q.parse_duration()
            pad.info("got position query answer : %d:%d" % (length, format))
        else:
            length = -1
            gst.warning("position query didn't work")

        # We store the caps and length in the proper location
        if "audio" in caps.to_string():
            self.audiocaps = caps
            self.audiolength = length
            try:
                pos = 0
                cap = caps[pos]
                while not cap.has_key("rate"):
                    pos += 1
                    cap = caps[pos]
                self.audiorate = cap["rate"]
                self.audiowidth = cap["width"]
                self.audiochannels = cap["channels"]
            except IndexError:
                pass
            if "x-raw-float" in caps.to_string():
                self.audiofloat = True
            else:
                self.audiodepth = caps[0]["depth"]
            if self._nomorepads and ((not self.is_video) or self.videocaps):
                self._finished(True)
        elif "video" in caps.to_string():
            self.videocaps = caps
            self.videolength = length
            try:
                pos = 0
                cap = caps[pos]
                while not cap.has_key("width"):
                    pos += 1
                    cap = caps[pos]
                self.videowidth = cap["width"]
                self.videoheight = cap["height"]
                self.videorate = cap["framerate"]
            except IndexError:
                pass
            if self._nomorepads and ((not self.is_audio) or self.audiocaps):
                self._finished(True)
Exemplo n.º 8
0
 def on_sync_message(self, bus, message):
     if message.structure is None:
         return
     message_name = message.structure.get_name()
     if message_name == 'prepare-xwindow-id':
         # Assign the viewport
         imagesink = message.src
         imagesink.set_property('force-aspect-ratio', True)
         try:
             imagesink.set_xwindow_id(self.draw_window.window.xid)
         except:
             gst.warning("Couldn't set the XID on our video sink !")
Exemplo n.º 9
0
 def remoteTest(self):
     # kickstart pipeline to initial state
     PythonDBusTest.remoteTest(self)
     debug("Setting pipeline to initial state %r", self.__pipeline_initial_state__)
     gst.log("Setting pipeline to initial state %r" % self.__pipeline_initial_state__)
     res = self.pipeline.set_state(self.__pipeline_initial_state__)
     debug("set_state returned %r", res)
     gst.log("set_state() returned %r" % res)
     self.validateStep("pipeline-change-state", not res == gst.STATE_CHANGE_FAILURE)
     if res == gst.STATE_CHANGE_FAILURE:
         warning("Setting pipeline to initial state failed, stopping test")
         gst.warning("State change failed, stopping")
         self.stop()
Exemplo n.º 10
0
 def on_message(self, bus, message):
     t = message.type
     if t == gst.MESSAGE_ERROR:
         err, debug = message.parse_error()
         print "Error: %s" % err, debug
         self.stop()
     elif t == gst.MESSAGE_EOS:
         gst.info("File playback completed")
         ok,moved = self.cb_eos()
         if ok:
             gst.debug('eos callback completed, moved queue %d places' % moved)
         else:
             gst.warning('eos callback failed!')
Exemplo n.º 11
0
    def switch(self, padname):
        switch = self.pipeline.get_by_name('s')
        stop_time = switch.emit('block')
        newpad = switch.get_static_pad(padname)
        start_time = newpad.get_property('running-time')
        
        gst.warning('stop time = %d' % (stop_time,))
        gst.warning('stop time = %s' % (gst.TIME_ARGS(stop_time),))

        gst.warning('start time = %d' % (start_time,))
        gst.warning('start time = %s' % (gst.TIME_ARGS(start_time),))

        gst.warning('switching from %r to %r'
                    % (switch.get_property('active-pad'), padname))
        switch.emit('switch', newpad, stop_time, start_time)
Exemplo n.º 12
0
 def _padElement(self, pad, direction):
     if not pad:
         gst.warning("GStreamer internal behavior changed, "
                     + "cannot properly crawl the pipline")
         return None
     if isinstance(pad, gst.GhostPad):
         return self._padElement(pad.get_target(), direction)
     if pad.get_direction() == direction:
         return self._padElement(pad.get_peer(), direction)
     parent = pad.get_parent()
     if parent == None:
         gst.warning("GStreamer internal behavior changed, "
                     + "cannot properly crawl the pipline")
         return None
     if isinstance(parent, gst.GhostPad):
         return self._padElement(parent.get_peer(), direction)
     return parent
Exemplo n.º 13
0
    def _notify_caps_cb(self, pad, args):
        self.discovered_cond.acquire()

        caps = pad.get_negotiated_caps()
        if not caps:
            pad.info("no negotiated caps available")
            self.discovered = True
            self.discovered_cond.notify()
            self.discovered_cond.release()
            return
        # the caps are fixed
        # We now get the total length of that stream
        q = gst.query_new_duration(gst.FORMAT_TIME)
        pad.info("sending duration query")
        if pad.get_peer().query(q):
            format, length = q.parse_duration()
            if format == gst.FORMAT_TIME:
                pad.info("got duration (time) : %s" % (gst.TIME_ARGS(length),))
            else:
                pad.info("got duration : %d [format:%d]" % (length, format))
        else:
            length = -1
            gst.warning("duration query failed")

        # We store the caps and length in the proper location
        if "audio" in caps.to_string():
            self.input_samplerate = caps[0]["rate"]
            if not self.output_samplerate:
                self.output_samplerate = self.input_samplerate
            self.input_channels = caps[0]["channels"]
            if not self.output_channels:
                self.output_channels = self.input_channels
            self.input_duration = length / gst.SECOND

            self.input_totalframes = int(
                self.input_duration * self.input_samplerate)
            if "x-raw-float" in caps.to_string():
                self.input_width = caps[0]["width"]
            else:
                self.input_width = caps[0]["depth"]

        self.discovered = True
        self.discovered_cond.notify()
        self.discovered_cond.release()
Exemplo n.º 14
0
    def _notify_caps_cb(self, pad, args):
        caps = pad.get_negotiated_caps()
        if not caps:
            pad.info("no negotiated caps available")
            return
        pad.info("caps:%s" % caps.to_string())
        # the caps are fixed
        # We now get the total length of that stream
        q = gst.query_new_duration(gst.FORMAT_TIME)
        pad.info("sending duration query")
        if pad.get_peer().query(q):
            format, length = q.parse_duration()
            if format == gst.FORMAT_TIME:
                pad.info("got duration (time) : %s" %
                         (gst.TIME_ARGS(length), ))
            else:
                pad.info("got duration : %d [format:%d]" % (length, format))
        else:
            length = -1
            gst.warning("duration query failed")

        # We store the caps and length in the proper location
        if "audio" in caps.to_string():
            self.audiocaps = caps
            self.audiolength = length
            self.audiorate = caps[0]["rate"]
            self.audiowidth = caps[0]["width"]
            self.audiochannels = caps[0]["channels"]
            if "x-raw-float" in caps.to_string():
                self.audiofloat = True
            else:
                self.audiodepth = caps[0]["depth"]
            if self._nomorepads and ((not self.is_video) or self.videocaps):
                self._finished(True)
        elif "video" in caps.to_string():
            self.videocaps = caps
            self.videolength = length
            self.videowidth = caps[0]["width"]
            self.videoheight = caps[0]["height"]
            self.videorate = caps[0]["framerate"]
            if self._nomorepads and ((not self.is_audio) or self.audiocaps):
                self._finished(True)
Exemplo n.º 15
0
    def _notify_caps_cb(self, pad, args):
        caps = pad.get_negotiated_caps()
        if not caps:
            pad.info("no negotiated caps available")
            return
        pad.info("caps:%s" % caps.to_string())
        # the caps are fixed
        # We now get the total length of that stream
        q = gst.query_new_duration(gst.FORMAT_TIME)
        pad.info("sending duration query")
        if pad.get_peer().query(q):
            format, length = q.parse_duration()
            if format == gst.FORMAT_TIME:
                pad.info("got duration (time) : %s" % (gst.TIME_ARGS(length),))
            else:
                pad.info("got duration : %d [format:%d]" % (length, format))
        else:
            length = -1
            gst.warning("duration query failed")

        # We store the caps and length in the proper location
        if "audio" in caps.to_string():
            self.audiocaps = caps
            self.audiolength = length
            self.audiorate = caps[0]["rate"]
            self.audiowidth = caps[0]["width"]
            self.audiochannels = caps[0]["channels"]
            if "x-raw-float" in caps.to_string():
                self.audiofloat = True
            else:
                self.audiodepth = caps[0]["depth"]
            if self._nomorepads and ((not self.is_video) or self.videocaps):
                self._finished(True)
        elif "video" in caps.to_string():
            self.videocaps = caps
            self.videolength = length
            self.videowidth = caps[0]["width"]
            self.videoheight = caps[0]["height"]
            self.videorate = caps[0]["framerate"]
            if self._nomorepads and ((not self.is_audio) or self.audiocaps):
                self._finished(True)
Exemplo n.º 16
0
    def get_peak_dB(self, channel=None):
        """
        Get the list of peak values for the given channel, in dB.
        If no channel specified, take peak over all channels.

        @param channel: channel number to get peak values for, starting from 0
        @type  channel: int or None

        @returns: the peak level graph in dB
        @rtype:   L{level.Level}
        """
        if channel is not None:
            return self.peakdBs[channel]

        peak = level.Level(scale=level.SCALE_DECIBEL)

        for i, (endtime, v) in enumerate(self.peakdBs[0]):
            maxdB = max([l[i][1] for l in self.peakdBs])
            if maxdB > 0.0:
                gst.warning('maxdB higher than unity: %r dB' % maxdB)
            peak.append((endtime, maxdB))

        return peak
Exemplo n.º 17
0
    def handle_cmd(self, msg):
        """
        Receives a msg and executes it if it corresponds to a registered cmd

        Return values:
          - If successful: [200,data_returned_by_cmd]
          - else: [err_code,err_msg]
        """
        if self.src == 'zmq':
            cmd,cmd_code,args = shared.json_server_dec(msg)
            gst.debug('dec: cmd_name=%s,'\
                          'cmd_code=%d,args=%s' % (cmd,cmd_code,args.__str__()))
        else:
            words       = msg.split()
            cmd         = words[0]
            cmd_code    = words[-1]
            args        = []
        cmd_code_dic= 0
        ans         = [200] # default to OK

        if not self.is_registered(cmd) or (self.src == 'stdin' and len(words) < 2):
            gst.error("Error: Invalid command: %s, Ignoring...\n" % cmd)
            help_msg = self.help_msg()
            if(self.src == 'stdin'):
                print help_msg
            ans = [401]
            ans.append(help_msg)
        else:
            # first arg is command name, last is cmd if
            if self.src == 'stdin':
                # if src is zmq, then json_server_dec() took
                # care of fetching arguments for command
                args = words[1:-1]
                try:
                    # convert from string to int
                    cmd_code = int(cmd_code)
                except ValueError as e:
                    gst.warning('int(cmd_code) failed!Exception:%s' % e.__str__())
            try:
                # get command id from dict, compare with rx id (must match)
                gst.debug('Matching command id with dict values...')
                cmd_code_dic = shared.cmd_name_id[cmd]
                try:
                    # check matching
                    if cmd_code_dic != cmd_code:
                        gst.error('Command code received %d does not match dict %d'
                                    % (cmd_code,cmd_code_dic))
                    else:
                        gst.debug('Command id matched!')
                    try:
                        if(args):
                            gst.debug('Executing cmd=%s with args=%s' % (cmd,args))
                            args = args[0]
                            if cmd == 'queue_add':
                                ans = list(self.queue_add(args))
                            elif cmd == 'queue_del':
                                param = -1
                                try:
                                    param = int(args)
                                except ValueError as e:
                                    gst.debug('Param is not int. Exception:%s' % e.__str__())
                                if not param == -1:
                                    ans = list(self.queue_del(pos=param))
                                else:
                                    ans = list(self.queue_del(uri=args))
                            #TODO implement generic multi arg command and support for multi load (queue)
                            # ans = self.fire(cmd,args)
                        else:
                            gst.debug('Executing cmd=%s without args' % cmd)
                            ans = list(self.fire(cmd))
                    except ValueError as ve:
                        print 'Exception:',ve
                    except Exception, e:
                        print 'Exception:',e
                        gst.error('Problem near cmd execution: %s' % msg)
                        ans = [402]
                except Exception as e:
                    print 'Exception:',e
                    gst.error('Problem near command id matching: (rx,dict)=(%d,%d)' % (cmd_code,cmd_code_dic))
            except Exception as e:
                print 'Exception:',e
                gst.error('Problem near: find Id for cmd: %s' % cmd)

        # Take cmd result and prepare answer to send to client
        gst.debug('ans(len=%d)=%s' % (len(ans),ans))
        assert(len(ans) == 1 or len(ans) == 2) # (code, data)
        data = []
        if len(ans) == 2:
            data = ans[1]
        return shared.json_server_enc(cmd_code, ans[0], data)
Exemplo n.º 18
0
    def queue_add(self, location):
        """
        Adds location to the play queue.

        NOTES:
          - location must be a valid URI
          - If self.verify_on_load==True, then location
          can be a directory. All .mp3 files from the
          directory will be loaded.

        Return values:
          - If successful: [200]
          - else: [err_code,[err_msg]].
        """
        ans = [200]
        is_dir = False
        is_ascii = True
        # ignore non-ascii stuff
        try:
            unicode(location)
        except UnicodeDecodeError as e:
            is_ascii = False
            gst.warning('Ignoring %s, not ascii' % location)
            ans = [406]
            ans.append(e.__str__())
        if not is_ascii or not gst.uri_is_valid(location):
            if is_ascii:
                gst.error("Error: Invalid URI: %s\nExpected uri"
                      "like file:///home/foo/bar.mp3\nIgnoring...\n" % location)
                ans = [403]
        else:
            # if(self.player.status()):
            #     self.queued = True
            gst.debug('URI is valid: %s' % location)
            err_msg = []
            code = 0
            msg  = ''
            if self.verify_on_load:
                gst.debug('Attempting to verify %s' % location)
                if location[0:4] == 'file':
                    path = location[7:]
                    try:
                        with open(path) as f: pass
                    except IOError as e:
                        if e.errno == 21:
                            is_dir = True
                            loaded = []
                            try:
                                # is directory, load content
                                os.chdir(path)
                                for f in os.listdir('.'):
                                    if f.endswith('.mp3'):
                                        full_path = location+'/'+f
                                        res = self.queue_add(full_path)
                                        if res[0] == 200:
                                            loaded.append(full_path)
                                ans.append(loaded)
                            except IOError as e:
                                err_msg = 'Error parsing directory, will'\
                                    'stop loading, exception:%s' % e.__str__()
                                gst.error(err_msg)
                                ans = [404]
                                ans.append(err_msg)
                        else:
                            err_msg = 'Will not load, exception when opening'\
                                '%s: %s' % (path,e.__str__())
                            gst.error(err_msg)
                            ans = [404]
                            ans.append(err_msg)
                elif location[0:4] == 'http':
                    try:
                        urlopen_ans  = urlopen(location)
                        code = urlopen_ans.code
                        msg  = urlopen_ans.msg
                        if code >= 400:
                            err_msg = 'urlopen failed with %d: %s' % (code,msg)
                    except:
                        err_msg = 'urlopen() failed'
                    if err_msg:
                        ans = [400]
                        ans.append(err_msg)
                if not err_msg:
                    gst.debug('Verification succeeded!')
            if err_msg:
                gst.warning(err_msg)
            elif not is_dir:
                gst.debug('Setting location to %s' % location)
                try:
                    if location in self.queue:
                        gst.info('Duplicate entry %s' % location)
                    self.queue.append({'uri':location,'tags':{}})
                    try:
                        gst.debug('will prepare tag getter: get_tags(%s)' % location)
                        tgt = threading.Thread(target=tagget.get_tags,
                                               args=[self.queue[-1]['tags'],
                                                     location])
                        gst.debug('will start tag getter')
                        tgt.start()

                    except Exception as e:
                        err_msg = 'Problem near tag get thread. Exception:%s' % e.__str__()
                        gst.warning(err_msg)
                    # call to print current queue
                    self.queue_get()
                    if self.queue_pos == -1:
                        gst.debug('New queue, will next()')
                        ans_n = self.queue_next()
                        if ans_n[0] == 200:
                            gst.debug('New queue play success!')
                        else:
                            ans = [400]
                            ans.append('Failed to set initial queue position')
                except Exception as e:
                    print e
                    ans = [400]
                    gst.error('Problem near queue.append()')
        return ans
Exemplo n.º 19
0
    def _eos_cb(self, source):
        gst.debug("eos, start calcing")

        # get the highest peak RMS for this track
        highestdB = self._peaksdB[0][1]

        for (time, peakdB) in self._peaksdB:
            if peakdB > highestdB:
                highestdB = peakdB
        gst.debug("highest peak(dB): %f" % highestdB)

        # get the length
        (self.length, peakdB) = self._peaksdB[-1]
        
        # find the mix in point
        for (time, peakdB) in self._peaksdB:
            gst.log("time %s, peakdB %f" % (gst.TIME_ARGS(time), peakdB))
            if peakdB > self._thresholddB + highestdB:
                gst.debug("found mix-in point of %f dB at %s" % (
                    peakdB, gst.TIME_ARGS(time)))
                self.mixin = time
                break

        # reverse and find out point
        self._peaksdB.reverse()
        found = None
        for (time, peakdB) in self._peaksdB:
            if found:
                self.mixout = time
                gst.debug("found mix-out point of %f dB right before %s" % (
                    found, gst.TIME_ARGS(time)))
                break
                
            if peakdB > self._thresholddB + highestdB:
                found = peakdB

        # now calculate RMS between these two points
        weightedsquaresums = 0.0
        lasttime = self.mixin
        for (time, meansquaresum) in self._meansquaresums:
            if time <= self.mixin:
                continue

            delta = time - lasttime
            weightedsquaresums += meansquaresum * delta
            gst.log("added MSS %f over time %s at time %s, now %f" % (
                meansquaresum, gst.TIME_ARGS(delta),
                gst.TIME_ARGS(time), weightedsquaresums))

            lasttime = time
            
            if time > self.mixout:
                break

        # calculate
        try:
            ms = weightedsquaresums / (self.mixout - self.mixin)
        except ZeroDivisionError:
            # this is possible when, for example, the whole sound file is
            # empty
            gst.warning('ZeroDivisionError on %s, mixin %s, mixout %s' % (
                self._filename, gst.TIME_ARGS(self.mixin),
                gst.TIME_ARGS(self.mixout)))
            self.emit('done', WRONG_TYPE)
            return

        self.rms = math.sqrt(ms)
        self.rmsdB = 10 * math.log10(ms)

        self.emit('done', EOS)