2011-12-14 39 views
10

đây là bài đăng đầu tiên của tôi trên ngăn xếp. Cho đến nay trang web này đã rất hữu ích, nhưng tôi là một người mới và cần một lời giải thích rõ ràng cho vấn đề của tôi, đó là liên quan đến âm thanh pitch-shifting trong Python. Tôi đã cài đặt các mô-đun hiện tại: numpy, scipy, pygame và scikits "samplerate" api.Python: Thay đổi Pitch of Audio File

Mục tiêu của tôi là lấy tệp âm thanh nổi và phát lại ở một bước khác trong ít bước nhất có thể. Hiện tại, tôi tải tệp vào một mảng bằng pygame.sndarray, sau đó áp dụng chuyển đổi lấy mẫu bằng scikits.samplerate.resample, sau đó chuyển đầu ra trở lại đối tượng âm thanh để phát lại bằng pygame. Vấn đề là âm thanh rác xuất phát từ loa của tôi. Chắc chắn tôi đang thiếu một vài bước (ngoài việc không biết gì về toán học và âm thanh).

Cảm ơn.

import time, numpy, pygame.mixer, pygame.sndarray 
from scikits.samplerate import resample 

pygame.mixer.init(44100,-16,2,4096) 

# choose a file and make a sound object 
sound_file = "tone.wav" 
sound = pygame.mixer.Sound(sound_file) 

# load the sound into an array 
snd_array = pygame.sndarray.array(sound) 

# resample. args: (target array, ratio, mode), outputs ratio * target array. 
# this outputs a bunch of garbage and I don't know why. 
snd_resample = resample(snd_array, 1.5, "sinc_fastest") 

# take the resampled array, make it an object and stop playing after 2 seconds. 
snd_out = pygame.sndarray.make_sound(snd_resample) 
snd_out.play() 
time.sleep(2) 

Trả lời

10

Vấn đề của bạn là pygame làm việc với numpy.int16 mảng nhưng cuộc gọi đến resample trả về một mảng numpy.float32:

>>> snd_array.dtype 
dtype('int16') 
>>> snd_resample.dtype 
dtype('float32') 

Bạn có thể chuyển đổi resample kết quả để numpy.int16 sử dụng astype:

>>> snd_resample = resample(snd_array, 1.5, "sinc_fastest").astype(snd_array.dtype) 

Với sửa đổi này, tập lệnh python của bạn phát độc đáo, ở độ cao thấp hơn và tốc độ thấp hơn.

+0

Ôi trời, tôi không biết cảm ơn bạn như thế nào. Không chờ đợi, tôi làm, tôi có thể gửi cho bạn tiền bia qua PayPal nếu bạn chấp nhận đề nghị của tôi. Tôi đã vô số giờ tìm kiếm một giải pháp. Cái này thật tuyệt. – hilmers

+1

Vui mừng khi thấy bạn thích phản ứng của tôi :) Bạn không cần phải cung cấp cho tôi bất cứ điều gì, câu hỏi của bạn là thú vị và tôi cũng đã học được một vài điều với nó! – kasyc

+0

Có thể lưu đối tượng pygame.micer.Sound đã sửa đổi thành tệp âm thanh thay vì phát không? –

0

Rất có thể scikits.samplerate.resample đang "suy nghĩ" âm thanh của bạn ở định dạng khác với âm thanh nổi 16 bit. Kiểm tra tài liệu trên scikits.samplerate về nơi để chọn định dạng âm thanh thích hợp trong mảng của bạn - Nếu nó lấy lại âm thanh 16 bit xử lý nó như rác 8 bit là những gì sẽ đi ra.

3

Đặt cược tốt nhất của bạn có thể là sử dụng bộ đọc python.

Đây là một liên kết, tôi đã sử dụng nó để làm cùng một loại điều, nó rất dễ dàng, chỉ cần đọc tất cả tài liệu.

http://audiere.sourceforge.net/home.php

+0

Cảm ơn, Audiere là lựa chọn đầu tiên của tôi, nhưng tôi không thể đưa nó vào _make_ mà không có lỗi. Tôi không quá sáng với những thứ này vì vậy tôi phải đi với những gì làm việc cho các kỹ năng hạn chế của tôi. – hilmers

+0

Điều này có vẻ tốt, nó hoạt động cho python 2.7? Nó có vẻ là cho python 2.2 –

0

Từ các tài liệu scikits.samplerate.resample:

Nếu đầu vào có thứ hạng 1, hơn tất cả các dữ liệu được sử dụng, và được giả định là từ một tín hiệu mono. Nếu xếp hạng là 2, các cột số sẽ được giả định là số kênh.

Vì vậy, tôi nghĩ rằng những gì bạn cần làm là một cái gì đó như thế này để vượt qua các dữ liệu âm thanh stereo để resample theo định dạng nó hy vọng:

snd_array = snd_array.reshape((-1,2)) 

snd_resample = resample(snd_array, 1.5, "sinc_fastest") 

snd_resample = snd_resample.reshape(-1) # Flatten it out again 
+0

Cảm ơn. Tôi đã thử đề xuất của bạn, nhưng cùng một đầu ra đi ra. – hilmers