Пример #1
0
def fx_distortion(chunk_p, gain_p, tres_p):
    if len(chunk_p) != 2 * CHUNK:
        print('[distortion] chunk size is not %d but %d' % (2 * CHUNK, len(chunk_p)))
        return chunk_p
    if  tres_p<= 0:
        print('[distortion] threshold should be > 0!')
        return chunk_p

    if  tres_p > 1:
        print('[distortion] threshold should be < 1!')
        return chunk_p
    
    if  gain_p < 1:
        print('[distortion] gain should be > 1!')
        return chunk_p

    #do distortion
    temp1 = audioop.mul(chunk_p, 2, 1 / tres_p)
    temp2 = audioop.mul(temp1, 2, tres_p)

    #do gain
    chunk_p = audioop.mul(temp2, 2, gain_p)
    del temp1
    del temp2
    return chunk_p
def mul_stereo(fileName,width,lfactor,rfactor):
    lsample = audioop.tomono(fileName, width, 1, 0)
    rsample = audioop.tomono(fileName,width, 0, 1)
    lsample = audioop.mul(lsample,width,lfactor)
    rsample = audioop.mul(rsample, width,rfactor)
    lsample = audioop.tostereo(lsample, width, 1, 0)
    rsample = audioop.tostereo(rsample, width, 0, 1)
    return audioop.add(lsample,rsample,width)
Пример #3
0
 def test_mul(self):
     data2 = []
     for d in data:
         str = ''
         for s in d:
             str = str + chr(ord(s)*2)
         data2.append(str)
     self.assertEqual(audioop.mul(data[0], 1, 2), data2[0])
     self.assertEqual(audioop.mul(data[1],2, 2), data2[1])
     self.assertEqual(audioop.mul(data[2], 4, 2), data2[2])
Пример #4
0
 def test_mul(self):
     data2 = []
     for d in data:
         str = bytearray(len(d))
         for i,b in enumerate(d):
             str[i] = 2*b
         data2.append(str)
     self.assertEqual(audioop.mul(data[0], 1, 2), data2[0])
     self.assertEqual(audioop.mul(data[1],2, 2), data2[1])
     self.assertEqual(audioop.mul(data[2], 4, 2), data2[2])
Пример #5
0
def convert_wave_data(f_rate,frame_count,sample_width,channels,data):
    """ Convert wave sample data into pleo format
    """
    if channels==2: data = audioop.tomono(data,sample_width,1,1)
    data = audioop.mul(data,sample_width,0.97999999999999998)
    data = audioop.ratecv(data,sample_width,1,f_rate,11025,None,4,4)[0]
    if sample_width==1:
       data = audioop.bias(data,1,-128)
       data = audioop.lin2lin(data,1,2)
    data = audioop.mul(data,2,(1.0/256))
    data = audioop.lin2adpcm(data,2,None)[0]
    return (11025,frame_count,sample_width,1,data)
Пример #6
0
def testmul(data):
	data2 = []
	for d in data:
		str = ''
		for s in d:
			str = str + chr(ord(s)*2)
		data2.append(str)
	if audioop.mul(data[0], 1, 2) <> data2[0] or \
		  audioop.mul(data[1],2, 2) <> data2[1] or \
		  audioop.mul(data[2], 4, 2) <> data2[2]:
		return 0
	return 1
Пример #7
0
    def _play(self, start, length):
        self.isplaying = True
        if AudioSegment:
            millisecondchunk = 50 / 1000.0
            playchunk = self.pydubfile[start*1000.0:(start+length)*1000.0] - (60 - (60 * (self.volume/100.0)))
            self.time = start
            self.audio.play(playchunk.get_array_of_samples(), blocking=False)

            # For some reason it does not like the seperated chunks, so we play it non-
            # We might be able to use self.audio.get_stream().time to improve accuracy
            for chunks in make_chunks(playchunk, millisecondchunk*1000):
                self.time += millisecondchunk

                time.sleep(millisecondchunk)
                if not self.isplaying:
                    break
                if self.time >= start+length:
                    break
        else:
            startframe = int(round(start * self.wave_reference.getframerate()))
            samplelen = int(round(length * self.wave_reference.getframerate()))
            remaining = samplelen
            chunk = 1024
            try:
                self.wave_reference.setpos(startframe)
            except wave.Error:
                self.isplaying = False
                return

            if remaining >= 1024:
                data = audioop.mul(self.wave_reference.readframes(chunk),self.wave_reference.getsampwidth(), self.volume/100.0)
                remaining -= chunk
            else:
                data = audioop.mul(self.wave_reference.readframes(remaining),self.wave_reference.getsampwidth(), self.volume/100.0)
                remaining = 0

            # play stream
            self.audio.play(data.get_array_of_samples(), blocking=False)

            while len(data) > 0 and self.isplaying:

                time.sleep(float(self.wave_reference.getframerate()))
                self.time = float(self.wave_reference.tell()) / float(self.wave_reference.getframerate())
                if remaining >= 1024:
                    data = audioop.mul(self.wave_reference.readframes(chunk),self.wave_reference.getsampwidth(), self.volume/100.0)
                    remaining -= chunk
                else:
                    data = audioop.mul(self.wave_reference.readframes(remaining),self.wave_reference.getsampwidth(), self.volume/100.0)
                    remaining = 0

        self.audio.stop()
        self.isplaying = False
