Python: изменение шага аудиофайла

Это мой первый пост на стек. До сих пор этот сайт был очень полезен, но я новичок и нуждаюсь в четком объяснении моей проблемы, связанной с переключением звука в Python. У меня установлены текущие модули: numpy, scipy, pygame и scikits "samplerate" api.

моя цель состоит в том, чтобы взять стереофайл и воспроизвести его на другом поле за несколько шагов. В настоящее время я загружаю файл в массив с помощью pygame.sndarray, затем применить samplerate преобразование с помощью scikits.оцифровки.повторите, затем преобразуйте вывод обратно в звуковой объект для воспроизведения с помощью pygame. Проблема в том, что звук мусора выходит из моих динамиков. Конечно, я пропустил несколько шагов (в дополнение к тому, что ничего не знаю о математике и аудио).

спасибо.

import time, numpy, pygame.mixer, pygame.sndarray
from scikits.samplerate import resample

pygame.mixer.init(44100,-16,2,4096)

# choose a file and make a sound object
sound_file = "tone.wav"
sound = pygame.mixer.Sound(sound_file)

# load the sound into an array
snd_array = pygame.sndarray.array(sound)

# resample. args: (target array, ratio, mode), outputs ratio * target array.
# this outputs a bunch of garbage and I don't know why.
snd_resample = resample(snd_array, 1.5, "sinc_fastest")

# take the resampled array, make it an object and stop playing after 2 seconds.
snd_out = pygame.sndarray.make_sound(snd_resample)
snd_out.play()
time.sleep(2)

4 ответов


ваша проблема в том, что pygame работает с numpy.int16 массивы, но вызов resample возвратить numpy.float32 время:

>>> snd_array.dtype
dtype('int16')
>>> snd_resample.dtype
dtype('float32')

вы можете конвертировать resample результат numpy.int16 используя astype:

>>> snd_resample = resample(snd_array, 1.5, "sinc_fastest").astype(snd_array.dtype)

С этой модификацией ваш скрипт python воспроизводит tone.wav файл красиво, с более низким шагом и более низкой скоростью.


лучше всего, вероятно, использовать python audiere.

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

http://audiere.sourceforge.net/home.php


скорее всего, scikits.оцифровки.resample "думает", что ваш звук находится в другом формате, чем 16-битный стерео. Проверьте документацию по scikits.samplerate о том, где выбрать правильный формат звука в массиве - Если он пересчитал 16-битный звук, рассматривая его как 8-битный мусор, это то, что выйдет.


С scikits.samplerate.resample документы:

если вход имеет ранг 1, то используются все данные и предполагается, что они из моносигнала. Если rank равен 2, число столбцов будет считаться числом каналов.

поэтому я думаю, что вам нужно сделать что-то вроде этого, чтобы передать стереоданные resample в формате он ожидает:

snd_array = snd_array.reshape((-1,2))

snd_resample = resample(snd_array, 1.5, "sinc_fastest")

snd_resample = snd_resample.reshape(-1) # Flatten it out again