2010-03-01 2 views
10

Я использовал Audiolab для импорта звуковых файлов в прошлом, и это сработало довольно хорошо. Однако:Импорт звуковых файлов в Python в виде массивов NumPy (альтернативы аудиолабу)

-

In [2]: from scikits import audiolab 
-------------------------------------------------------------------- 

ImportError        Traceback (most recent call last) 

C:\Python26\Scripts\<ipython console> in <module>() 

C:\Python26\lib\site-packages\scikits\audiolab\__init__.py in <module>() 
    23 __version__ = _version 
    24 
---> 25 from pysndfile import formatinfo, sndfile 
    26 from pysndfile import supported_format, supported_endianness, \ 
    27      supported_encoding, PyaudioException, \ 

C:\Python26\lib\site-packages\scikits\audiolab\pysndfile\__init__.py in <module>() 
----> 1 from _sndfile import Sndfile, Format, available_file_formats, available_encodings 
     2 from compat import formatinfo, sndfile, PyaudioException, PyaudioIOError 
     3 from compat import supported_format, supported_endianness, supported_encoding 

ImportError: DLL load failed: The specified module could not be found.`` 

Я так же хотел бы:

  • Выяснить, почему он не работает в 2.6 (что-то не так с _sndfile.pyd?) И, возможно, найти способ, чтобы расширить его для работы с неподдерживаемых форматов
  • Найти полную замену AudioLab
+0

Проблема специфична для python 2.6 для окон (т. Е. Вы не увидите ее на python 2.5). Я еще не нашел способ исправить это. –

+2

И я, наконец, занял время между двумя рейсами, в итоге это стало ошибкой. Я опубликовал новую версию 0.11.0, которая должна исправить эту проблему. –

+1

Дэвид, ты сделал замечательный инструмент в аудиолабе! Я часто использую его. Спасибо. –

ответ

0

Я использую PySoundFile в последнее время вместо AudioLab. Он легко устанавливается с conda.

Это does not support mp3, как и большинство вещей. MP3 больше не запатентован, поэтому нет причин, по которым он не может его поддерживать; кто-то просто должен write support into libsndfile.

9

Audiolab является работая для меня на Ubuntu 9.04 с Python 2.6.2, так что это может быть проблема с Windows. В вашей ссылке на форум автор также предполагает, что это ошибка Windows.

В прошлом, этот вариант работает для меня тоже:

from scipy.io import wavfile 
fs, data = wavfile.read(filename) 

Только учтите, что data может иметь int тип данных, поэтому он не масштабируется в пределах [-1,1). Например, если data - int16, вы должны разделить data на 2**15 на шкалу в пределах [-1,1).

+0

Может ли scipy.io читать 24-битные WAV? – endolith

+0

Я не уверен в этом. 16- или 32-разрядный должен быть точным, но я не знаю о 24-бит. –

+0

Он ничего не читает. Даже 16-битные файлы выглядят инвертированными, с ошибками обхода для значения -1. 24-бит получает «TypeError: тип данных непонятен». Конечно, есть что-то лучше ... – endolith

5

Sox http://sox.sourceforge.net/ может быть для вас другом. Он может читать много разных форматов и выводить их как необработанные в любой тип данных, который вы предпочитаете. На самом деле, я просто написал код для чтения блока данных из аудиофайла в массив numpy.

Я решил пойти по этому маршруту для переносимости (sox очень широко доступен) и максимизировать гибкость входных аудио-типов, которые я мог бы использовать. На самом деле, кажется, из первоначального тестирования, что он не заметно медленнее для того, что я использую для ..., который читает короткие (несколько секунд) аудио из очень длинных (часов) файлов.

Переменные вам нужно:

SOX_EXEC# the sox/sox.exe executable filename 
filename # the audio filename of course 
num_channels # duh... the number of channels 
out_byps # Bytes per sample you want, must be 1, 2, 4, or 8 

start_samp # sample number to start reading at 
len_samp # number of samples to read 

Реальный код очень прост. Если вы хотите извлечь весь файл, вы можете удалить файлы start_samp, len_samp и «trim».

import subprocess # need the subprocess module 
import numpy as NP # I'm lazy and call numpy NP 

cmd = [SOX_EXEC, 
     filename,    # input filename 
     '-t','raw',   # output file type raw 
     '-e','signed-integer', # output encode as signed ints 
     '-L',     # output little endin 
     '-b',str(out_byps*8), # output bytes per sample 
     '-',     # output to stdout 
     'trim',str(start_samp)+'s',str(len_samp)+'s'] # only extract requested part 

