Döngü değerini değiştirip yeniden başlatma

import math
from pyaudio import PyAudio

BITRATE = 40000
FREQUENCY = 2000.0
LENGTH = 30.0
NUMBEROFFRAMES = int(BITRATE*LENGTH)
RESTFRAMES = NUMBEROFFRAMES % BITRATE
WAVEDATA = ''
for x in range(NUMBEROFFRAMES):
	WAVEDATA += chr(int(math.sin(x/((BITRATE/FREQUENCY)/math.pi))*127 + 128))
for x in range(RESTFRAMES):
	WAVEDATA += chr(128)
p = PyAudio()
Stream = p.open(
	format = p.get_format_from_width(1),
	channels = 1,
	rate = BITRATE,
	output = True,
	)
stream.write(WAVEDATA)
stream.stop_stream()
stream.close()
p.terminate()

bu kodlar ile istediğim frekansa kesintili de olsa ulaşabiliyorum.
bu frekansı degişitirmek istediğimde döngünün bitmesini bekliyorum. anlık olarak döngünün bitmesini beklemeden ve (if) kullanmadan bunu nasıl yapabilirim?

Sorunuzu tam anlayamadım. stream.write(WAVEDATA) fonksiyonu çalışırken çalınacak sesi değiştirmek mi istiyorsunuz? Ayrıca neden if kullanmak istemiyorsunuz?

bu aslında programın bir parçası. tkinter ile oluşturduğum programda bulunan 5 buton ile frekans çıkışını seçmek istiyorum. 500 Hz, 750 Hz, 1000 Hz gibi. fakat 500 Hz çıkış alırken 1250 Hz için seçim yaptığımda
for x döngüsünün bitmesini beklemem gerekiyor. değişim olduğunda döngüyü kesip yeni değer ile tekrar başlatmak istiyorum.
araya if koyup değiştimi diye bakmak istediğimde döngü sürecinde if değerine baktığı için çıkış frekansı kesiliyor. asıl istediğim hiç kesilmemesi

Madem seçenekler sınırlı, yani sadece 500,750,1000 ve 1250 Hz seçilebilecek, bunların çıktısı yani WAVEDATA'yı -hep aynı olacağı için- her frekans için bir dosyaya yazarsınız. Program her açıldığında oradan okuyarak bir listede biriktirir. Hem bir daha for x in range(NUMBEROFFRAMES): döngüsünün çalışmasına gerek kalmaz, sonuçta zaman alıyor.

burada FREQUENCY = 2000 yazdığına bakmayın. bu değer değişecek. Aslında 40 civarı float değer var. yukarıda yazılan kodlar aslında fonksiyon du. acaba modül olarak çağırsam olurmu diye ayırdım. bir butona tıklıyorum 25345 Hz alıyorum slider ile küsuratı ayarlıyorum. mesela 25345.33 oluyor. yada 25345 değerinden 29 Hz değerine düşmeye çalışıyorum. her değişiklikte önceki çıkışın bitmesini bekliyorum.
modül olarak ayırdım her değişiklikle çağırayım dedim ortalık karıştı.

Buradaki kesilmeden kastınız ne? Çünkü for x in range(NUMBEROFFRAMES): bölümü çalışırken henüz bir ses verilmiyor, sadece WAVEDATA değişkeni değiştiriliyor.

RESTFRAMES değişeni BITRATE ve LENGTH ile belirleniyor. dolayısıyla bunun bir sonu var. bu sinyalin sürekliliğini sağlayamadım ama süresini istediğim kadar uzatabildim.

evet döngüyü kaldıralım bakalım ne olacak!

Aslnıda kodunuzun tamamını atsanız daha kolay yardım edebilirim.

tamam, yarım saat içinde.

from tkinter import*
import math
from pyaudio import PyAudio
win = Tk()