Пример #8
0
def testmul(data):
    if verbose:
        print 'mul'
    data2 = []
    for d in data:
        str = ''
        for s in d:
            str = str + chr(ord(s)*2)
        data2.append(str)
    if audioop.mul(data[0], 1, 2) != data2[0] or \
              audioop.mul(data[1],2, 2) != data2[1] or \
              audioop.mul(data[2], 4, 2) != data2[2]:
        return 0
    return 1
Пример #9
0
    def get_flush(st, channels, fade=0):
        """Like soundtouch's flush, don't require that all data comes through, just any.
        If fade > 0, only allow [fade] samples, and linearly scale volume to 0 over that length"""
        
        waiting = st.waiting_count()
        ready = st.ready_count()
        result = ""

        silence = array('h', [0] * 64)

        while st.ready_count() == ready:
            st.put_samples(silence)

        while st.ready_count() > 0:
            result += st.get_samples(11025)

        st.clear()

        if len(result) > 2 * channels * waiting:
            result = result[0:(2 * channels * waiting)]

        fade = min(fade, len(result) / 2)
        if fade > 0:
            resultstring = ""
            for ii in xrange(fade / channels):
                i0 = ii * 2*channels
                i1 = (ii+1) * 2*channels
                resultstring += audioop.mul(result[i0:i1], 2, 1 - float(ii) / (fade / channels))
            result = resultstring

        return result
Пример #10
0
def mix(layers, leftalign=True, boost=2.0):
    """ mixes N stereo audio strings """
    attenuation = 1.0 / len(layers)
    attenuation *= boost 
    layers.sort(key = len)
    output_length = flen(layers[-1])

    out = pad('', output_length, 0) 

    for layer in layers:
        padding = output_length - flen(layer) 

        if leftalign:
            layer = pad(layer, 0, padding)
        else:
            layer = pad(layer, padding, 0)

        layer = audioop.mul(layer, audio_params[1], attenuation)

        if len(layer) != ftc(output_length) or len(out) != ftc(output_length):
            dif = int(math.fabs(len(layer) - len(out)))
            log('unequal'+str(dif))
            if len(out) < len(layer):
                layer = layer[:len(layer) - dif]
            else:
                out = out[:len(out) - dif]

        out = audioop.add(out, layer, audio_params[1])

    return out 
Пример #11
0
    def __getitem__(self, millisecond):
        if isinstance(millisecond, slice):
            start = millisecond.start if millisecond.start is not None else 0
            end = millisecond.stop if millisecond.stop is not None \
                else len(self)

            start = min(start, len(self))
            end = min(end, len(self))
        else:
            start = millisecond
            end = millisecond + 1

        start = self._parse_position(start) * self.frame_width
        end = self._parse_position(end) * self.frame_width
        data = self._data[start:end]

        # ensure the output is as long as the requester is expecting
        expected_length = end - start
        missing_frames = (expected_length - len(data)) / self.frame_width
        if missing_frames:
            if missing_frames > self.frame_count(ms=2):
                raise TooManyMissingFrames("You should never be filling in "\
                "   more than 2 ms with silence here, missing frames: %s" % \
                missing_frames)
            silence = audioop.mul(data[:self.frame_width],
                self.sample_width, 0)
            data += (silence * missing_frames)

        return self._spawn(data)
Пример #12
0
    def _do_run(self):
        self.loops = 0
        self._start = time.time()
        while not self._end.is_set():
            # are we paused?
            if not self._resumed.is_set():
                # wait until we aren't
                self._resumed.wait()

            if not self._connected.is_set():
                self.stop()
                break

            self.loops += 1
            data = self.buff.read(self.frame_size)

            if self._volume != 1.0:
                data = audioop.mul(data, 2, min(self._volume, 2.0))

            if len(data) != self.frame_size:
                self.stop()
                break

            self.player(data)
            next_time = self._start + self.delay * self.loops
            delay = max(0, self.delay + (next_time - time.time()))
            time.sleep(delay)
Пример #13
0
 def tick(self):
     self.effect.tick()
     if self.period == 0 or self.sample is None:
         return dummy_sample
     else:
         data = self.sample.get_data(self.sample_offset, self.samples_per_tick())
         self.sample_offset += self.samples_per_tick()
         return mul(data, 1, self.volume / 64.0) 
Пример #14
0
    def __mul__(self, factor):
        """
        Implement audio_data * factor
        """

        if not isinstance(factor, (int, float)):
            return NotImplemented # passing the job to factor.__rmul__
        new_byte_data = audioop.mul(self.BYTE_DATA, self.BIT_WIDTH, factor)
        return type(self)(new_byte_data, self.SAMPLE_RATE, self.BIT_WIDTH, self.CHANNELS, self.dtype)
