在python的32位平面上用pyaudio传输块

时间:2019-01-13 11:53:06

标签: python pyaudio

我正在尝试发送一个1024位和3个子带的片段,该片段被分成32位平面,使用一种结构发送每个平面,其中我存储了该平面位置的一个位和一个1024链该位置的子带的所有平面(即,发送的第一个平面)的位将是平面31,带有包含3个子带的平面31的链的链,依此类推。飞机的位置是由于这样的事实,即稍后我们收到包裹时,我们将不得不对其进行分类和组合以使其更加高效,但是我无法传输音频,也不知道它在哪里出故障。我们之前描述的所有过程都是使用python的Wavelet变换完成的

 # PyAudio to capture and broadcast audio
import pyaudio
# NumPy to change variable types
import numpy as np
# Libreria socket para poder mandar data con conexion udp
import socket
#Libreria threading para usar hilos
from threading import Thread
#Libreria pywt para utilizar wavelet transform
import pywt
# Argparse to receive arguments for command line
import argparse
# Math to calculate log in base 2
import math
import struct

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
PORT = 8001
ITERACIONESDWT = 2

# Function that a component passes in 32-bit planes assigned to a list
def array_to_planos(planos):
    subbanda = []
    for i in range(0, len(planos)):
        b = planos[i].astype(np.int8)
        c = [(b & (0b1<<31)) >> 31,(b & (0b1<<30)) >> 30, (b & (0b1<<29)) >> 29, (b & (0b1<<28)) >> 28
                , (b & (0b1<<27)) >> 27, (b & (0b1<<26)) >> 26, (b & (0b1<<25)) >> 25, (b & (0b1<<24)) >> 24
                , (b & (0b1<<23)) >> 23, (b & (0b1<<22)) >> 22, (b & (0b1<<21)) >> 21, (b & (0b1<<20)) >> 20
                , (b & (0b1<<19)) >> 19, (b & (0b1<<18)) >> 18, (b & (0b1<<17)) >> 17, (b & (0b1<<16)) >> 16
                , (b & (0b1<<15)) >> 15, (b & (0b1<<14)) >> 14, (b & (0b1<<13)) >> 13, (b & (0b1<<12)) >> 12
                , (b & (0b1<<11)) >> 11, (b & (0b1<<10)) >> 10, (b & (0b1<<9)) >> 9, (b & (0b1<<8)) >> 8
                , (b & (0b1<<7)) >> 7, (b & (0b1<<6)) >> 6, (b & (0b1<<5)) >> 5, (b & (0b1<<4)) >> 4
                , (b & (0b1<<3)) >> 3, (b & (0b1<<2)) >> 2, (b & (0b1<<1)) >> 1, (b & (0b1<<0)) >> 0]
        subbanda.append(c)
    return subbanda

# Function that passes the list of 32 bits to decimal array
def planos_to_array(planos):
    subbanda = []
    for i in range(0, len(planos)):
        plano = planos[i]
        var1 = (plano[0]<<31 | plano[1]<<30 | plano[2]<<29 | plano[3]<<28 | plano[4]<<27 | plano[5]<<26 | plano[6]<<25 | 
                plano[7]<<24 | plano[8]<<23 | plano[9]<<22 | plano[10]<<21 | plano[11]<<20 | plano[12]<<19 | plano[13]<<18 | 
                plano[14]<<17 | plano[15]<<16 | plano[16]<<15 | plano[17]<<14 | plano[18]<<13 | plano[19]<<12 | plano[20]<<11 | 
                plano[21]<<10 | plano[22]<<9 | plano[23]<<8 | plano[24]<<7 | plano[25]<<6 | plano[26]<<5 | plano[27]<<4 | 
                plano[28]<<3 | plano[29]<<2 | plano[30]<<1 | plano[31]<<0).astype(np.int32).astype(float)
        subbanda.append(var1)
    return subbanda

#Enviamos audio usando udp
#Socket envia audio por puerto e ip indicado
#Graba sonido y envia
def enviar(direccionIp, puerto, CHUNK):
    udpEnviar = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    p = pyaudio.PyAudio()
    stream = p.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE,
                    input=True,
                    frames_per_buffer=CHUNK)


    while True:
        data = stream.read(CHUNK, exception_on_overflow=False)

        # Pass from type bytes to int16 using the numpy library
        array_In = np.frombuffer(data, dtype=np.int16)

        # Calculate the transform and store it in arrays in floats
        coeffs = pywt.wavedec(array_In, 'db1', level=ITERACIONESDWT)

        # Pass each component to 32-bit planes
        coeffs_planos = array_to_planos(coeffs)

        #data = np.array(coeffs_planos).tobytes()
        for u in range(31, -1, -1):
            p = b'' #struct de bytes
            for a in coeffs_planos:
                p = p + a[u].tobytes()
            data = struct.pack('b1024s', u, p)
            # Transmit to the sound card the wavelet array casted
            # to bytes
            udpEnviar.sendto(data, (direccionIp, puerto))


#Recibimos audio usando udp
#Socket escucha por el puerto indicado
#Recibe datos y reproduce
def recibir(port_receiv, CHUNK):
    udpRecibir = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    direccion = ('0.0.0.0', port_receiv)
    udpRecibir.bind(direccion)
    p = pyaudio.PyAudio()
    stream = p.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE,
                    output=True,
                    frames_per_buffer=CHUNK)

    while True:
        subanda = [None]*3
        planos_ordenados = [None]*32
        for i in range(3):
            subanda[i] = [None]*32

        for u in range(32):
            data = udpRecibir.recvfrom(CHUNK*2)
            p = struct.unpack('b256s256s512s', data[0])

            planos_ordenados[p[0]] = [np.frombuffer(p[1], dtype=np.int8),np.frombuffer(p[2], dtype=np.int8),np.frombuffer(p[3], dtype=np.int8)]

            for i in range(3):
                subanda[i][p[0]] = planos_ordenados[p[0]][i]

        # Pass each list of list in 32 planes to original coeffs
        coeffs1 = planos_to_array(subanda)
        # Calculate the inverse transform and store as int16
        # with the numpy library

        array_Out = pywt.waverec(coeffs1, 'db1').astype(np.int16)

        # Transmit to the sound card the wavelet array casted
        # to bytes          
        stream.write(array_Out.tobytes())
# Main
def main():

    Tr = Thread(target=recibir, args=(PORT, CHUNK))
    Tr.daemon = True
    Tr.start()

    direccionHost = input("Introduce direccion del host: ")

    print("\n***  Grabando")

    Te = Thread(target=enviar, args=(direccionHost, PORT, CHUNK))
    Te.daemon = True
    Te.start()
    Te.join()

if __name__ == '__main__':
    main()

0 个答案:

没有答案