2016-12-18 2 views
0

파이썬을 사용하여 키 보류시 음을 연주하고 싶습니다. 현재 코드를 구현하고 수정하는 중 here이 발견되었습니다. 그러나, 내가 직면하고있는 문제는 keydown 함수가 호출 될 때마다 오디오를 잘라내어 출력하는 결과로 키가 보관 될 때 keydown 함수가 반복적으로 호출된다는 것입니다.PyAudio 및 TK를 사용하여 키 보류시 음을 연주하십시오.

코드를 재생할 수있는 방법을 찾고 있지만이 키에 대해 keyup이 호출 될 때까지 같은 키의 keydown을 호출하지 않으면 서 in-and-out 커팅을 제거합니다. 내가 작업 한 코드의 특정 부분은 아래와 같습니다.

미리 감사드립니다.

p = pyaudio.PyAudio() 
chord = Chord() 
gen = NoteGen() 

def callback(in_data, frame_count, time_info, status): 
    wave = chord(frame_count) 
    data = wave.astype(numpy.float32).tostring() 
    return (data, pyaudio.paContinue) 

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

stream.start_stream() 


def keydown(event): 
    k = gen(event.char) 
    print("add note: " + event.char) 
    chord.add_note(k) 
    print [(n.name, n.frequency) for n in chord.notes] 


def keyup(event): 
    k = gen(event.char) 
    print("remove note: " + event.char) 
    chord.remove_note(k) 
    print [n.name for n in chord.notes] 


root = Tk() 
frame = Frame(root, width=100, height=100) 
frame.bind_all("<KeyPress>", keydown) 
frame.bind_all("<KeyRelease>", keyup) 
frame.pack() 
root.mainloop() 

stream.stop_stream() 
stream.close() 
p.terminate() 

답변

1

키 코드를 키로 사용하고 해당 키의 상태 (부울 값)를 값으로 포함하는 사전을 준비하십시오.

따라서 키 다운이 호출되면 키 코드가 값 1로 추가되지 않은 경우 키 코드가 있는지 확인하십시오. 그리고 노트 재생을 시작하십시오. 해당 키가있는 경우 해당 키의 상태를 확인하고 키를 누르면 이벤트를 무시하십시오. 그렇지 않으면 노트를 연주하러갑니다. 키 업에서 키 상태를 0으로 설정하십시오.

콜백을 사용하여 오디오를 재생하지 마십시오. 재생 된 음표를 방해하면 악몽이 생깁니다.

스레드 내부의 메모를 스트림에 잘 기록하는 것이 좋습니다.

청크로 데이터를 쓰고 중지 플래그를 확인하십시오. 키까지가 호출

는 플래그를 설정하고 수행

stream.stop_stream(); stream.start_stream() 

정확하게 소리를 차단하기 위해.

try-except 블록에 쓰기 부분을 넣으면 스트림을 스레드 외부에서 강제 종료 할 때 아무런 문제가 발생하지 않습니다.

여러 사운드를 동시에 재생할 수있는 pyaudio를 더 나은 방법으로 사용하려면 PyPI for SWmixer module을 검색하십시오. 당신은 또한 질책이 필요합니다. 그런 다음 SWMixer를 사용하여 각 사운드를 자체 객체에로드하고 원하는대로 시작하고 중지합니다. 사용법은 pygame.mixer 모듈과 매우 비슷합니다.

현재 여러 개의 PyAudio 스트림을 병렬로 사용하려고하면 어떻게 작동하는지 모르겠습니다.

즉, 하나의 출력과 하나의 입력 스트림을 많은 문제없이 병렬로 사용할 수 있다는 것을 알고 있습니다. 그러나 2 개 이상의 출력 스트림이 일부를 유발할 수 있습니다. 그래서 SWMixer에 대해 언급했습니다. 나는 둘 이상을 사용해서 시도한 적이 없기 때문에 틀릴 수도있다.

하지만 PyAudio 자체의 여러 인스턴스를 사용해 보았습니다. 이전에 호출 한 볼륨을 줄임으로써 작동합니다. 그래서 나도 시내에서 일어난다. 따라서 이전에 시작한 것보다 마지막으로 들리는 노트가 더 크게 들리거나 재미있는 노이즈가 발생할 수 있습니다.

0

일부 글로벌 변수를 사용하여 keydown 이벤트가 이미 실행되었는지 확인할 수 있습니다.

key_pressed = False 

def keydown(event): 
    if key_pressed: 
     return 

    key_pressed = True 
    k = gen(event.char) 
    print("add note: " + event.char) 
    chord.add_note(k) 
    print [(n.name, n.frequency) for n in chord.notes] 


def keyup(event): 
    key_pressed = False 
    k = gen(event.char) 
    print("remove note: " + event.char) 
    chord.remove_note(k) 
    print [n.name for n in chord.notes] 
+0

보시다시피 변수의 이름은 chord입니다. 따라서 궁극적 인 목표는 동시에 여러 노트를 재생할 수있게하는 것입니다. 내가 슬프게도 실수하지 않는다면. 따라서 하나의 변수는 수행하지 않습니다. – Dalen

+0

@Dalen, 예입니다.하나는 변수의 배열을 만들거나 다른 키를 가진 사전을 만들고 그것을 검사 할 수 있습니다. 보시다시피, 현재 하나의 음 (44100 Hz) 만 어떤 건반에서 연주하고 있습니다. – akarilimano

+0

예, 예, 그렇습니다! – Dalen

관련 문제