2011-10-19 63 views
6

Làm cách nào để tạo âm thanh 440 Hz phát mượt mà bằng âm thanh với Pygame? Tôi cho rằng điều này nên dễ dàng, nhưng tôi không muốn sử dụng bất kỳ tập tin ngu ngốc nào để hoàn thành nhiệm vụ. Mục đích cuối cùng của việc này là để chơi một ghi chú trong khi một phím được giữ lại như tôi đã hỏi trong một câu hỏi khác. Bất kỳ trợ giúp nào cũng sẽ được đánh giá rất cao vì tôi đã lãng phí một lượng lớn thời gian cố gắng tìm câu trả lời cho điều này.Âm thanh Pygame đơn giản ở tần số

Trả lời

3

Loại âm thanh 440 Hz nào? Có nhiều loại sóng ở "440 Hz": sin, cưa, hình vuông, v.v. Bạn có thể có một cây sáo chơi chữ A, và điều đó cũng có thể đếm.

Giả sử bạn muốn có sóng sin, có vẻ như bạn có thể tạo đối tượng Âm thanh với pygame.sndarray.samples. (Tôi chưa thử nghiệm điều này) Bạn có thể tạo các mẫu với:

samples = [math.sin(2.0 * math.pi * frequency * t/sample_rate) for t in xrange(0, duration_in_samples)] 

Đây là công cụ sóng sin cơ bản hy vọng. frequency là tần số mong muốn, tính bằng Hz. sample_rate là số lượng mẫu/giây trong âm thanh được tạo: 44100 Hz là giá trị điển hình. duration_in_samples là độ dài của âm thanh. (5 * 44100 == 5 giây, nếu âm thanh của bạn đang ở một tỷ lệ mẫu 44100 Hz.)

Dường như bạn có thể có để chuyển đổi samples đến một numpy.array trước khi đi qua để pygame.sndarray.samples. Tài liệu cho biết rằng âm thanh phải khớp với định dạng được trả về bởi pygame.mixer.get_init, vì vậy hãy điều chỉnh samples một cách thích hợp, nhưng đó là ý tưởng cơ bản. (mixer.get_init sẽ cho bạn biết biến sample_rate trên, và cho dù bạn cần phải giải thích cho âm thanh stereo, và nếu bạn cần phải điều chỉnh biên độ của sóng hoặc chuyển nó.)

Hãy samples một số không thể thiếu của sóng dài, và nó nên lặp lại.

+0

Tôi làm cách nào để phát âm thanh vĩnh viễn? – Paul

+0

Bằng cách yêu cầu nó lặp lại mãi mãi khi bạn chơi. Bạn đã thử đọc các tài liệu chưa? (pygame.org/docs) Cụ thể, bạn muốn http://pygame.org/docs/ref/mixer.html#Sound.play – Thanatos

6

Sau khi hoàn toàn quá nhiều "ValueError: Độ sâu mảng phải khớp với số kênh trộn" và các lỗi tương tự khác, tôi đã phát hiện ví dụ làm việc này http://www.mail-archive.com/[email protected]/msg16140.html. Nó tạo ra một mảng số nguyên 16 bit đa chiều hoạt động với bộ trộn âm thanh nổi. Ví dụ làm việc tối thiểu dưới đây, chủ yếu được nâng lên từ liên kết trước với các bit pygame cần thiết được đưa vào. Thử nghiệm trong Python 2.7.2 với pygame.ver '1.9.1release'.

Ví dụ này sẽ phát âm 440 Hz ra khỏi một loa và âm 550 Hz ra khỏi loa khác trong thiết lập âm thanh nổi. Sau một chút chơi với thời lượng tôi phát hiện ra rằng các nhấp chuột âm thanh sẽ bật lên trong vòng lặp âm thanh nếu bạn đặt biến "duration" thành bất kỳ thứ gì khác ngoài một số nguyên.

import pygame 
from pygame.locals import * 

import math 
import numpy 

size = (1366, 720) 

bits = 16 
#the number of channels specified here is NOT 
#the channels talked about here http://www.pygame.org/docs/ref/mixer.html#pygame.mixer.get_num_channels 

pygame.mixer.pre_init(44100, -bits, 2) 
pygame.init() 
_display_surf = pygame.display.set_mode(size, pygame.HWSURFACE | pygame.DOUBLEBUF) 


duration = 1.0   # in seconds 
#freqency for the left speaker 
frequency_l = 440 
#frequency for the right speaker 
frequency_r = 550 

#this sounds totally different coming out of a laptop versus coming out of headphones 

sample_rate = 44100 

n_samples = int(round(duration*sample_rate)) 

#setup our numpy array to handle 16 bit ints, which is what we set our mixer to expect with "bits" up above 
buf = numpy.zeros((n_samples, 2), dtype = numpy.int16) 
max_sample = 2**(bits - 1) - 1 

for s in range(n_samples): 
    t = float(s)/sample_rate # time in seconds 

    #grab the x-coordinate of the sine wave at a given time, while constraining the sample to what our mixer is set to with "bits" 
    buf[s][0] = int(round(max_sample*math.sin(2*math.pi*frequency_l*t)))  # left 
    buf[s][1] = int(round(max_sample*0.5*math.sin(2*math.pi*frequency_r*t))) # right 

sound = pygame.sndarray.make_sound(buf) 
#play once, then loop forever 
sound.play(loops = -1) 


#This will keep the sound playing forever, the quit event handling allows the pygame window to close without crashing 
_running = True 
while _running: 

    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      _running = False 
      break 

pygame.quit() 
Các vấn đề liên quan