2016-01-29 4 views
1

Я пытаюсь написать простой генератор звуковых функций в Python, который будет запускаться на малиновой Pi (модель 2). Код по существу делает это:Создание гладкого звука с Python на компьютере с низким энергопотреблением

  • Генерировать 1 секунду звукового сигнала (скажем, синусоидальную волну или квадратную волну, и т.д.)
  • Play ее несколько раз в цикле

Например :

import pyaudio 
from numpy import linspace,sin,pi,int16 

def note(freq, len, amp=1, rate=44100): 
t = linspace(0,len,len*rate) 
data = sin(2*pi*freq*t)*amp 
return data.astype(int16) # two byte integers 

RATE = 44100 
FREQ = 261.6 

pa = pyaudio.PyAudio() 
s = pa.open(output=True, 
      channels=2, 
      rate=RATE, 
      format=pyaudio.paInt16, 
      output_device_index=2) 

# generate 1 second of sound 
tone = note(FREQ, 1, amp=10000, rate=RATE) 

# play it forever  
while True: 
    s.write(tone) 

проблема заключается в том, что каждая итерация результатов цикла слышимым «галочки» в аудио, даже при использовании внешнего USB звуковой карты. Есть ли способ избежать этого, вместо того, чтобы пытаться переписать все на C?

Я попытался использовать интерфейс обратного вызова pyaudio, но это на самом деле звучало хуже (например, возможно, мой Pi был напыщенным).

Сгенерированное аудио должно быть коротким, поскольку в конечном итоге оно будет динамически изменяться с помощью внешнего управления, и что-то большее, чем 1-секундная латентность при управлении, просто чувствует себя неловко. Есть ли лучший способ получить эти сигналы из кода Python?

+0

Такие клики могут быть связаны с использованием режима блокировки 'PyAudio'. Для ваших целей (небольшой буфер/низкая латентность) вам все равно лучше использовать режим обратного вызова. Попробуйте выполнить этот пример: https://people.csail.mit.edu/hubert/pyaudio/docs/#example-callback-mode-audio-i-o – quasoft

ответ

4

Вы слышите «галочку», потому что в звуке, который вы отправляете, есть разрыв. Одна секунда 261,6 Гц содержит 261,6 циклов, так что вы в конечном итоге с около половины цикла осталось в конце:

Waveform showing discontinuity at 1 second

Вам необходимо либо изменить частоту таким образом, что существует целый ряд циклов в секунду (например, 262 Гц), изменяйте продолжительность так, чтобы она была достаточно длинной для целого числа циклов или создавала новый звуковой клип каждую секунду, которая начинается в правильной фазе, чтобы она соответствовала тому, где последний фрагмент остался.

+0

Ну, теперь, когда вы это говорите, я чувствую себя глупо. Позвольте мне настроить свой код так, чтобы я генерировал полный период и посмотрел, что произойдет. Это была моя попытка создать простой тестовый пример без необходимости воспроизводить более сложный код, но, очевидно, я не думал об этом. – larsks

+0

Отмечая это как ответ, потому что даже с кодом, который правильно генерирует полный период, я получаю неопределенные повторные результаты. Как и в, иногда он играет гладко, а иногда тот же код - без изменений - приводит к слышимому «ритму». Вернусь, если я смогу достоверно воспроизвести ... – larsks

1

Я искал аналогичный вопрос для вас и нашел вариацию, которая воспроизводит заранее рассчитанную длину, объединяя кучу предварительно рассчитанных фрагментов.

http://milkandtang.com/blog/2013/02/16/making-noise-in-python/

Используя для цикла с функцией 1-второй предварительно вычисленным куском «play_tone», кажется, генерировать плавный выход звучания, но это на ПК. Если это не сработает для вас, возможно, что у малины pi есть другая обратная реализация, которая не любит последовательные записи.

+0

Я закончил решение своей проблемы по-другому, а затем аккуратно упаковал ее и использовал ее для демонстрации в ночь на K-4 «STEM»: https://github.com/larsks/Python-Siggen – larsks

 Смежные вопросы

  • Нет связанных вопросов^_^