data = NP.fromstring(subprocess.check_output(cmd),'<i%d'%(out_byps)) 
data = data.reshape(len(data)/num_channels, num_channels) # make samples x channels 

PS: Вот код для чтения вещи из аудио заголовков файлов с использованием Сокс ...

info = subprocess.check_output([SOX_EXEC,'--i',filename]) 
    reading_comments_flag = False 
    for l in info.splitlines(): 
     if(not l.strip()): 
      continue 
     if(reading_comments_flag and l.strip()): 
      if(comments): 
       comments += '\n' 
      comments += l 
     else: 
      if(l.startswith('Input File')): 
       input_file = l.split(':',1)[1].strip()[1:-1] 
      elif(l.startswith('Channels')): 
       num_channels = int(l.split(':',1)[1].strip()) 
      elif(l.startswith('Sample Rate')): 
       sample_rate = int(l.split(':',1)[1].strip()) 
      elif(l.startswith('Precision')): 
       bits_per_sample = int(l.split(':',1)[1].strip()[0:-4]) 
      elif(l.startswith('Duration')): 
       tmp = l.split(':',1)[1].strip() 
       tmp = tmp.split('=',1) 
       duration_time = tmp[0] 
       duration_samples = int(tmp[1].split(None,1)[0]) 
      elif(l.startswith('Sample Encoding')): 
       encoding = l.split(':',1)[1].strip() 
      elif(l.startswith('Comments')): 
       comments = '' 
       reading_comments_flag = True 
      else: 
       if(other): 
        other += '\n'+l 
       else: 
        other = l 
       if(output_unhandled): 
        print >>sys.stderr, "Unhandled:",l 
       pass 
+0

Интересно, хотя вроде kludgy и, возможно, не кросс-платформенный? Существует [pysox] (http://pypi.python.org/pypi/pysox) для непосредственного взаимодействия с библиотекой [libSoX] (http://sox.sourceforge.net/libsox.html). Похоже, что [SoX поддерживает кучу форматов самостоятельно] (http://sox.sourceforge.net/Docs/Features) и может использовать несколько других библиотек для большего. У меня было много проблем с работой аудиолаба, и он не поддерживает MP3 и т. Д., Поэтому pysox может стоить попробовать. – endolith

+1

Я посмотрю на pysox ... спасибо. Хотя подпроцессный подход с использованием sox на самом деле не является питоническим или симпатичным, он очень мощный и относительно портативный (поскольку для большинства систем могут быть найдены двоичные файлы/установщики sox). – travc

3

FFmpeg поддерживает mp3s и работает на Windows (http://zulko.github.io/blog/2013/10/04/read-and-write-audio-files-in-python-using-ffmpeg/).

Чтение файла mp3:

import subprocess as sp 

FFMPEG_BIN = "ffmpeg.exe" 

command = [ FFMPEG_BIN, 
     '-i', 'mySong.mp3', 
     '-f', 's16le', 
     '-acodec', 'pcm_s16le', 
     '-ar', '44100', # ouput will have 44100 Hz 
     '-ac', '2', # stereo (set to '1' for mono) 
     '-'] 
pipe = sp.Popen(command, stdout=sp.PIPE, bufsize=10**8) 

Формат данных в Numpy массив:

raw_audio = pipe.proc.stdout.read(88200*4) 

import numpy 

audio_array = numpy.fromstring(raw_audio, dtype="int16") 
audio_array = audio_array.reshape((len(audio_array)/2,2)) 
0

В случае, если вы хотите сделать это для MP3

Вот что я использую: Это использует pydub и scipy.

Полная установка (на Mac, могут отличаться от других систем):

import tempfile 
import os 
import pydub 
import scipy 
import scipy.io.wavfile 


def read_mp3(file_path, as_float = False): 
    """ 
    Read an MP3 File into numpy data. 
    :param file_path: String path to a file 
    :param as_float: Cast data to float and normalize to [-1, 1] 
    :return: Tuple(rate, data), where 
     rate is an integer indicating samples/s 
     data is an ndarray(n_samples, 2)[int16] if as_float = False 
      otherwise ndarray(n_samples, 2)[float] in range [-1, 1] 
    """ 

    path, ext = os.path.splitext(file_path) 
    assert ext=='.mp3' 
    mp3 = pydub.AudioSegment.from_mp3(FILEPATH) 
    _, path = tempfile.mkstemp() 
    mp3.export(path, format="wav") 
    rate, data = scipy.io.wavfile.read(path) 
    os.remove(path) 
    if as_float: 
     data = data/(2**15) 
    return rate, data 

Кредит James Thompson's blog