Пример #15
0
def fx_noise_cancel(chunk_p, tres_p):
    if len(chunk_p) != 2 * CHUNK:
        print('[echo] chunk size is not %d but %d' % (2 * CHUNK, len(chunk_p)))
        return chunk_p

    power = audioop.rms(chunk_p, 2) / float(math.pow(2, 15))
    if power < tres_p:
        chunk_p = audioop.mul(chunk_p, 2, 0)
    return chunk_p
Пример #16
0
 def amplify_max(self):
     """Amplify the sample to maximum volume without clipping or overflow happening."""
     assert not self.__locked
     max_amp = audioop.max(self.__frames, self.samplewidth)
     max_target = 2 ** (8 * self.samplewidth - 1) - 2
     if max_amp > 0:
         factor = max_target/max_amp
         self.__frames = audioop.mul(self.__frames, self.samplewidth, factor)
     return self
Пример #17
0
    def mul(self, factor):
        """ Return frames for which all samples are multiplied by factor.
        Samples are truncated in case of overflow.

        :param factor: (int) the factor which will be applied to each sample.
        :returns: (str) converted frames

        """
        return audioop.mul(self._frames, self._sampwidth, factor)
def echocancel(outputdata, inputdata):
    pos = audioop.findmax(outputdata, 800)   # one tenth second
    out_test = outputdata[pos*2:]
    in_test = inputdata[pos*2:]
    ipos, factor = audioop.findfit(in_test,out_test)
    prefill = '\0'*(pos+ipos)*2
    postfill = '\0'*(len(inputdata)-len(prefill)-len(outputdata))
    outputdata = prefill + audioop.mul(outputdata,2-factor) + postfill
    return audioop.add(inputdata, outputdata,2)
Пример #19
0
 def test_mul(self):
     for w in 1, 2, 3, 4:
         self.assertEqual(audioop.mul(b"", w, 2), b"")
         self.assertEqual(audioop.mul(bytearray(), w, 2), b"")
         self.assertEqual(audioop.mul(memoryview(b""), w, 2), b"")
         self.assertEqual(audioop.mul(datas[w], w, 0), b"\0" * len(datas[w]))
         self.assertEqual(audioop.mul(datas[w], w, 1), datas[w])
     self.assertEqual(audioop.mul(datas[1], 1, 2), b"\x00\x24\x7f\x80\x7f\x80\xfe")
     self.assertEqual(audioop.mul(datas[2], 2, 2), packs[2](0, 0x2468, 0x7FFF, -0x8000, 0x7FFF, -0x8000, -2))
     self.assertEqual(
         audioop.mul(datas[3], 3, 2), packs[3](0, 0x2468AC, 0x7FFFFF, -0x800000, 0x7FFFFF, -0x800000, -2)
     )
     self.assertEqual(
         audioop.mul(datas[4], 4, 2), packs[4](0, 0x2468ACF0, 0x7FFFFFFF, -0x80000000, 0x7FFFFFFF, -0x80000000, -2)
     )
Пример #20
0
    def mul(self, factor):
        """
        Return frames that has all samples are multiplied by factor.
        Samples are truncated in case of overflow.

        @param factor (int) the factor which will be applied to each sample.
        @return converted frames

        """
        return audioop.mul(self.frames, self.sampwidth, factor)
Пример #21
0
 def get_32bit_frames(self, scale_amplitude=True):
     """Returns the raw sample frames scaled to 32 bits. See make_32bit method for more info."""
     if self.samplewidth == 4:
         return self.__frames
     frames = audioop.lin2lin(self.__frames, self.samplewidth, 4)
     if not scale_amplitude:
         # we need to scale back the sample amplitude to fit back into 24/16/8 bit range
         factor = 1.0/2**(8*abs(self.samplewidth-4))
         frames = audioop.mul(frames, 4, factor)
     return frames
Пример #22
0
def env(audio_string, wavetable_type="sine", fullres=False, highval=1.0, lowval=0.0):
    # Very short envelopes are possible...
    if flen(audio_string) < dsp_grain * 4 or fullres == True:
        packets = split(audio_string, 1)
    else:
        packets = split(audio_string, dsp_grain)

    wtable = wavetable(wavetable_type, len(packets), highval, lowval)
    packets = [audioop.mul(packet, audio_params[1], wtable[i]) for i, packet in enumerate(packets)]

    return ''.join(packets) 
Пример #23
0
def pan(slice, pan_pos=0.5, amp=1.0):
    amps = pantamp(pan_pos)

    lslice = audioop.tomono(slice, audio_params[1], 1, 0)
    lslice = audioop.tostereo(lslice, audio_params[1], amps[0], 0)

    rslice = audioop.tomono(slice, audio_params[1], 0, 1)
    rslice = audioop.tostereo(rslice, audio_params[1], 0, amps[1])

    slice = audioop.add(lslice, rslice, audio_params[1])
    return audioop.mul(slice, audio_params[1], amp)
