Простой звук Pygame на частоте - PullRequest
6 голосов
/ 19 октября 2011

Как я могу создать звук с частотой 440 Гц, который всегда будет плавно воспроизводиться с использованием звука в Pygame? Я предполагаю, что это должно быть достаточно просто, но я не хочу использовать какие-либо глупые файлы для выполнения задачи. Конечная цель этого - сыграть ноту, пока нажата клавиша, как я задал в другом вопросе. Любая помощь будет принята с благодарностью, так как я потратил много времени, пытаясь найти ответ на этот вопрос.

Ответы [ 2 ]

7 голосов
/ 29 апреля 2013

Получив слишком много «ValueError: Глубина массива должна соответствовать количеству каналов микшера» и другие подобные ошибки, я обнаружил этот рабочий пример http://www.mail-archive.com/pygame-users@seul.org/ msg16140.html . Он правильно генерирует многомерный 16-битный целочисленный массив, который работает со стерео микшером. Ниже приведен минимальный рабочий пример, в основном взятый из предыдущей ссылки с необходимыми вставленными битами пигамии. Протестировано в Python 2.7.2 с pygame.ver '1.9.1release'.

В этом примере будет воспроизводиться звук 440 Гц из одного динамика и звук 550 Гц из другого динамика в режиме стерео. Немного поиграв с длительностью, я обнаружил, что слышимые щелчки появятся в звуковом цикле, если вы установите переменную «длительность» в любое значение, кроме целого числа.

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()
3 голосов
/ 19 октября 2011

Что за звук 440 Гц? В «440 Гц» есть много типов волн: синус, пила, квадрат и т. Д. У вас может быть флейта, играющая на А, и это тоже может иметь значение.

Если вы хотите получить синусоидальную волну, похоже, что вы можете создать объект Sound с помощью pygame.sndarray.samples. (Я не проверял это) Вы можете создать образцы с:

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

Это, надеюсь, основные синусоидальные волны. frequency - желаемая частота в Гц. sample_rate - количество сэмплов в секунду в сгенерированном звуке: 44100 Гц - типичное значение. duration_in_samples - длина аудио. (5 * 44100 == 5 секунд, если звук воспроизводится с частотой дискретизации 44100 Гц.)

Похоже, вам, возможно, придется преобразовать samples в numpy.array, прежде чем переходить к pygame.sndarray.samples. Документы указывают, что аудио должно соответствовать формату, возвращаемому pygame.mixer.get_init, поэтому настройте samples соответствующим образом, но это основная идея. (mixer.get_init сообщит вам переменную sample_rate, указанную выше, и о том, нужно ли вам учитывать стерео, и нужно ли регулировать амплитуду волны или сдвигать ее.)

Сделайте samples целым числом длин волн, и оно должно зацикливаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...