2010-03-01 9 views
10

Używam Audiolab do importowania plików dźwiękowych w przeszłości i działało całkiem nieźle. Jednakże:Importowanie plików dźwiękowych do Pythona jako tablice NumPy (alternatywy dla audiolabu)

-

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.`` 

Więc chciałbym albo:

  • dowiedzieć się, dlaczego to nie działa w 2.6 (coś z _sndfile.pyd?) I może znaleźć sposób, aby go przedłużyć do pracy z nieobsługiwanych formatów
  • Znajdź pełne zastąpienie Audiolab
+0

Problem dotyczy programu python 2.6 w systemie Windows (to znaczy, że nie będzie go widać na pythonie 2.5). Nie znalazłem jeszcze sposobu, żeby to naprawić. –

+2

W końcu wziąłem czas pomiędzy dwoma lotami, co skończyło się błędem. Opublikowałem nową wersję 0.11.0, która powinna rozwiązać ten problem. –

+1

David, zrobiłeś wspaniałe narzędzie w audiolab! Często go używam. Dziękuję Ci. –

Odpowiedz

9

Audiolab jest działa dla mnie na Ubuntu 9.04 z Pythonem 2.6.2, więc może to być problem z Windows. W linku do forum autor sugeruje również, że jest to błąd systemu Windows.

W przeszłości ta opcja pracował dla mnie, zbyt:

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

Tylko uważaj, że data może mieć int typ danych, więc to nie jest skalowany w ciągu [-1,1). Na przykład, jeśli data jest int16, musisz podzielić data przez 2**15 na skalę w granicach [-1,1).

+0

Czy scipy.io może odczytać 24-bitowe pliki WAV? – endolith

+0

Nie jestem tego pewien. 16- lub 32-bitowe powinny być w porządku, ale nie wiem o 24-bitowym. –

+0

Nie czyta dużo z niczego. Nawet pliki 16-bitowe są odwrócone, z błędami zawijania do wartości -1. 24-bitowy dostaje "TypeError: typ danych nierozpoznany" Na pewno jest coś lepszego ... – endolith

5

Sox http://sox.sourceforge.net/ może być twoim przyjacielem. Może czytać wiele różnych formatów i wyświetlać je jako surowe w dowolnym typie danych, który preferujesz. Właściwie to właśnie napisałem kod, aby odczytać blok danych z pliku audio do tablicy numpy.

Zdecydowałem się na tę przenośność (sox jest bardzo szeroko dostępny) i zmaksymalizować elastyczność wejściowych typów audio, które mogłem wykorzystać. W rzeczywistości wydaje się, że z początkowego testowania nie jest to zauważalnie wolniejsze w przypadku tego, czego używam, ponieważ ... co oznacza krótki (kilka sekund) dźwięk z bardzo długich (godzin) plików.

Zmienne trzeba:

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 

Rzeczywisty kod jest naprawdę proste. Jeśli chcesz wyodrębnić cały plik, możesz usunąć pliki start_samp, len_samp i "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: Oto kod czytać rzeczy z nagłówków plików dźwiękowych wykorzystujących sox ...

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

Interesujące, choć trochę kludgy i może nie na różnych platformach? Jest [pysox] (http://pypi.python.org/pypi/pysox) do bezpośredniego połączenia z biblioteką [libSoX] (http://sox.sourceforge.net/libsox.html). Wygląda na to, że [SoX obsługuje tylko kilka formatów] (http://sox.sourceforge.net/Docs/Features) i może używać kilku innych bibliotek. Miałem wiele problemów z działaniem audiolabu i nie obsługuje on plików MP3 itp., Więc warto wypróbować pysoks. – endolith

+1

Spojrzę na pysoks ... dzięki. Chociaż podejście oparte na podprocesach przy użyciu sox nie jest w rzeczywistości pythonic lub pretty, jest ono bardzo wydajne i stosunkowo przenośne (ponieważ pliki binarne/instalatory sox można znaleźć w większości systemów). – travc

3

FFmpeg obsługuje pliki MP3 i działa na Windows (http://zulko.github.io/blog/2013/10/04/read-and-write-audio-files-in-python-using-ffmpeg/).

Odczytywanie pliku 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) 

danych formatu na numpy tablicy:

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

W przypadku, gdy chcesz to zrobić dla MP3

Oto co używam: Jest używa pydub i scipy.

Pełna konfiguracja (na Mac, może się różnić w innych systemach):

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 

zgłosił James Thompson's blog

Powiązane problemy