Saya perlu menganalisis suara yang ditulis dalam file .wav. Untuk itu saya perlu mengubah file ini menjadi kumpulan angka (array, misalnya). Saya rasa saya perlu menggunakan paket gelombang. Namun, saya tidak tahu bagaimana tepatnya cara kerjanya. Misalnya saya melakukan yang berikut:
import wave
w = wave.open('/usr/share/sounds/ekiga/voicemail.wav', 'r')
for i in range(w.getnframes()):
frame = w.readframes(i)
print frame
Sebagai hasil dari kode ini saya berharap untuk melihat tekanan suara sebagai fungsi waktu. Sebaliknya, saya melihat banyak simbol aneh dan misterius (yang bukan merupakan angka heksadesimal). Adakah yang bisa, mohon, bantu saya dengan itu?
data
adalah array numpy 2-D sehinggadata.shape
mengembalikan tupel dari (num_samples, num_channels)Dengan menggunakan
struct
modul , Anda dapat mengambil frame gelombang (yang berada dalam biner komplementer 2 antara -32768 dan 32767 (yaitu0x8000
dan0x7FFF
). Ini membaca file MONO, 16-BIT, WAVE. Saya menemukan halaman web ini cukup berguna dalam merumuskan ini:import wave, struct wavefile = wave.open('sine.wav', 'r') length = wavefile.getnframes() for i in range(0, length): wavedata = wavefile.readframes(1) data = struct.unpack("<h", wavedata) print(int(data[0]))
Cuplikan ini membaca 1 bingkai. Untuk membaca lebih dari satu bingkai (mis., 13), gunakan
wavedata = wavefile.readframes(13) data = struct.unpack("<13h", wavedata)
sumber
Modul Python yang berbeda untuk membaca wav:
Setidaknya ada pustaka berikut ini untuk membaca file audio wave:
Contoh paling sederhana:
Ini adalah contoh sederhana dengan SoundFile:
import soundfile as sf data, samplerate = sf.read('existing_file.wav')
Format keluaran:
Peringatan, data tidak selalu dalam format yang sama, itu bergantung pada pustaka. Contohnya:
from scikits import audiolab from scipy.io import wavfile from sys import argv for filepath in argv[1:]: x, fs, nb_bits = audiolab.wavread(filepath) print('Reading with scikits.audiolab.wavread:', x) fs, x = wavfile.read(filepath) print('Reading with scipy.io.wavfile.read:', x)
Keluaran:
Reading with scikits.audiolab.wavread: [ 0. 0. 0. ..., -0.00097656 -0.00079346 -0.00097656] Reading with scipy.io.wavfile.read: [ 0 0 0 ..., -32 -26 -32]
SoundFile dan Audiolab kembali mengapung antara -1 dan 1 (seperti yang dilakukan matab, itu adalah konvensi untuk sinyal audio). Scipy dan wave return integer, yang dapat Anda ubah menjadi float sesuai dengan jumlah bit pengkodean, misalnya:
from scipy.io.wavfile import read as wavread samplerate, x = wavread(audiofilename) # x is a numpy array of integers, representing the samples # scale to -1.0 -- 1.0 if x.dtype == 'int16': nb_bits = 16 # -> 16-bit wav files elif x.dtype == 'int32': nb_bits = 32 # -> 32-bit wav files max_nb_bit = float(2 ** (nb_bits - 1)) samples = x / (max_nb_bit + 1) # samples is a numpy array of floats representing the samples
sumber
IMHO, cara termudah untuk mendapatkan data audio dari file suara ke dalam array NumPy adalah SoundFile :
import soundfile as sf data, fs = sf.read('/usr/share/sounds/ekiga/voicemail.wav')
Ini juga mendukung file 24-bit di luar kotak.
Ada banyak pustaka file suara yang tersedia, saya telah menulis ikhtisar di mana Anda dapat melihat beberapa pro dan kontra. Ia juga memiliki halaman yang menjelaskan bagaimana membaca file wav 24-bit dengan
wave
modul .sumber
Anda dapat melakukannya dengan menggunakan modul scikits.audiolab . Ini membutuhkan NumPy dan SciPy untuk berfungsi, dan juga libsndfile.
Catatan, saya hanya bisa membuatnya berfungsi di Ubunutu dan bukan di OSX.
from scikits.audiolab import wavread filename = "testfile.wav" data, sample_frequency,encoding = wavread(filename)
Sekarang Anda memiliki data wav
sumber
scikits.audiolab
belum diperbarui sejak 2010 dan mungkin hanya Python 2.Jika Anda ingin memproses audio blok demi blok, beberapa solusi yang diberikan cukup buruk dalam arti bahwa mereka menyiratkan memuat seluruh audio ke dalam memori menghasilkan banyak cache yang meleset dan memperlambat program Anda. python-wavefile menyediakan beberapa konstruksi pythonic untuk melakukan pemrosesan blok-demi-blok NumPy menggunakan manajemen blok yang efisien dan transparan melalui generator. Kelebihan pythonic lainnya adalah pengelola konteks untuk file, metadata sebagai properti ... dan jika Anda menginginkan seluruh antarmuka file, karena Anda sedang mengembangkan prototipe cepat dan Anda tidak peduli dengan efisiensi, seluruh antarmuka file masih ada.
Contoh pemrosesan sederhana adalah:
import sys from wavefile import WaveReader, WaveWriter with WaveReader(sys.argv[1]) as r : with WaveWriter( 'output.wav', channels=r.channels, samplerate=r.samplerate, ) as w : # Just to set the metadata w.metadata.title = r.metadata.title + " II" w.metadata.artist = r.metadata.artist # This is the prodessing loop for data in r.read_iter(size=512) : data[1] *= .8 # lower volume on the second channel w.write(data)
Contoh tersebut menggunakan kembali blok yang sama untuk membaca seluruh file, bahkan dalam kasus blok terakhir yang biasanya berukuran kurang dari ukuran yang diperlukan. Dalam hal ini Anda mendapatkan sepotong blok. Jadi percayalah pada panjang blok yang dikembalikan alih-alih menggunakan ukuran 512 yang di-hardcode untuk pemrosesan lebih lanjut.
sumber
Jika Anda akan melakukan transfer pada data bentuk gelombang maka mungkin Anda harus menggunakan SciPy , secara khusus
scipy.io.wavfile
.sumber
Saya perlu membaca file WAV 24-bit 1 saluran. Postingan Nak di atas sangat bermanfaat. Namun, seperti yang disebutkan di atas oleh basj 24-bit tidak langsung. Saya akhirnya berhasil menggunakan cuplikan berikut:
from scipy.io import wavfile TheFile = 'example24bit1channelFile.wav' [fs, x] = wavfile.read(TheFile) # convert the loaded data into a 24bit signal nx = len(x) ny = nx/3*4 # four 3-byte samples are contained in three int32 words y = np.zeros((ny,), dtype=np.int32) # initialise array # build the data left aligned in order to keep the sign bit operational. # result will be factor 256 too high y[0:ny:4] = ((x[0:nx:3] & 0x000000FF) << 8) | \ ((x[0:nx:3] & 0x0000FF00) << 8) | ((x[0:nx:3] & 0x00FF0000) << 8) y[1:ny:4] = ((x[0:nx:3] & 0xFF000000) >> 16) | \ ((x[1:nx:3] & 0x000000FF) << 16) | ((x[1:nx:3] & 0x0000FF00) << 16) y[2:ny:4] = ((x[1:nx:3] & 0x00FF0000) >> 8) | \ ((x[1:nx:3] & 0xFF000000) >> 8) | ((x[2:nx:3] & 0x000000FF) << 24) y[3:ny:4] = (x[2:nx:3] & 0x0000FF00) | \ (x[2:nx:3] & 0x00FF0000) | (x[2:nx:3] & 0xFF000000) y = y/256 # correct for building 24 bit data left aligned in 32bit words
Beberapa penskalaan tambahan diperlukan jika Anda membutuhkan hasil antara -1 dan +1. Mungkin beberapa dari Anda di luar sana mungkin menganggap ini berguna
sumber
jika hanya ada dua file dan kecepatan sampel sangat tinggi, Anda dapat menyisipkannya.
from scipy.io import wavfile rate1,dat1 = wavfile.read(File1) rate2,dat2 = wavfile.read(File2) if len(dat2) > len(dat1):#swap shortest temp = dat2 dat2 = dat1 dat1 = temp output = dat1 for i in range(len(dat2)/2): output[i*2]=dat2[i*2] wavfile.write(OUTPUT,rate,dat)
sumber
Anda juga dapat menggunakan
import wavio
perpustakaan sederhana. Anda juga perlu memiliki pengetahuan dasar tentang suara.sumber
PyDub ( http://pydub.com/ ) belum disebutkan dan itu harus diperbaiki. IMO ini adalah pustaka paling komprehensif untuk membaca file audio dengan Python saat ini, meskipun bukan tanpa kesalahannya. Membaca file wav:
from pydub import AudioSegment audio_file = AudioSegment.from_wav('path_to.wav') # or audio_file = AudioSegment.from_file('path_to.wav') # do whatever you want with the audio, change bitrate, export, convert, read info, etc. # Check out the API docs http://pydub.com/
PS. Contohnya adalah tentang membaca file wav, tetapi PyDub dapat menangani banyak format yang berbeda di luar kotak. Peringatannya adalah ini didasarkan pada dukungan asli Python wav dan ffmpeg, jadi Anda harus menginstal ffmpeg dan banyak kapabilitas pydub bergantung pada versi ffmpeg. Biasanya jika ffmpeg bisa melakukannya, begitu pula pydub (yang cukup kuat).
Non-disclaimer: Saya tidak terkait dengan proyek ini, tetapi saya adalah pengguna berat.
sumber