Пример #24
0
def mul(fragment, sampwidth, factor):
    """
    Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor. Samples are truncated in case of overflow.

    @param fragment (string) input frames.
    @param sampwidth (int) sample width of the frames.
    @param factor (int) the factor which will be applied to each sample.
    @return converted frames

    """
    return audioop.mul(fragment, sampwidth, factor)
Пример #25
0
    def _frame_vol(self, frame, mult, *, maxv=2, use_audioop=True):
        if use_audioop:
            return audioop.mul(frame, 2, min(mult, maxv))
        else:
            # ffmpeg returns s16le pcm frames.
            frame_array = array('h', frame)

            for i in range(len(frame_array)):
                frame_array[i] = int(frame_array[i] * min(mult, min(1, maxv)))

            return frame_array.tobytes()
Пример #26
0
 def echocancel(outputdata, inputdata):
     """Try to identify an echo and remove it.
     Should contain 2-byte samples"""
     pos = audioop.findmax(outputdata, 800)
     out_test = outputdata[pos*2:]
     in_test = inputdata[pos*2:]
     ipos, factor = audioop.findfit(in_test, out_test)
     factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)], out_test)
     prefill = '\0'*(pos+ipos)*2
     postfill = '\0'*(len(inputdata) - len(prefill) - len(outputdata))
     outputdata = prefill + audioop.mul(outputdata, 2, -factor) + postfill
     return audioop.add(inputdata, outputdata, 2)
Пример #27
0
 def test_mul(self):
     for w in 1, 2, 3, 4:
         self.assertEqual(audioop.mul(b'', w, 2), b'')
         self.assertEqual(audioop.mul(bytearray(), w, 2), b'')
         self.assertEqual(audioop.mul(memoryview(b''), w, 2), b'')
         self.assertEqual(audioop.mul(datas[w], w, 0),
                          b'\0' * len(datas[w]))
         self.assertEqual(audioop.mul(datas[w], w, 1),
                          datas[w])
     self.assertEqual(audioop.mul(datas[1], 1, 2),
                      b'\x00\x24\x7f\x80\x7f\x80\xfe')
     self.assertEqual(audioop.mul(datas[2], 2, 2),
             packs[2](0, 0x2468, 0x7fff, -0x8000, 0x7fff, -0x8000, -2))
     self.assertEqual(audioop.mul(datas[3], 3, 2),
             packs[3](0, 0x2468ac, 0x7fffff, -0x800000,
                      0x7fffff, -0x800000, -2))
     self.assertEqual(audioop.mul(datas[4], 4, 2),
             packs[4](0, 0x2468acf0, 0x7fffffff, -0x80000000,
                      0x7fffffff, -0x80000000, -2))
Пример #28
0
    def raw_read(self):
        """Return some amount of data as a raw audio string"""
        buf = self.source.raw_read()
        if buf is None:
            self.eof = True
            return None

        # Perform the scaling and biasing
        if self.scale != 1.0:
            buf = audioop.mul(buf, self.source.raw_width(), self.scale)

        if self.bias != 0:
            buf = audioop.bias(buf, self.source.raw_width(), self.bias)

        return buf
Пример #29
0
 def mixAudio(self):
     # XXX see the comment above about storing a decaying number for the
     # volume. For instance, each time round the loop, take the calculated
     # volume, and the stored volume, and do something like:
     # newStoredVolume = (oldStoredVolume * 0.33) + (thisPacketVolume * 0.66)
     import audioop
     self._audioOut = {}
     if not self._open:
         log.msg('mixing closed room %r'%(self,), system='doug')
         return
     audioIn = {}
     for m in self._members:
         bytes = m.getAudioForRoom()
         if bytes: audioIn[m] = bytes
     if CONFDEBUG:
         print "room %r has %d members"%(self, len(self._members))
         print "got %d samples this time"%len(audioIn)
         print "samples: %r"%(audioIn.items(),)
     # short-circuit this case
     if len(self._members) < 2:
         if CONFDEBUG:
             print "less than 2 members, no sound"
         self._audioOutDefault = ''
         return
     # Samples is (confsource, audio)
     samples = audioIn.items()
     # power is three-tuples of (rms,audio,confsource)
     power = [ (audioop.rms(x[1],2),x[1], x[0]) for x in samples ]
     power.sort(); power.reverse()
     if CONFDEBUG:
         for rms,audio,confsource in power:
             print confsource, rms
     # Speakers is a list of the _maxSpeakers loudest speakers
     speakers = Set([x[2] for x in power[:self._maxSpeakers]])
     # First we calculate the 'default' audio. Used for everyone who's
     # not a speaker in the room.
     samples = [ x[1] for x in power[:self._maxSpeakers] ]
     scaledsamples = [ audioop.mul(x, 2, 1.0/len(samples)) for x in samples ]
     if scaledsamples:
         # ooo. a use of reduce. first time for everything...
         try:
             combined = reduce(lambda x,y: audioop.add(x, y, 2), scaledsamples)
         except audioop.error, exc:
             # XXX tofix!
             print "combine got error %s"%(exc,)
             print "lengths", [len(x) for x in scaledsamples]
             combined = ''
