蟒蛇简单的音频音频生成器



寻找一些(简单的)python音调生成器,用于在带有USB声卡的raspi上运行的以下脚本。需要动态音调开/关和频率更改。

import serial, time
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=0.1)
def monitor(inp=0):
if inp != inpold:
if inp != 0:
ser.setDTR(1)   # LED on (GPIO?)
# start tone here, generate tone forever or change tone freq
else:
ser.setDTR(0)   # LED off
# stop tone without clicks
inpold = inp 
While True:
time.sleep(0.01)        # min lenght tone pulse 10 milliseconds
input = ser.getCTS()        # or GPIO input
monitor(input)

所以我找到了几种方法来做到这一点,我将按照可行性顺序排列它们(最容易先应用):

>关于语气的假设:-
  • 波型 = 正弦波

  • 频率 = 440Hz

<小时 />

路1(离线轨道,没有声音设备/后端麻烦)

1-使用Audacity软件(或任何类似软件)创建一个 特定的音调并将其导出到文件中。

2-从大胆中,从上面的选项卡中选择"生成",然后选择 "音调"并在频率旁边放 440。

3-从Audacity中,从上面的选项卡中选择"文件",然后选择"导出"并选择 导出为您喜欢的任何扩展名,最好是MP3。"出.mp3">

4-点安装播放声音

5-在蟒蛇中

import playsound
playsound.playsound('out.mp3')

方式2(灵活,但必须确保后端工作正常)

1-点安装pygame游戏

2-如果您在Linux环境下工作,请确保安装以下库

libsdl1.2-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev

3-在蟒蛇中

import numpy
import pygame
sampleRate = 44100
freq = 440
pygame.mixer.init(44100,-16,2,512)
# sampling frequency, size, channels, buffer
# Sampling frequency
# Analog audio is recorded by sampling it 44,100 times per second, 
# and then these samples are used to reconstruct the audio signal 
# when playing it back.
# size
# The size argument represents how many bits are used for each 
# audio sample. If the value is negative then signed sample 
# values will be used.
# channels
# 1 = mono, 2 = stereo
# buffer
# The buffer argument controls the number of internal samples 
# used in the sound mixer. It can be lowered to reduce latency, 
# but sound dropout may occur. It can be raised to larger values
# to ensure playback never skips, but it will impose latency on sound playback. 
arr = numpy.array([4096 * numpy.sin(2.0 * numpy.pi * freq * x / sampleRate) for x in range(0, sampleRate)]).astype(numpy.int16)
arr2 = numpy.c_[arr,arr]
sound = pygame.sndarray.make_sound(arr2)
sound.play(-1)
pygame.time.delay(1000)
sound.stop()

方式3(正弦波)

如果您只需要正弦波,请使用此选项

1-点安装皮辛

2-如果您在Linux环境下工作,请确保安装以下库

portaudio19-dev

但是,如果您在Windows环境中工作,请确保使用pipwin安装它。

pipwin install pysine

3-在蟒蛇中

import pysine
pysine.sine(frequency=440.0, duration=1.0) 

尝试pysinewave. 它允许您开始、停止和平滑地更改音调的音高和音量.
示例:

from pysinewave import SineWave
import time
sinewave = SineWave(pitch = 12)
sinewave.play()
time.sleep(1)
sinewave.stop()

花很多时间在pyaudio上,但pygame非常简单。谢谢 http://shallowsky.com/blog/programming/python-play-chords.html

import pygame, pygame.sndarray
import numpy
import scipy.signal
from time import sleep
sample_rate = 48000
pygame.mixer.pre_init(sample_rate, -16, 1, 1024)
pygame.init()
def square_wave(hz, peak, duty_cycle=.5, n_samples=sample_rate):
t = numpy.linspace(0, 1, 500 * 440/hz, endpoint=False)
wave = scipy.signal.square(2 * numpy.pi * 5 * t, duty=duty_cycle)
wave = numpy.resize(wave, (n_samples,))
return (peak / 2 * wave.astype(numpy.int16))
def audio_freq(freq = 800):
global sound
sample_wave = square_wave(freq, 4096)
sound = pygame.sndarray.make_sound(sample_wave)
# TEST
audio_freq()
sound.play(-1)
sleep(0.5)
sound.stop()
audio_freq(1000)
#sleep(1)
sound.play(-1)
sleep(2)
sound.stop()
sleep(1)
sound.play(-1)
sleep(0.5)

有一个使用 PySDL2 实时生成音调的示例。向上和向下键用于更改频率。

import sys
import sdl2
import sdl2.ext
import math
import struct
import ctypes
basefreq = 110
nframes = 0
@ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.POINTER(sdl2.Uint8), ctypes.c_int)
def playNext(notused, stream, len):
global nframes
for i in range(0, len, 4):
t = (nframes + i) / 44100
left  = int(math.sin(2 * math.pi * t * (basefreq - 1)) * 32000)
right = int(math.sin(2 * math.pi * t * (basefreq + 1)) * 32000)
stream[i]   = left & 0xff
stream[i+1] = (left >> 8) & 0xff
stream[i+2] = right & 0xff
stream[i+3] = (right >> 8) & 0xff
nframes += len
def initAudio():
spec = sdl2.SDL_AudioSpec(0, 0, 0, 0)
spec.callback = playNext
spec.freq = 44100
spec.format = sdl2.AUDIO_S16SYS
spec.channels = 2
spec.samples = 1024
devid = sdl2.SDL_OpenAudioDevice(None, 0, spec, None, 0)
sdl2.SDL_PauseAudioDevice(devid, 0)
def run():
global basefreq
sdl2.SDL_Init(sdl2.SDL_INIT_AUDIO | sdl2.SDL_INIT_TIMER | sdl2.SDL_INIT_VIDEO)
window = sdl2.ext.Window("Tone Generator", size=(800, 600))
window.show()
running = True
initAudio()
while running:
events = sdl2.ext.get_events()
for event in events:
if event.type == sdl2.SDL_QUIT:
running = False
break
elif event.type == sdl2.SDL_KEYDOWN:
if event.key.keysym.sym == sdl2.SDLK_UP:
basefreq *= 2
elif event.key.keysym.sym == sdl2.SDLK_DOWN:
basefreq /= 2
break
sdl2.SDL_Delay(20)
return 0
if __name__ == "__main__":
sys.exit(run())

相关内容

最新更新