def freq(come):
    
    BITRATE = 110000
    FREQUENCY = int(come)
    LENGTH = 50.0
    l1.configure(text = come)
    NUMBEROFFRAMES = int(BITRATE * LENGTH)
    RESTFRAMES = NUMBEROFFRAMES % BITRATE
    WAVEDATA = ''    

    for x in range(NUMBEROFFRAMES):
       WAVEDATA += chr(int(math.sin(x / ((BITRATE / FREQUENCY) / math.pi)) * 127 + 128))    


    for x in range(RESTFRAMES): 
        WAVEDATA += chr(128)

    p = PyAudio()
    stream = p.open(
        format=p.get_format_from_width(1),
        channels=1,
        rate=BITRATE,
        output=True)
    stream.write(WAVEDATA)
    stream.stop_stream()
    stream.close()
    p.terminate()
l1=Label(win).pack()
b1=Button(win, text = "240", command = freq('240')).pack()
b2=Button(win, text= "500", command = freq('500')).pack()
b3=Button(win, text = "12550", command = freq('12550')).pack()
win.mainloop()

gibi.
telefon ile yazmak zor oldu.

Kodunuzu hızlıca hatırladığınız kadarı ile yazdınız sanırım, bu hali ile hata verecektir. l1, l1=Label(win).pack() kısmında None oluyor. Şimdi kodunuzu inceleyeceğim.

doğrudur. telefonumda pydroid 3 var, pyaudio modülünü ekleyemediğim için kontrol yapamadım.
ancak anlatmak istediğimi anladığınızı sanıyorum. b1 butonu ile fonksiyona değer gönderdiğimde bu değer ile ilgili çıkışı 50 sn boyunca alıyorum. fakat bu süre dolmadan b2 butonuna bastığımda 50 sn sürenin dolmasını bekliyorum.
aslında normalde 50 sn değil, 1200 sn olarak yazdım programı. amacım çıkışın ben değiştirene kadar süresiz olması fakat gerçekleştiremedim.

Sanırım bu kod işinizi görecektir, anlamadığınız bir yer olursa sorabilirsiniz:

from tkinter import*
import math
from pyaudio import PyAudio
win = Tk()

count = 0

def freq(come,Id):

        BITRATE = 40000
        FREQUENCY = int(come)
        LENGTH = 30.0
        l1.configure(text = come)
        win.update()
        NUMBEROFFRAMES = int(BITRATE * LENGTH)
        RESTFRAMES = NUMBEROFFRAMES % BITRATE
        WAVEDATA = ''    

        for x in range(NUMBEROFFRAMES):
                WAVEDATA += chr(int(math.sin(x / ((BITRATE / FREQUENCY) / math.pi)) * 127 + 128))    


        for x in range(RESTFRAMES): 
                WAVEDATA += chr(128)

        p = PyAudio()
        stream = p.open(
                format=p.get_format_from_width(1),
                channels=1,
                rate=BITRATE,
                output=True,
                )

        data = WAVEDATA[:1024]

        index = 1
        while len(data) > 0:
                stream.write(data)
                data = WAVEDATA[index*1024:(index+1)*1024]
                if count != Id: break
                index += 1
                win.update()



        # stop stream (4)
        stream.stop_stream()
        stream.close()

        p.terminate()

def çağır(text):
        global count
        count+=1
        freq(text,count)
    
l1=Label(win)
l1.pack()
b1=Button(win, text = "240", command = lambda: çağır('240')).pack()
b2=Button(win, text= "500", command = lambda: çağır('500')).pack()
b3=Button(win, text = "12550", command = lambda: çağır('12550')).pack()
win.mainloop()
1 Beğeni

Bunun dogrusu (ve kolayi) pyaudio’yu callback modunda kullanmak: http://people.csail.mit.edu/hubert/pyaudio/docs/#example-callback-mode-audio-i-o

Dalgayi frekansindan bagimsiz olarak frame_count'luk (frames_per_buffer, buffer size) parcalara bolup callback her cagrildiginda bir sonraki parcayi vermek lazim.

Mesela frame sayisi 1024, dalga boyu da 2048 ise (frekans=44100/2048=21.5Hz), her frame’de dalganin yarisini dondurmek lazim. Toplam frame sayisi veya callback sayisi fonksiyon disinda tutulup iceride gereken faz kaymasi hesaplanip dalganin dogru parcasi dondurulebilir.