Пример #30
0
	def run(self):
		while 1:
			olddata = data = self.iport.readsamps(600)
			if self.do_ulaw:
				data = audioop.lin2ulaw(data, 2)
				data = audioop.ulaw2lin(data, 2)
			if self.do_adpcm:
				data, nacstate = audioop.lin2adpcm(data, 2, \
					  self.acstate)
				data, dummy = audioop.adpcm2lin(data, 2, \
					  self.acstate)
				self.acstate = nacstate
			if self.do_diff:
				olddata = audioop.mul(olddata, 2, -1)
				data = audioop.add(olddata, data, 2)
			self.oport.writesamps(data)
			fl.check_forms()
Пример #31
0
    def _callback( self, data, frame_count, time_info, status):
        # Если микрофон замьючен - ничего не делаем
        if self.muted :
            self.buffer.clear()
            self.ignoreFirstFrame = True
            return None, pyaudio.paContinue
        # А еще игнорируем первый фрейм после unmute:
        if self.ignoreFirstFrame :
            self.ignoreFirstFrame = False
            return None, pyaudio.paContinue

        # Контролируем размер буфера. В режиме ожидания 1с, в активном режиме 3с
        maxBufferSize = int(CHUNKS_PER_SECOND * (3 if self.active else 1) )

        while len(self.buffer)>maxBufferSize : 
            self.buffer.pop(0)

        data = numpy.fromstring( data, dtype='int16')

        if self.sampleRate != VOICE_SAMPLING_RATE:
            data, self.__ratecvState = audioop.ratecv( data.tobytes(), 2, self.channels, self.sampleRate, VOICE_SAMPLING_RATE, self.__ratecvState )
            data = numpy.fromstring( data, dtype='int16')

        #print(f"channels:")

        # Раскидываем на каналы
        channels = [0]*self.channels
        for ch in range(self.channels):
            channels[ch] = data[ch::self.channels].tobytes()
            #print(numpy.fromstring(channels[ch], dtype='int16'))


        # "Оптимальный уровень громкости"
        if config.micSelection == "rms":

            # Вариант 2: "наибольший RMS, но без искажений".
            chBest = -1
            rmsBest = 0
            maxBest = 0
            chGood = -1
            rmsGood = 100000
            maxGood = 0

            for ch in config.microphones:
                __rms = audioop.rms( channels[ch], self.sampleSize )
                __maxpp = audioop.maxpp( channels[ch], self.sampleSize )

                if (__rms>rmsBest) and (__rms<5000) and (__maxpp<64000) :
                    rmsBest = __rms
                    maxBest = __maxpp
                    chBest = ch
                if (chGood<0) or (__rms < rmsGood) :
                    rmsGood = __rms
                    rmsBest = __maxpp
                    chGood = ch

            #print(f'rms:[{__rms[0]},{__rms[1]}], maxpp:[{__maxpp[0]},{__maxpp[1]}], rmsBest={rmsBest}({chBest}), rmsGood={rmsGood}({chGood})')
            #print(f'rmsBest={rmsBest}({chBest}), rmsGood={rmsGood}({chGood})')
            if chBest>=0:
                self.channel = chBest
                self.__rms = rmsBest
                self.__maxpp = maxBest
            else:
                self.channel = chGood
                self.__rms = rmsGood
                self.__maxpp = maxGood

            data = channels[self.channel]

        # "Среднее по микрофонным каналам":
        else :
            self.channel = "avg"
            factor = 1.0 / len(config.microphones)
            #print(f'factor={factor} ')
            data = None
            for ch in config.microphones :
                if data==None :
                    data = audioop.mul( channels[ch], 2, factor )
                else :
                    data = audioop.add( data, audioop.mul( channels[ch], 2, factor ), 2 )

            self.__rms = audioop.rms( data, self.sampleSize )
            self.__maxpp = audioop.maxpp( data, self.sampleSize )

        #print(f"Final data: channel={self.channel}, rms={self.rms}, maxpp={self.maxpp} ")
        #print(numpy.fromstring(data, dtype='int16'))

        # Сохранить фрагмент в буфере:
        self.buffer.append( data )

        if not self.active:
            # Если уровень звука "немного меньше" фонового шума - снизить значение порогового шума
            if self.__rms + config.noiseThreshold < self.__noiseLevel:
                self.__noiseLevel = self.__rms + int( config.noiseThreshold / 4 )

            # Посчитать VAD index (self.vadLevel)
            vadFrameSize = int(VOICE_SAMPLING_RATE*self.sampleSize/1000 * VAD_FRAME)
            p = 0
            voiceFrames = 0
            totalFrames = 0
            while p+vadFrameSize <= len(data):
                totalFrames += 1
                if self.vad.is_speech( data[p:p+vadFrameSize], VOICE_SAMPLING_RATE ): voiceFrames += 1
                p += vadFrameSize

            self.vadLevel = int(voiceFrames*100/totalFrames)

            isVoice = (totalFrames>0) and (self.vadLevel>=config.vadConfidence)

            if isVoice and (self.rms > self.triggerLevel):
                self.active = True
        else:
            if self.__rms + config.noiseThreshold > self.__noiseLevel :
                self.__noiseLevel = self.__rms

        return None, pyaudio.paContinue
