在32位平面上使用pyaudio传输块

时间:2019-01-12 10:49:39

标签: python pyaudio

我正在尝试发送一个1024位的块和3个子带,该块被划分为32个位平面,使用一种结构发送每个平面,其中我存储了该平面和一个链条的位置的一个位其中存储了该位置的子带的所有平面的1024位中的1个,也就是说,发送的第一个平面将是平面31,其链包含3个子带的平面31,依此类推。飞机的位置是因为稍后我们收到包裹时,我们将需要订购它们并加入所有飞机以提高效率,但是我无法传输音频,也不知道它在哪里出故障。 / p>

# 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 个答案:

没有答案