2010-03-01 6 views
10

He estado usando Audiolab para importar archivos de sonido en el pasado, y funcionó bastante bien. Sin embargo:Importación de archivos de sonido en Python como matrices NumPy (alternativas al 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.`` 

Entonces me gustaría:

  • averiguar por qué no está funcionando en 2,6 (algo malo con _sndfile.pyd?) Y tal vez encontrar una manera de extenderlo a trabajar con formatos no compatibles
  • encontrar un reemplazo completo para Audiolab
+0

El problema es específico de Python 2.6 en Windows (es decir, no lo verá en python 2.5). No he encontrado una manera de arreglarlo aún –

+2

Y finalmente tomé el tiempo entre dos vuelos, terminó siendo un error de mingw. He publicado una nueva versión 0.11.0, que debería solucionar este problema. –

+1

David, ¡has creado una herramienta maravillosa en audiolab! Lo uso a menudo Gracias. –

Respuesta

9

AudioLab es trabajando para mí en Ubuntu 9.04 con Python 2.6.2, por lo que podría ser un problema de Windows. En su enlace al foro, el autor también sugiere que es un error de Windows.

En el pasado, esta opción ha trabajado para mí también:

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

Sólo ten en cuenta que puede tener dataint tipo de datos, por lo que no se amplíe el plazo de [-1,1). Por ejemplo, si data es int16, debe dividir data por 2**15 para escalar dentro de [-1,1).

+0

¿Puede scipy.io leer WAV de 24 bits? – endolith

+0

No estoy seguro de eso. 16 o 32 bits debería estar bien, pero no sé de 24 bits. –

+0

No lee mucho de nada. Incluso los archivos de 16 bits salen invertidos, con errores envolventes por un valor de -1. 24-bit obtiene "TypeError: tipo de datos no comprendido" Seguramente hay algo mejor ... – endolith

5

Sox http://sox.sourceforge.net/ puede ser tu amigo para esto. Puede leer muchos formatos diferentes y mostrarlos como sin procesar en cualquier tipo de datos que prefiera. De hecho, acabo de escribir el código para leer un bloque de datos de un archivo de audio en una matriz numpy.

Decidí tomar esta ruta por portabilidad (Sox está ampliamente disponible) y maximizar la flexibilidad de los tipos de audio de entrada que podría usar. De hecho, parece que, a partir de las pruebas iniciales, no es notablemente más lento para lo que lo estoy usando ... que está leyendo en pocas palabras (unos segundos) de audio de archivos muy largos (horas).

variables que necesitan:

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 

El código real es muy simple. Si desea extraer todo el archivo, puede eliminar las cosas start_samp, len_samp y '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 

PD: Aquí está el código para leer cosas de cabeceras de los archivos de audio usando 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

Interesante, aunque tipo de kludgy y tal vez no multiplataforma? Hay [pysox] (http://pypi.python.org/pypi/pysox) para interactuar directamente con la biblioteca [libSoX] (http://sox.sourceforge.net/libsox.html). Parece que [SoX admite varios formatos por su cuenta] (http://sox.sourceforge.net/Docs/Features) y puede usar varias otras bibliotecas para obtener más información. He tenido muchos problemas para hacer que funcione el audiolab, y no es compatible con MP3, etc., así que podría valer la pena intentar con pysox. – endolith

+1

Voy a mirar pysox ... gracias. Aunque el enfoque de subprocesos que utiliza sox no es realmente pitónico o bonito, es muy potente y relativamente portátil (ya que los sockets binarios/instaladores se pueden encontrar para la mayoría de los sistemas). – travc

3

FFmpeg es compatible con mp3 y funciona en Windows (http://zulko.github.io/blog/2013/10/04/read-and-write-audio-files-in-python-using-ffmpeg/).

Lectura de un archivo 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) 

formato a los datos en una matriz 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

En caso de que quiera hacer esto para MP3

Aquí es lo que estoy usando: Se usa pydub y scipy.

instalación completa (en Mac, pueden diferir en otros sistemas):

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 

crédito a James Thompson's blog

Cuestiones relacionadas