¿Cómo manipular los datos del archivo wav en Python?

Estoy tratando de leer un archivo wav, luego manipular su contenido, muestra por muestra

Esto es lo que tengo hasta ahora:

import scipy.io.wavfile import math rate, data = scipy.io.wavfile.read('xenencounter_23.wav') for i in range(len(data)): data[i][0] = math.sin(data[i][0]) print data[i][0] 

El resultado que obtengo es:

 0 0 0 0 0 0 

etc

Se está leyendo correctamente, porque si escribo print data[i] lugar, normalmente obtengo matrices de tamaño 2 que no son cero.

Los data matriz devueltos por wavfile.read son una matriz numpy con un tipo de datos entero . El tipo de datos de una matriz numpy no se puede cambiar en su lugar, por lo que esta línea:

 data[i][0] = math.sin(data[i][0]) 

math.sin el resultado de math.sin a un entero, que siempre será 0.

En lugar de esa línea, cree una nueva matriz de punto flotante para almacenar el resultado calculado.

O use numpy.sin para calcular el seno de todos los elementos de la matriz a la vez:

 import numpy as np import scipy.io.wavfile rate, data = scipy.io.wavfile.read('xenencounter_23.wav') sin_data = np.sin(data) print sin_data 

De sus comentarios adicionales, parece que desea tomar el seno de cada valor y escribir el resultado como un nuevo archivo wav.

Aquí hay un ejemplo que (creo) hace lo que quieres. Usaré el archivo ‘M1F1-int16-AFsp.wav’ desde aquí: http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples.html . La función show_info es solo una forma conveniente de ilustrar los resultados de cada paso. Si está utilizando un shell interactivo, puede usarlo para inspeccionar las variables y sus atributos.

 import numpy as np from scipy.io import wavfile def show_info(aname, a): print "Array", aname print "shape:", a.shape print "dtype:", a.dtype print "min, max:", a.min(), a.max() print rate, data = wavfile.read('M1F1-int16-AFsp.wav') show_info("data", data) # Take the sine of each element in `data`. # The np.sin function is "vectorized", so there is no need # for a Python loop here. sindata = np.sin(data) show_info("sindata", sindata) # Scale up the values to 16 bit integer range and round # the value. scaled = np.round(32767*sindata) show_info("scaled", scaled) # Cast `scaled` to an array with a 16 bit signed integer data type. newdata = scaled.astype(np.int16) show_info("newdata", newdata) # Write the data to 'newname.wav' wavfile.write('newname.wav', rate, newdata) 

Aquí está la salida. (La advertencia inicial significa que quizás haya algunos metadatos en el archivo que scipy.io.wavfile.read no comprende).

 /scipy/io/wavfile.py:147: WavFileWarning: Chunk (non-data) not understood, skipping it. WavFileWarning) Array 'data' shape: (23493, 2) dtype: int16 min, max: -7125 14325 Array 'sindata' shape: (23493, 2) dtype: float32 min, max: -0.999992 0.999991 Array 'scaled' shape: (23493, 2) dtype: float32 min, max: -32767.0 32767.0 Array 'newdata' shape: (23493, 2) dtype: int16 min, max: -32767 32767 

El nuevo archivo ‘newname.wav’ contiene dos canales de valores de 16 bits firmados.