2010-03-01 16 views
10

Ho utilizzato Audiolab per importare file audio in passato e ha funzionato abbastanza bene. Tuttavia:Importazione di file audio in Python come array NumPy (alternative a audiolab)

-

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

Quindi vorrei:

  • capire perché non funziona a 2.6 (qualcosa di sbagliato con _sndfile.pyd?) E magari trovare un modo per estenderla a lavorare con formati non supportati
  • trovare un sostituto completo per AudioLab
+0

Il problema è specifico per python 2.6 su Windows (ad esempio non lo si vedrà su python 2.5). Non ho ancora trovato un modo per risolverlo, –

+2

E alla fine ho preso il tempo tra due voli, finendo per essere un bug mingw. Ho pubblicato una nuova versione 0.11.0, che dovrebbe risolvere questo problema. –

+1

David, hai creato uno strumento meraviglioso in audiolab! Lo uso spesso. Grazie. –

risposta

9

Audiolab è lavorando per me su Ubuntu 9.04 con Python 2.6.2, quindi potrebbe essere un problema di Windows. Nel tuo link al forum, l'autore suggerisce anche che si tratta di un errore di Windows.

In passato, questa opzione ha lavorato anche per me:

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

State attenti che data possono avere int tipo di dati, quindi non è in scala all'interno di [-1,1). Ad esempio, se data è int16, è necessario dividere per 2**15 in scala all'interno di [-1,1).

+0

Scipy.io può leggere WAV a 24 bit? – endolith

+0

Non ne sono sicuro. 16 o 32 bit dovrebbe andare bene, ma non so a 24 bit. –

+0

Non legge molto di nulla. Anche i file a 16 bit escono invertiti, con errori di avvolgimento per un valore di -1. 24-bit ottiene "TypeError: tipo di dati non compreso" Sicuramente c'è qualcosa di meglio ... – endolith

5

Sox http://sox.sourceforge.net/ può essere il tuo amico per questo. Può leggere molti molti formati diversi e visualizzarli come grezzi in qualsiasi tipo di dati che preferisci. In effetti, ho appena scritto il codice per leggere un blocco di dati da un file audio in un array numpy.

Ho deciso di seguire questa strada per la portabilità (il sox è ampiamente disponibile) e di ottimizzare la flessibilità dei tipi di audio in ingresso che potrei utilizzare. In realtà, dai test iniziali sembra che non sia notevolmente più lento per quello che sto usando per ... che sta leggendo a breve (pochi secondi) di audio da file molto lunghi (ore).

Variabili è necessario:

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 

Il codice reale è davvero semplice. Se vuoi estrarre l'intero file, puoi rimuovere il file start_samp, len_samp e '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: Qui è il codice per leggere roba da intestazioni dei file audio utilizzando 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

Interessante, anche se un po 'kludgy e forse non multipiattaforma? C'è [pysox] (http://pypi.python.org/pypi/pysox) per interfacciarsi direttamente con la libreria [libSoX] (http://sox.sourceforge.net/libsox.html). Sembra che [SoX supporti molti formati a parte] (http://sox.sourceforge.net/Docs/Features) e possa utilizzare diverse altre librerie per ulteriori informazioni. Ho avuto molti problemi nel far funzionare audiolab, e non supporta MP3, ecc., Quindi pysox potrebbe valere la pena provare. – endolith

+1

Guarderò pysox ... grazie. Sebbene l'approccio di sottoprocesso che usa sox non sia realmente pitonico o carino, è molto potente e relativamente portabile (dato che i binari/installatori di sox possono essere trovati per la maggior parte dei sistemi). – travc

3

FFmpeg supporta MP3 e funziona su Windows (http://zulko.github.io/blog/2013/10/04/read-and-write-audio-files-in-python-using-ffmpeg/).

lettura di un file 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) 

dati formato in un array di 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

Nel caso in cui si vuole fare questo per MP3

Ecco quello che sto usando: E ' utilizza pydub e scipy.

configurazione completa (su Mac, può essere diversa su altri sistemi):

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 

credito al James Thompson's blog

Problemi correlati