Пример #32
0
 def read(self, volume=None):
     self.frames += 1
     return audioop.mul(super().read(), 2, volume or self.volume)
Пример #33
0
def create_audio_thread(audio_lib_path: str,
                        audio_lib_type,
                        uri: str,
                        skipto: int = 0,
                        quiet: bool = True,
                        stereo: bool = True,
                        use_reconnect=False):
    if uri == '':
        return

    global_settings.mumble_inst.sound_output.clear_buffer()
    if global_settings.audio_inst:
        pid = global_settings.audio_inst.pid
        global_settings.audio_inst.terminate()
        try:
            os.kill(pid, 0)
            global_settings.audio_inst.kill()
        except OSError as e:
            dprint(e)
        global_settings.audio_inst = None

    if audio_lib_type.value == AudioLibrary.FFMPEG.value:
        params = [audio_lib_path]
        if quiet:
            params.extend(["-loglevel", "quiet"])
        if use_reconnect:
            params.extend([
                "-reconnect", "1", "-reconnect_streamed", "1",
                "-reconnect_delay_max", "2"
            ])
        params.extend([
            "-i", uri, "-ss", f"{skipto}", "-acodec", "pcm_s16le", "-f",
            "s16le", "-ab", "192k", "-ac", "2"
        ])
        if stereo:
            params.extend(["-ar", "48000", "-threads", "8", "-"])
        else:
            params.extend(["-ar", "24000", "-threads", "8", "-"])
    elif audio_lib_type.value == AudioLibrary.VLC.value:
        params = [audio_lib_path, uri, '-I', 'dummy']
        if quiet:
            params.extend(["--quiet"])
        params.extend(["--one-instance", f"--start-time={skipto}"])
        if stereo:
            params.extend([
                "--sout",
                "#transcode{acodec=s16le, channels=2, samplerate=48000, ab=192, threads=8}:std{access=file, mux=wav, dst=-}"
            ])
        else:
            params.extend([
                "--sout",
                "#transcode{acodec=s16le, channels=2, samplerate=24000, ab=192, threads=8}:std{access=file, mux=wav, dst=-}"
            ])
        params.extend(["vlc://quit"])
    else:
        return

    global_settings.audio_inst = sp.Popen(params, stdout=sp.PIPE, bufsize=1024)

    rutils.unmute()

    while not global_settings.aud_interface.exit_flag and global_settings.audio_inst:
        while global_settings.mumble_inst.sound_output.get_buffer_size(
        ) > 0.5 and not global_settings.aud_interface.exit_flag:
            sleep(0.01)
        if global_settings.audio_inst:
            raw_music = global_settings.audio_inst.stdout.read(1024)
            if raw_music and global_settings.aud_interface.status.is_playing():
                global_settings.mumble_inst.sound_output.add_sound(
                    audioop.mul(
                        raw_music, 2,
                        global_settings.aud_interface.status.get_volume()))
            else:
                if global_settings.aud_interface.next_track():
                    create_audio_thread(audio_lib_path=audio_lib_path,
                                        audio_lib_type=audio_lib_type,
                                        uri=global_settings.aud_interface.
                                        status.get_track().uri,
                                        skipto=0,
                                        quiet=quiet,
                                        stereo=stereo)
                else:
                    global_settings.aud_interface.reset()
                return
        else:
            return
