Генерация звука синусоидальной волны в Python

Мне нужно создать синусоидальный звук в Python, и мне нужно иметь возможность контролировать частоту, длительность и относительный объем. "Генерировать" я имею в виду, что я хочу, чтобы он сразу воспроизводил динамики, а не сохранял файл.

Каков самый простой способ сделать это?

Ответы

Ответ 1

import pyaudio
import numpy as np

p = pyaudio.PyAudio()

volume = 0.5     # range [0.0, 1.0]
fs = 44100       # sampling rate, Hz, must be integer
duration = 1.0   # in seconds, may be float
f = 440.0        # sine frequency, Hz, may be float

# generate samples, note conversion to float32 array
samples = (np.sin(2*np.pi*np.arange(fs*duration)*f/fs)).astype(np.float32)

# for paFloat32 sample values must be in range [-1.0, 1.0]
stream = p.open(format=pyaudio.paFloat32,
                channels=1,
                rate=fs,
                output=True)

# play. May repeat with different volume values (if done interactively) 
stream.write(volume*samples)

stream.stop_stream()
stream.close()

p.terminate()

Ответ 2

ivan-onys дал отличный ответ, но есть небольшое дополнение к нему: этот script произведет в 4 раза более короткий звук, чем ожидалось, потому что для метода записи Pyaudio нужны строковые данные float32, но когда вы передаете массив numpy этому методу, он преобразует весь массив как сущность в строку, поэтому вам нужно преобразовать данные в numpy массив в последовательность байтов:

samples = (np.sin(2*np.pi*np.arange(fs*duration)*f/fs)).astype(np.float32).tobytes()

и вы также должны изменить эту строку:

stream.write(samples)

Ответ 3

Одним из наиболее простых и простых в установке способов обработки звука в Python являются мультимедийные библиотеки Pygame.

Я бы рекомендовал использовать его - есть подмодуль pygame.sndarray, который позволяет вам манипулировать числами в векторе данных, который становится звуковым объектом высокого уровня, который может быть playerd в модуле pygame.mixer.

Документация на сайте pygame.org должна быть достаточной для использования модуля sndarray.

Ответ 4

Сегодня для Python 3.5+ лучший способ - установить пакеты, рекомендованные разработчиком.

http://people.csail.mit.edu/hubert/pyaudio/

Для Debian do

sudo apt-get install python3-all-dev portaudio19-dev

прежде чем пытаться установить pyaudio

Ответ 5

Я bragman lab toolbox у вас есть набор функций, которые делают именно то, что вы хотите. Этот модуль python немного глючит, но вы можете адаптировать этот код для получения собственных функций.

Ответ 6

так какие-нибудь примеры о том, как увеличить конверт в качестве рекламы?

Ответ 7

Сценарий от ivan_onys выдает сигнал, который в четыре раза короче, чем предполагалось. Если TypeError возвращается, когда том является плавающим, попробуйте добавить .tobytes() в следующую строку.

stream.write((volume*samples).tobytes())

@mm_ float32 = 32 бита и 8 бит = 1 байт, поэтому float32 = 4 байта. Когда сэмплы передаются в stream.write как float32, число байтов (длительность) делится на 4. Записывание сэмплов обратно .tobytes() исправляет четвертность сэмпла при записи в float32.