(self, length)
return chunk
Build a sound chunk.
Build a sound chunk.
Build a sound chunk .
def build_chunk(self, length):
        """Build a sound chunk."""
        self._signal_source.feedback = self._feedback
        if self._count_samples >= self._num_samples:
            # done already
            return None
        # don't generate too many samples
        if length + self._count_samples > self._num_samples and not self.loop:
            length = (self._num_samples - self._count_samples)
        if self._frequency == 32767:
            self._frequency = 0
        # work on last element of sound queue
        if self._frequency == 0:
            chunk = bytearray(length)
        else:
            half_wavelength = SAMPLE_RATE / (2.*self._frequency)
            # generate first half-wave so as to complete the last one played
            if self._signal_source.phase:
                first_length = int(half_wavelength * self._signal_source.phase)
                first_half_wave = bytearray([self._signal_source.bit]) * first_length * _RESOLUTION
                length -= first_length
                self._signal_source.phase = 0.
            else:
                first_half_wave = bytearray()
            num_half_waves = int(ceil(length / half_wavelength))
            # generate bits
            bits = (
                self._signal_source.next()
                for _ in range(num_half_waves)
            )
            # do sampling by averaging the signal over bins of given resolution
            # this allows to use vectors all the way
            # which is *much* faster than looping over an array
            # stretch array by half_wavelength * _RESOLUTION
            stretch = int(half_wavelength * _RESOLUTION)
            waves = bytearray().join(bytearray([_b]) * stretch for _b in bits)
            matrix = bytearray().join((first_half_wave, waves))
            # cut off on round number of resolution blocks
            use_length = len(matrix) - (len(matrix) % _RESOLUTION)
            # average over blocks
            # sums are between 0 and RESOLUTION, inclusive
            sums = (
                sum(matrix[_i:_i+_RESOLUTION])
                for _i in xrange(0, use_length, _RESOLUTION)
            )
            # scale to signed amplitude
            half_res = _RESOLUTION // 2
            averages = ((_s - half_res) * self._amplitude // _RESOLUTION for _s in sums)
            # pack signed bytes into bytearray
            chunk = bytearray(_sb if _sb >= 0 else 0xff + _sb for _sb in averages)
        if not self.loop:
            # last chunk is shorter
            if self._count_samples + len(chunk) < self._num_samples:
                self._count_samples += len(chunk)
            else:
                # append final chunk
                rest_length = self._num_samples - self._count_samples
                # keep track of remaining phase to avoid ticks
                if self._frequency:
                    self._signal_source.phase = float(len(chunk) - rest_length) / half_wavelength
                else:
                    self._signal_source.phase = 0.
                chunk = chunk[:rest_length]
                # done
                self._count_samples = self._num_samples
        # if loop, attach one chunk to loop, do not increment count
        return chunk
def build_chunk ( self , length ) : self . _signal_source . feedback = self . _feedback if self . _count_samples >= self . _num_samples : # done already return None # don't generate too many samples if length + self . _count_samples > self . _num_samples and not self . loop : length = ( self . _num_samples - self . _count_samples ) if self . _frequency == 32767 : self . _frequency = 0 # work on last element of sound queue if self . _frequency == 0 : chunk = bytearray ( length ) else : half_wavelength = SAMPLE_RATE / ( 2. * self . _frequency ) # generate first half-wave so as to complete the last one played if self . _signal_source . phase : first_length = int ( half_wavelength * self . _signal_source . phase ) first_half_wave = bytearray ( [ self . _signal_source . bit ] ) * first_length * _RESOLUTION length -= first_length self . _signal_source . phase = 0. else : first_half_wave = bytearray ( ) num_half_waves = int ( ceil ( length / half_wavelength ) ) # generate bits bits = ( self . _signal_source . next ( ) for _ in range ( num_half_waves ) ) # do sampling by averaging the signal over bins of given resolution # this allows to use vectors all the way # which is *much* faster than looping over an array # stretch array by half_wavelength * _RESOLUTION stretch = int ( half_wavelength * _RESOLUTION ) waves = bytearray ( ) . join ( bytearray ( [ _b ] ) * stretch for _b in bits ) matrix = bytearray ( ) . join ( ( first_half_wave , waves ) ) # cut off on round number of resolution blocks use_length = len ( matrix ) - ( len ( matrix ) % _RESOLUTION ) # average over blocks # sums are between 0 and RESOLUTION, inclusive sums = ( sum ( matrix [ _i : _i + _RESOLUTION ] ) for _i in xrange ( 0 , use_length , _RESOLUTION ) ) # scale to signed amplitude half_res = _RESOLUTION // 2 averages = ( ( _s - half_res ) * self . _amplitude // _RESOLUTION for _s in sums ) # pack signed bytes into bytearray chunk = bytearray ( _sb if _sb >= 0 else 0xff + _sb for _sb in averages ) if not self . loop : # last chunk is shorter if self . _count_samples + len ( chunk ) < self . _num_samples : self . _count_samples += len ( chunk ) else : # append final chunk rest_length = self . _num_samples - self . _count_samples # keep track of remaining phase to avoid ticks if self . _frequency : self . _signal_source . phase = float ( len ( chunk ) - rest_length ) / half_wavelength else : self . _signal_source . phase = 0. chunk = chunk [ : rest_length ] # done self . _count_samples = self . _num_samples # if loop, attach one chunk to loop, do not increment count return chunk