Пример #34
0
    def loop(self):
        while not self.exit and self.mumble.is_alive():

            while self.thread and self.mumble.sound_output.get_buffer_size(
            ) > 0.5 and not self.exit:
                # If the buffer isn't empty, I cannot send new music part, so I wait
                self._loop_status = f'Wait for buffer {self.mumble.sound_output.get_buffer_size():.3f}'
                time.sleep(0.01)

            raw_music = None
            if self.thread:
                # I get raw from ffmpeg thread
                # move playhead forward
                self._loop_status = 'Reading raw'
                if self.song_start_at == -1:
                    self.song_start_at = time.time() - self.playhead
                self.playhead = time.time() - self.song_start_at

                raw_music = self.thread.stdout.read(self.pcm_buffer_size)
                self.read_pcm_size += len(raw_music)

                if self.redirect_ffmpeg_log:
                    try:
                        self.last_ffmpeg_err = self.thread_stderr.readline()
                        if self.last_ffmpeg_err:
                            self.log.debug("ffmpeg: " +
                                           self.last_ffmpeg_err.strip("\n"))
                    except:
                        pass

                if raw_music:
                    # Adjust the volume and send it to mumble
                    self.volume_cycle()

                    if not self.on_interrupting and len(
                            raw_music) == self.pcm_buffer_size:
                        self.mumble.sound_output.add_sound(
                            audioop.mul(raw_music, 2,
                                        self.volume_helper.real_volume))
                    elif self.read_pcm_size == 0:
                        self.mumble.sound_output.add_sound(
                            audioop.mul(
                                self._fadeout(raw_music,
                                              self.stereo,
                                              fadein=True), 2,
                                self.volume_helper.real_volume))
                    elif self.on_interrupting or len(
                            raw_music) < self.pcm_buffer_size:
                        self.mumble.sound_output.add_sound(
                            audioop.mul(
                                self._fadeout(raw_music,
                                              self.stereo,
                                              fadein=False), 2,
                                self.volume_helper.real_volume))
                        self.thread.kill()
                        self.thread = None
                        time.sleep(0.1)
                        self.on_interrupting = False
                else:
                    time.sleep(0.1)
            else:
                time.sleep(0.1)

            if not self.is_pause and not raw_music:
                self.thread = None
                # bot is not paused, but ffmpeg thread has gone.
                # indicate that last song has finished, or the bot just resumed from pause, or something is wrong.
                if self.read_pcm_size < self.pcm_buffer_size \
                        and var.playlist.current_index != -1 \
                        and self.last_ffmpeg_err:
                    current = var.playlist.current_item()
                    self.log.error("bot: cannot play music %s",
                                   current.format_debug_string())
                    self.log.error("bot: with ffmpeg error: %s",
                                   self.last_ffmpeg_err)
                    self.last_ffmpeg_err = ""

                    self.send_channel_msg(
                        tr('unable_play', item=current.format_title()))
                    var.playlist.remove_by_id(current.id)
                    var.cache.free_and_delete(current.id)

                # move to the next song.
                if not self.wait_for_ready:  # if wait_for_ready flag is not true, move to the next song.
                    if var.playlist.next():
                        current = var.playlist.current_item()
                        self.log.debug(
                            f"bot: next into the song: {current.format_debug_string()}"
                        )
                        try:
                            self.validate_and_start_download(current)
                            self.wait_for_ready = True

                            self.song_start_at = -1
                            self.playhead = 0

                        except ValidationFailedError as e:
                            self.send_channel_msg(e.msg)
                            var.playlist.remove_by_id(current.id)
                            var.cache.free_and_delete(current.id)
                    else:
                        self._loop_status = 'Empty queue'
                else:
                    # if wait_for_ready flag is true, means the pointer is already
                    # pointing to target song. start playing
                    current = var.playlist.current_item()
                    if current:
                        if current.is_ready():
                            self.wait_for_ready = False
                            self.read_pcm_size = 0

                            self.launch_music(current, self.playhead)
                            self.last_volume_cycle_time = time.time()
                            self.async_download_next()
                        elif current.is_failed():
                            var.playlist.remove_by_id(current.id)
                            self.wait_for_ready = False
                        else:
                            self._loop_status = 'Wait for the next item to be ready'
                    else:
                        self.wait_for_ready = False

        while self.mumble.sound_output.get_buffer_size() > 0:
            # Empty the buffer before exit
            time.sleep(0.01)
        time.sleep(0.5)

        if self.exit:
            self._loop_status = "exited"
            if var.config.getboolean('bot', 'save_playlist', fallback=True) \
                    and var.config.get("bot", "save_music_library", fallback=True):
                self.log.info("bot: save playlist into database")
                var.playlist.save()
Пример #35
0
def audioseg_adjust_volume(audio: AudioSegment, factor: float):
    return audio._spawn(
        data=audioop.mul(audio._data, audio.sample_width, factor))
Пример #36
0
    def fade(self,
             to_gain=0,
             from_gain=0,
             start=None,
             end=None,
             duration=None):
        """
        Fade the volume of this audio segment.
        
        to_gain (float): 
            resulting volume_change in db
            
        start (int): 
            default = beginning of the segment
            when in this segment to start fading in milliseconds
            
        end (int):
            default = end of the segment
            when in this segment to start fading in milliseconds
            
        duration (int):
            default = until the end of the audio segment
            the duration of the fade
        """
        if None not in [duration, end, start]:
            raise TypeError(
                "Only two of the three arguments, \"start\", \"end\", and \"duration\" may be specified"
            )

        # no fade == the same audio
        if to_gain == 0 and from_gain == 0: return self

        frames = self.frame_count()

        start = min(len(self), start)
        end = min(len(self), end)

        if start is not None and start < 0: start += len(self)
        if end is not None and end < 0: end += len(self)

        if duration is not None and duration < 0:
            raise InvalidDuration("duration must be a positive integer")

        if duration:
            if start is not None:
                end = start + duration
            elif end is not None:
                start = end - duration
        else:
            duration = end - start

        from_power = db_to_float(from_gain)

        output = []

        # original data - up until the crossfade portion, as is
        before_fade = self[:start]._data
        if from_gain != 0:
            before_fade = audioop.mul(before_fade, self.sample_width,
                                      from_power)
        output.append(before_fade)

        gain_delta = db_to_float(to_gain) - from_power
        scale_step = gain_delta / duration

        for i in range(duration):
            volume_change = from_power + (scale_step * i)
            chunk = self[start + i]
            chunk = audioop.mul(chunk._data, self.sample_width, volume_change)

            output.append(chunk)

        # original data after the crossfade portion, at the new volume
        after_fade = self[end:]._data
        if to_gain != 0:
            after_fade = audioop.mul(after_fade, self.sample_width,
                                     db_to_float(to_gain))
        output.append(after_fade)

        return self._spawn(data=output)
