gpt4 book ai didi

python - 使用 Pydub 实时发出连续声音

转载 作者:太空宇宙 更新时间:2023-11-03 21:44:18 26 4
gpt4 key购买 nike

我正在尝试制作一个从 wifi 探针日志生成声音的程序,以便一定数量的设备(在一定距离内)生成声音,而 rssi 就是频率。

我试图使其尽可能实时,但无法弄清楚如何使音调连续并根据值的变化更改频率。

'''
This program takes a log file from a
wifi probe and translates it into sound
'''

import time
import math #import needed modules
import pyaudio #sudo apt-get install python-pyaudio
import threading
from threading import Thread
from pydub import AudioSegment
from pydub.generators import Sine
from pydub.playback import play
import signal


def logData():
'''
Takes log file data and puts it into database
updates every 1 sec
'''
global dic
global tone
tone = []
dic = {}
while True:
with open("/Users/CWT/Documents/VÆRKER/probemon.log") as f:
for line in f:
(key, val) = line.split()
if val <= str(-50):
dic[(key)] = val
print (dic)
time.sleep(1)



def sound():

'''
Generate sounds
'''

# Play final tone
while (True):
with open("/Users/CWT/Documents/VÆRKER/probemon.log") as i:
try:
tone1 = Sine(abs(int(list(dic.values())[0]))).to_audio_segment(3000)
tone2 = Sine(abs(int(list(dic.values())[1]))).to_audio_segment(3000)
tone3 = Sine(abs(int(list(dic.values())[2]))).to_audio_segment(3000)
except:
print('Index error')
try:
multitone1 = tone1
multitone2 = tone1.overlay(tone2)
multitone3 = tone3.overlay(multitone2)
except:
print('Multitone error')


try:
if len(dic) <= 1:
play(multitone1.fade_in(250).fade_out(250))
elif len(dic) == 2:
play(multitone2.fade_in(250).fade_out(250))
elif len(dic) >= 3:
play(multitone3.fade_in(250).fade_out(250))
except:
print('Playback error')

if __name__ == '__main__':
try:
Thread(target = logData).start()
time.sleep(1)
Thread(target = sound).start()
except KeyboardInterrupt:
print('Interrupted')

最佳答案

我能够制作一个样板解决方案,您可以根据您的需求进行定制。

这里是中心思想

1) 在每秒重复的连续循环中使用 os.popen 读取日志文件的最后一行

2) RSSI值非常小,并且这些值之间的差异也很小。我们在这里将其乘以常量 100 以产生明显的差异。您可以尝试不同的值。

3)使用 pydub 我们创建正弦音并播放它们

代码

from pydub.generators import Sine
from pydub import AudioSegment
from pydub.playback import play
import os
import time

sr = 44100 # sample rate
bd = 16 # bit depth
l = 50.0 # duration in millisec

last_line = "" #to avoid same line played again
log_file = "probemon.log"


while True:

line = os.popen('tail -n 1 {}'.format(log_file)).read()
if last_line == line:
pass

else:
key, val = line.split()
f = abs(int(val)) * 100

#create sine wave of given freq
sine_wave = Sine(f, sample_rate=sr, bit_depth=bd)

#Convert waveform to audio_segment for playback and export
sine_segment = sine_wave.to_audio_segment(duration=l)

print "mac:{} , rssi:{}".format(key,val)
#Play audio segment
play(sine_segment)

last_line = line
time.sleep(1) #sleep 1 sec, synch this with log file fill

我通过从不同的终端逐行填充 probemon.log 文件进行测试,延迟 1 秒。如果没有新数据,循环将等待。

编辑1

音频“音调”有“频率”,当改变频率时,音调也会改变。根据我们的讨论,由于我们需要实时改变音调,因此我们不能使用 pydub,它主要适合离线操作。

pyaudio 有一个使用回调的非阻塞方法,允许在实时播放流数据时对其进行操作。

该解决方案根据日志的最后一行连续播放音频,直到日志数据发生变化。

此解决方案还消除了合并两个音调时出现的爆裂声/破裂声。

灵感来自 here

import pyaudio
import numpy as np
from time import time,sleep
import os

CHANNELS = 2
RATE = 44100

TT = time()
freq = 100
newfreq = 100
phase = 0
log_file = "probemon.log"

def callback(in_data, frame_count, time_info, status):
global TT,phase,freq,newfreq
if newfreq != freq:
phase = 2*np.pi*TT*(freq-newfreq)+phase
freq=newfreq
left = (np.sin(phase+2*np.pi*freq*(TT+np.arange(frame_count)/float(RATE))))
data = np.zeros((left.shape[0]*2,),np.float32)
data[0::2] = left #left data
data[1::2] = left #right data
TT+=frame_count/float(RATE)
return (data, pyaudio.paContinue)

p = pyaudio.PyAudio()

stream = p.open(format=pyaudio.paFloat32,
channels=CHANNELS,
rate=RATE,
output=True,
stream_callback=callback)

stream.start_stream()
tmphold = ""
try:
while True:
line = os.popen('tail -n 1 {}'.format(log_file)).read()
try:
key, val = line.split()
except:
key, val = "default", 0.0

f = abs(int(val))
newfreq = f * 10 #update freq per log
if newfreq != tmphold:
tmphold = newfreq
print "mac:{} , rssi:{} , freq:{}
finally:
stream.stop_stream()
stream.close()
p.terminate()

结果

mac:default , rssi:0.0 , freq:0 Hz
mac:d8:8f:76:1a:cb:65 , rssi:-43 , freq:430 Hz
mac:04:4f:4c:77:72:8f , rssi:-51 , freq:510 Hz
mac:20:39:56:af:51:49 , rssi:-39 , freq:390 Hz
mac:20:39:56:af:51:49 , rssi:-45 , freq:450 Hz
mac:5e:e2:1d:a3:d2:da , rssi:-47 , freq:470 Hz
mac:5e:e2:1d:a3:d2:da , rssi:-49 , freq:490 Hz
mac:12:84:16:9c:75:ee , rssi:-43 , freq:430 Hz
mac:da:a1:19:71:4d:0c , rssi:-55 , freq:550 Hz
mac:d8:8f:76:1a:cb:65 , rssi:-49 , freq:490 Hz

关于python - 使用 Pydub 实时发出连续声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52604019/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com