2015-07-13 3 views
2

J'utilise Pygame pour rendre un Sprite dans une fenêtre et je veux jouer un son sinusoïdal dont la fréquence dépend de la position y de ce Sprite. Je ne veux pas de discontinuités dans la phase du signal. Quel est le meilleur moyen d'y parvenir?Comment changer en continu la fréquence d'un son sinusoïdal?

+0

Ce que vous avez essayé jusqu'à présent? Une solution évidente serait de faire passer la fréquence en utilisant une fonction spline ou quelque chose de similaire. – llogiq

+0

@llogic si je change juste la fréquence comment puis-je m'assurer que la phase n'obtiendra pas de discontinuité? –

+0

changer la fréquence à un passage à zéro. – jaket

Répondre

1

J'ai trouvé cette solution. Modifier le freq-newfreq puis changer la phase comme ceci: newphase = 2*np.pi*t*(freq-newfreq)+phase

import pyaudio 
import numpy as np 
from time import time 

CHANNELS = 2 
RATE = 44100 

TT = time() 
freq = 100 
newfreq = 100 
phase = 0 
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[::2] = left 
    data[1::2] = left 
    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() 
start = time() 
try: 
    while 1: 
     now = time()  
     if now-start>1/24.: 
      newfreq=200+np.sin(2*np.pi*1/20.*now)*100 #update the frequency This will depend on y on the future 
      print newfreq 
     start=now 
finally: 
    stream.stop_stream() 
    stream.close() 
    p.terminate()