Почему у меня такое искажение с объектами Pygame sndarray? - PullRequest
0 голосов
/ 26 октября 2011

Я использую sndarray из pygame, чтобы играть с базовым синтезом звука. Проблема в том, что я делаю, но у меня ужасное искажение сгенерированного звука.

В коде, который я приведу в конце вопроса, вы увидите здесь и там кучу кода. На самом деле основной материал взят из источника MIT, который я нашел на веб-сайте, который использует Numeric для математических операций и обработки массивов, и, поскольку я не могу установить его сейчас, я решил использовать для этого Numpy.

Сначала я подумал, что проблема связана с форматом Int моих массивов, но если я приведу значения к numpy.int16, у меня больше не будет звука.

Кроме того, я не могу найти в Google ничего такого о поведении от pygame / sndarray.

Есть идеи?

Спасибо!

Код:

global_sample_rate = 44100

def sine_array_onecycle(hz, peak):
    length = global_sample_rate / float(hz)
    omega = numpy.pi * 2 / length
    xvalues = numpy.arange(int(length)) * omega 
    return (peak * numpy.sin(xvalues))

def zipstereo(f):
    return numpy.array(zip (f , f))

def make_sound(arr, n_samples = global_sample_rate):
    return pygame.sndarray.make_sound( zipstereo( numpy.resize(numpy.array(arr), (n_samples,)) ) )

def sine(hz, peak):
    snd = make_sound(sine_array_onecycle(hz, peak), global_sample_rate)
    return snd

=> 'надеюсь, я не совершил ни одной ошибки, я довольно новичок в мире питона

1 Ответ

2 голосов
/ 25 марта 2012

Предполагается, что у вас есть некоторый код инициализации, такой как

pygame.mixer.pre_init(44100, -16, 2) # 44.1kHz, 16-bit signed, stereo

. Sndarray ожидает, что вы передадите ему 16-битные целочисленные массивы, а не массивы с плавающей запятой.

Ваше "пиковое" значение необходимо сделатьсмысл дан 16-битным целочисленным представлением.Таким образом, если ваш массив с плавающей запятой имеет значения в диапазоне от -1,0 до +1,0, то вам нужно умножить его на 2 ** 15, чтобы правильно масштабировать его.

Для ясности, вы можете захотеть преобразование, например:

numpy.int16(float_array*(2**15))

Мое лучшее предположение о ситуации заключается в том, что у вас был массив с плавающей точкой с низким пиковым значением, таким как 1,0, поэтому при преобразовании его в int16 большинство всего преобразовывалось в 0 или +/- 1, чтоты не сможешь услышать.При прохождении массива с плавающей запятой вы, вероятно, просто получали случайные биты (при интерпретации как 16-битные целые числа), поэтому он звучал как резкий шум (я наткнулся на этот этап на пути к тому, чтобы это заработало).

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