Пример #37
0
 def apply_gain(self, volume_change):
     return self._spawn(data=audioop.mul(self._data, self.frame_width,
                                         db_to_float(float(volume_change))))
Пример #38
0
    def read(self):
        if not self.start_time:
            self.start_time = time.time() - self.resume_from

        ret = self.original.read()
        return audioop.mul(ret, 2, self._volume)
Пример #39
0
        # Normalize audio
        new_audio_sample = []
        audio_sample_recording_list_counter = 0
        rms = []

        for x in audio_sample:
            rms.append(audioop.rms(x, 2))

        sample_mean = np.mean(rms)
        scaling_factor = 4000 / sample_mean

        if debug:
            print(scaling_factor)

        for x in audio_sample:
            new_audio_sample.append(audioop.mul(x, 2, scaling_factor))

        audio_sample = new_audio_sample

        # Write audio audio_data_directory

        audio_sample_file_path = audio_data_directory + UID + ".wav"

        audio_sample_file = open(audio_sample_file_path, 'w+')

        w = wave.open(audio_sample_file_path, "w")
        w.setnchannels(1)
        w.setsampwidth(2)
        w.setframerate(byterate)

        for x in new_audio_sample:
Пример #40
0
    def fade(self,
             to_gain=0,
             from_gain=0,
             start=None,
             end=None,
             duration=None):
        """
        Fade the volume of this audio segment.

        to_gain (float):
            resulting volume_change in db

        start (int):
            default = beginning of the segment
            when in this segment to start fading in milliseconds

        end (int):
            default = end of the segment
            when in this segment to start fading in milliseconds

        duration (int):
            default = until the end of the audio segment
            the duration of the fade
        """
        if None not in [duration, end, start]:
            raise TypeError('Only two of the three arguments, "start", '
                            '"end", and "duration" may be specified')

        # no fade == the same audio
        if to_gain == 0 and from_gain == 0:
            return self

        frames = self.frame_count()

        start = min(len(self), start) if start is not None else None
        end = min(len(self), end) if end is not None else None

        if start is not None and start < 0:
            start += len(self)
        if end is not None and end < 0:
            end += len(self)

        if duration is not None and duration < 0:
            raise InvalidDuration("duration must be a positive integer")

        if duration:
            if start is not None:
                end = start + duration
            elif end is not None:
                start = end - duration
        else:
            duration = end - start

        from_power = db_to_float(from_gain)

        output = []

        # original data - up until the crossfade portion, as is
        before_fade = self[:start]._data
        if from_gain != 0:
            before_fade = audioop.mul(before_fade, self.sample_width,
                                      from_power)
        output.append(before_fade)

        gain_delta = db_to_float(to_gain) - from_power

        # fades longer than 100ms can use coarse fading (one gain step per ms),
        # shorter fades will have audible clicks so they use precise fading (one
        # gain step per sample)
        if duration > 100:
            scale_step = gain_delta / duration

            for i in range(duration):
                volume_change = from_power + (scale_step * i)
                chunk = self[start + i]
                chunk = audioop.mul(chunk._data, self.sample_width,
                                    volume_change)

                output.append(chunk)
        else:
            start_frame = self.frame_count(ms=start)
            end_frame = self.frame_count(ms=end)
            fade_frames = end_frame - start_frame
            scale_step = gain_delta / fade_frames

            for i in range(int(fade_frames)):
                volume_change = from_power + (scale_step * i)
                sample = self.get_frame(int(start_frame + i))
                sample = audioop.mul(sample, self.sample_width, volume_change)

                output.append(sample)

        # original data after the crossfade portion, at the new volume
        after_fade = self[end:]._data
        if to_gain != 0:
            after_fade = audioop.mul(after_fade, self.sample_width,
                                     db_to_float(to_gain))
        output.append(after_fade)

        return self._spawn(data=output)
Пример #41
0
    return db


p = pyaudio.PyAudio()

volume = []

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                input_device_index=D_INDEX,
                frames_per_buffer=CHUNK)

print('using device #%d' % D_INDEX)
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    data = audioop.mul(data, 2, 10)
    volume.append(printDB(data))

stream.stop_stream()
stream.close()
p.terminate()

print('writing %d volume samples to file' % len(volume))
target = open(FILENAME, 'w')
target.truncate()
for i in volume:
    target.write('%f' % i)
    target.write(';')
target.close()
Пример #42
0
 def write(self, data):
     data = audioop.mul(data.data, 2, min(self._volume, 2.0))
     self.destination.write(data)
Пример #43
0
 def read(self):
     ret = self.original.read()
     return audioop.mul(ret, 2, min(self._volume, 2.0))