def clipping_rate(self, factor): """ Return the clipping rate of the frames. @param factor (float) An interval to be more precise on clipping rate. It will consider that all frames outside the interval are clipped. Factor has to be between 0 and 1. @return the clipping rate """ if self.sampwidth == 4 : data = struct.unpack("<%ul" % (len(self.frames) / 4), self.frames) elif self.sampwidth == 2 : data = struct.unpack("<%uh" % (len(self.frames) / 2), self.frames) else : data = struct.unpack("%uB" % len(self.frames), self.frames) data = [ s - 128 for s in data ] maxval = audioutils.get_maxval(self.sampwidth)*(factor/2.) minval = audioutils.get_minval(self.sampwidth)*(factor/2.) nbclipping = 0 for i in xrange(len(data)): if data[i] >= maxval or data[i] <= minval: nbclipping = nbclipping + 1 return float(nbclipping)/len(data)
def _sampleCalculator(self, channels, pos, sampwidth, factors, attenuator): """ Return the sample value, applying a factor and an attenuator. @param channels (Channel[]) the list of channels @param pos (int) the position of the sample to calculate @param sampwidth (int) the sample width @param factors (float[]) the list of factors to apply to each sample of a channel (1 channel = 1 factor) @param attenuator (float) a factor to apply to each sum of samples @return the value of the sample calculated (float) """ # variables to compare the value of the result sample to avoid clipping minval = audioutils.get_minval(sampwidth) maxval = audioutils.get_maxval(sampwidth) # the result sample is the sum of each sample with the application of the factors sampsum = 0 for factor,channel in zip(factors,channels): data = channel.frames[pos:pos+sampwidth] data = audioutils.unpack_data(data, sampwidth) # without a cast, sum is a float! sampsum += data[0]*factor*attenuator # truncate the values if there is clipping if sampsum < 0: return max(sampsum,minval) elif sampsum > 0: return min(sampsum,maxval) return 0