2013-09-05 30 views
8

Tôi đang cố gắng để đọc một file wav, sau đó thao tác nội dung của nó, mẫu bằng mẫuLàm cách nào để thao tác dữ liệu tệp wav bằng Python?

Dưới đây là những gì tôi có cho đến nay:

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] 

Kết quả tôi nhận được là:

0 
0 
0 
0 
0 
0 

etc

Đọc đúng cách, bởi vì nếu tôi viết print data[i] thay vào đó, tôi thường nhận được các mảng khác không có kích thước 2.

Trả lời

11

Mảng data được trả về bởi wavfile.read là mảng có khối lượng với số nguyên . Các kiểu dữ liệu của một mảng NumPy không thể thay đổi tại chỗ, vì thế dòng này:

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

phôi kết quả của math.sin đến một số nguyên, mà sẽ luôn luôn là 0.

Thay vì dòng đó, tạo một mảng dấu chấm động mới để lưu trữ kết quả tính toán của bạn.

Hoặc sử dụng numpy.sin để tính sin của tất cả các yếu tố trong mảng cùng một lúc:

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 

Từ ý kiến ​​bổ sung của bạn, dường như bạn muốn lấy sin của mỗi giá trị và viết ra kết quả dưới dạng tệp wav mới.

Đây là một ví dụ mà tôi nghĩ rằng bạn làm những gì bạn muốn. Tôi sẽ sử dụng tệp 'M1F1-int16-AFsp.wav' từ đây: http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples.html. Hàm show_info chỉ là một cách thuận tiện để minh họa kết quả của từng bước. Nếu bạn đang sử dụng một trình bao tương tác, bạn có thể sử dụng nó để kiểm tra các biến và các thuộc tính của chúng.

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) 

Đây là đầu ra. (Cảnh báo ban đầu có nghĩa là có lẽ là một số siêu dữ liệu trong tập tin đó không được hiểu bởi scipy.io.wavfile.read.)

<snip>/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 

File mới 'newname.wav' chứa hai kênh của ký 16 giá trị bit.

+1

+1 để đề xuất 'np.sin (...)'. Đó chắc chắn là cách để đi, và nó sẽ là * cách * nhanh hơn. – nneonneo

+0

Cảm ơn. Tôi đã thử lưu các giá trị sin vào một mảng khác (hoặc về mặt kỹ thuật một danh sách), nhưng khi viết, tôi nhận được lỗi 'AttributeError:' list 'đối tượng không có thuộc tính' ndim'' – JVE999

+0

@Jamil, tôi nghĩ bạn sẽ muốn tự làm quen với các khái niệm cơ bản về mảng có nhiều mảng (ví dụ: http://www.engr.ucsb.edu/~shell/che210d/numpy.pdf hoặc http://wiki.scipy.org/Tentative_NumPy_Tutorial hoặc bất kỳ hướng dẫn nào khác trong nhiều hướng dẫn gọn gàng ngoài đó). Nếu không nhìn thấy những gì bạn đã làm, tôi không thể giải quyết vấn đề đó. –

Các vấn đề liên quan