Передача звука UDP: воспроизводимый звук имеет большой шум

Я понятия не имею, как решить эту проблему. Помогите пожалуйста мне :)

Я хотел бы отправить звуковые данные, записанные одним компьютером, на другой компьютер и воспроизвести их. (по УДП)

Программа может работать корректно, но звук содержит(?) неприятный шум. когда я пытался записать и воспроизвести звук в одной программной последовательности, он работал правильно. Шума не было. В случае использования UDP даже на одном ПК, используйте IP 127.0.0.1, появился шум. Сначала я подумал, что причина в том, что воспроизводимый звук отсутствует на другом ПК, и я исправил это, создав буфер. Это устранило небольшой шум, но почти весь шум все еще остается.

следующий код это

Клиент

import pyaudio
import socket
from threading import Thread

frames = []

def udpStream():
    udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    

    while True:
        if len(frames) > 0:
            udp.sendto(frames.pop(0), ("127.0.0.1", 12345))

    udp.close()

def record(stream, CHUNK):    
    while True:
        frames.append(stream.read(CHUNK))

if __name__ == "__main__":
    CHUNK = 1024
    FORMAT = pyaudio.paInt16
    CHANNELS = 2
    RATE = 44100

    p = pyaudio.PyAudio()

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

    Tr = Thread(target = record, args = (stream, CHUNK,))
    Ts = Thread(target = udpStream)
    Tr.setDaemon(True)
    Ts.setDaemon(True)
    Tr.start()
    Ts.start()
    Tr.join()
    Ts.join()

Сервер

import pyaudio
import socket
from threading import Thread

frames = []

def udpStream(CHUNK):

    udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udp.bind(("127.0.0.1", 12345))

    while True:
        soundData, addr = udp.recvfrom(CHUNK)
        frames.append(soundData)

    udp.close()

def play(stream, CHUNK):
    BUFFER = 10
    while True:
            if len(frames) == BUFFER:
                while True:
                    stream.write(frames.pop(0), CHUNK)

if __name__ == "__main__":
    FORMAT = pyaudio.paInt16
    CHUNK = 1024
    CHANNELS = 2
    RATE = 44100

    p = pyaudio.PyAudio()

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

    Ts = Thread(target = udpStream, args=(CHUNK,))
    Tp = Thread(target = play, args=(stream, CHUNK,))
    Ts.setDaemon(True)
    Tp.setDaemon(True)
    Ts.start()
    Tp.start()
    Ts.join()
    Tp.join()

извините за длинный исходный код. Не стесняйтесь играть в эту программу.


person ami_GS    schedule 16.01.2014    source источник
comment
Является ли он шумным (т. е. данные повреждаются (например, из-за потери пакетов или из-за неправильной обработки данных)) или он заикается (т. е. есть проблема с синхронизацией / задержкой / параллелизмом (я совсем не уверен, threading — правильный выбор для разделения извлечения потока и воспроизведения потока).   -  person Dr. Jan-Philip Gehrcke    schedule 16.01.2014
comment
Вы должны сравнить отправленные и полученные вещи друг с другом. Может быть, это отличается. Я мог бы представить, что сетевой уровень переключает старший и младший байты в ваших данных или подобных вещах. Это приведет к сильному шуму.   -  person Alfe    schedule 16.01.2014
comment
@Jan-PhilipGehrcke Я не заметил потери пакетов, потому что версия UDP-передачи «изображения» работала правильно, когда я ее пробовал. Благодарю вас! Я думаю о потере пакетов и пытаюсь реализовать TCP, чтобы сравнить данные.   -  person ami_GS    schedule 16.01.2014
comment
@Alfe Спасибо! Я думаю, вы могли бы также сказать о потере пакетов. Я пытаюсь сравнить эти данные.   -  person ami_GS    schedule 16.01.2014
comment
Попробуйте сначала с TCP. Если вы обнаружите, что производительность TCP неразумна, я бы начал рассматривать использование UDP.   -  person Clarus    schedule 16.01.2014


Ответы (2)


Я искал причину этого шума. Наконец-то я смог понять, почему это произошло.

На самом деле, эта UDP-передача не привела к потере пакетов.

Даже если бы это было так, в звуке не было бы такого серьезного шума.


Эта программа отправляла данные корректно, и потерь пакетов почти не было, но метод "получить" не смог корректно принять данные.


В серверной программе

def udpStream(CHUNK):

    udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udp.bind(("127.0.0.1", 12345))

    while True:
        soundData, addr = udp.recvfrom(CHUNK)
        frames.append(soundData)

    udp.close()

Эта программа могла данные только "25%". (Я проверил количество данных)

Итак, я попытался получить данные кратно (КАНАЛЫ * 2)

        soundData, addr = udp.recvfrom(CHUNK * CHANNELS * 2)

Это приводит к тому, что звуковые данные могут быть получены на 100% полностью.

Наконец, звук, записанный одним компьютером, воспроизводится на другом компьютере без шума.

person ami_GS    schedule 15.02.2014
comment
Проблема была связана с этим вопросом (я получил ошибку 10040 в Windows): -error-on-wsock2" title="как легко решить ошибку 10040 слишком длинное сообщение на wsock2"> stackoverflow.com/questions/9378146/. Спасибо за ваш код, он очень интересен для обучения! - person bomben; 29.06.2020

Я столкнулся с той же проблемой, но ваше решение мне не помогло. Я обнаружил, что с помощью

stream.write(frames.pop(0))

вместо

stream.write(frames.pop(0), CHUNK)

Очищает весь шум в полученном сигнале.

person pec orange    schedule 29.07.2019