کتابخانه wave در پایتون
کتابخانهٔ استاندارد «wave» در زبان برنامهنویسی پایتون، امکان خواندن و نوشتن فایلهای صوتی با فرمت WAV (یا WAVE) را فراهم میکند.
این ماژول به صورت پیشفرض در پایتون موجود است و نیازی به نصب جداگانه ندارد. در این مقاله قصد داریم به زبان فارسی با مفاهیم اصلی این کتابخانه، منطق کار آن، بهترین روشها و نکات مهم کار با فایلهای WAV آشنا شویم.
چرا فایلهای WAV؟
فایلهای WAV یکی از فرمتهای رایج برای ذخیرهٔ صوت خام (یا تقریباً خام) هستند و دارای ساختار سادهای برای ذخیره دادههای صوتی میباشند.
برخی مزایا عبارتند از:
- سادگی: فرمت WAV ساختار نسبتاًِ سادهای دارد و برای تحلیل یا ویرایش صوت مناسب است.
- کیفیت بالا: اغلب فایلهای WAV دادههای صوتی را به صورت PCM (بدون فشردهسازی) ذخیره میکنند و بنابراین کیفیت صوتی بالاتر از فرمتهای فشرده دارد.
- پشتیبانی گسترده: تقریباً بسیاری از ابزارها، کتابخانهها و سختافزارها فرمت WAV را پشتیبانی میکنند.
البته باید توجه داشت که فایلهای WAV ممکن است حجم بالایی داشته باشند، چون فشرده نشده هستند.
مفاهیم کلیدی و منطق کاری کتابخانهٔ wave
برای استفادهٔ مؤثر از ماژول wave لازم است چند مفهوم اساسی را بدانید:
پارامترهای فایل WAV
با باز کردن یک فایل WAV، میتوانید پارامترهایی مانند تعداد کانالها، عرض نمونه (sample width)، نرخ نمونهبرداری (frame rate)، تعداد فریمها و نوع فشردهسازی را مشاهده کنید. برای مثال:
- nchannels: تعداد کانالها (مثلاً ۱ برای مونو، ۲ برای استریو)
- sampwidth: عرض هر نمونه در تعداد بایتها (مثلاً 2 بایت برای 16-بیتی)
<li) framerate: تعداد فریم در ثانیه (مثلاً 44100 هرتز)
- nframes: تعداد کل فریمها در فایل
- comptype و compname: نوع عملیات فشردهسازی و نام آن (در ماژول wave فقط PCM بدون فشردهسازی پشتیبانی میشود)
خواندن فریمها (audio frames)
روش اصلی برای خواندن دادهٔ صوتی در ماژول wave، استفاده از متد readframes(n) است که «n» فریم بعدی را به صورت یک شیء بایت (bytes) برمیگرداند.
نکته این است که این بایتها به خودی خود معنا ندارند؛ باید بدانید که هر نمونه (sample) با چه عرضی ذخیره شده و سپس آنها را تبدیل به مقادیر عددی کنید.
نوشتن فایل WAV
برای نوشتن فایل WAV، از متدهایی مانند setnchannels()، setsampwidth()، setframerate() و سپس writeframes() استفاده میشود.
ماژول wave فقط از PCM بدون فشردهسازی پشتیبانی میکند، پس گزینههای کُدگذاری محدود است.
مثالهای کاربردی به همراه توضیح
۱. خواندن اطلاعات متادیتا و فریمها
import wave
with wave.open('audio.wav', 'rb') as wf:
params = wf.getparams()
nchannels = wf.getnchannels()
sampwidth = wf.getsampwidth()
framerate = wf.getframerate()
nframes = wf.getnframes()
frames = wf.readframes(nframes)
print("Channels:", nchannels)
print("Sample width (bytes):", sampwidth)
print("Frame rate (Hz):", framerate)
print("Number of frames:", nframes) توضیح: در این کد، فایل audio.wav برای خواندن باز میشود (‘rb’). سپس پارامترهای اصلی آن گرفته میشود و در نهایت همهٔ فریمها خوانده میشوند. خروجی شما میتواند برای تحلیل بیشتر صوت استفاده شود.
۲. تبدیل استریو به مونو
import wave
def stereo_to_mono(input_file, output_file):
with wave.open(input_file, 'rb') as inp:
params = inp.getparams()
nchannels, sampwidth, framerate, nframes, comptype, compname = params
```
if nchannels != 2:
raise ValueError("Input is not stereo")
with wave.open(output_file, 'wb') as outp:
outp.setnchannels(1)
outp.setsampwidth(sampwidth)
outp.setframerate(framerate)
outp.setcomptype(comptype, compname)
frames = inp.readframes(nframes)
mono_frames = bytearray()
for i in range(0, len(frames), sampwidth * 2):
left = int.from_bytes(frames[i:i+sampwidth], 'little', signed=True)
right = int.from_bytes(frames[i+sampwidth:i+2*sampwidth], 'little', signed=True)
mono_sample = ((left + right) // 2).to_bytes(sampwidth, 'little', signed=True)
mono_frames.extend(mono_sample)
outp.writeframes(mono_frames)
```
شرح: این تابع یک فایل استریو را باز میکند، پارامترها را میگیرد، سپس یک فایل مونو جدید با همان عرض نمونه و نرخ نمونهبرداری میسازد. سپس در حلقهٔ بایتها، نمونهٔ چپ و راست را میگیرد، میانگین میگیرد و آن را به عنوان نمونهٔ مونو مینویسد. در نهایت فایل خروجی ساخته میشود.
نکتهٔ بهبود: در این کد، اگر sampwidth برابر با 1 باشد (۸-بیتی) و unsigned باشد، باید تبدیل به signed انجام شود. بنابراین بهتر است قبل از اجرای کد، این مورد را بررسی کنیم.
۳. نوشتن یک فایل WAV ساده (صداسازی)
import math
import wave
FRAMES_PER_SECOND = 44100
DURATION_SECONDS = 2
FREQUENCY = 440
with wave.open('tone.wav', 'wb') as wf:
wf.setnchannels(1)
wf.setsampwidth(2) # 16-bit
wf.setframerate(FRAMES_PER_SECOND)
```
for i in range(int(DURATION_SECONDS * FRAMES_PER_SECOND)):
time = i / FRAMES_PER_SECOND
amplitude = int(32767 * math.sin(2 * math.pi * FREQUENCY * time))
wf.writeframes(amplitude.to_bytes(2, 'little', signed=True))
```
شرح: این مثال یک صدای سینوسی ساده تولید میکند با فرکانس ۴۴۰ هرتز (نت «لا») و مدت زمان ۲ ثانیه. سپس آن را در قالب فایل WAV ذخیره میکند. عرض نمونه ۲ بایت یعنی ۱۶ بیت است و کانال یک عددی یعنی مونو.
بهترین روشها و نکات کاربردی
- همیشه بررسی کنید که فایل ورودی «PCM بدون فشردهسازی» باشد چرا که ماژول wave فقط این حالت را پشتیبانی میکند.
- برای فایلهای صوتی بزرگ، از روشهای خواندن بخش-بخشی (chunking) استفاده کنید تا حافظه به سرعت به اتمام نرسد.
- تبدیل بایتها به اعداد صحیح و سپس به شناور بین -1 و 1 (normalization) میتواند کار را برای پردازش صوتی راحتتر کند.
- اگر لازم است صوت را پخش کنید، باید از کتابخانههای جداگانه استفاده نمایید؛ ماژول wave فقط برای خواندن/نوشتن فایل است.
- اگر میخواهید فایلهای صوتی را ادیت، ترکیب یا تغییر دهید، ممکن است استفاده از کتابخانههایی مانند pydub راحتتر باشد. اما اگر بخواهید کنترل دقیقتری بر بیتها داشته باشید، wave گزینهٔ مناسبی است.
مقایسهٔ موجز: مزایا و محدودیتها
| ویژگی | مزایا | محدودیتها |
|---|---|---|
| سادگی | ماژول از پیش نصب شده، بدون وابستگی اضافی | پشتیبانی فقط از PCM بدون فشردهسازی |
| کنترل سطح پایین | دسترسی به بایتها و تبدیل دلخواه | نیازمند دانستن ساختار بایتها و پردازش دستی |
| حجم فایل | کیفیت بالا، مناسب تحلیل دقیق | حجم بزرگ و احتمال مصرف بالای حافظه برای فایلهای طولانی |
| پخش صوت | — | هیچ قابلیت داخلی برای پخش یا ویرایش صوت ندارد |
نتیجهگیری فنی
ماژول wave در پایتون یک ابزار ساده اما قدرتمند برای کار با فایلهای WAV است، بهویژه زمانی که میخواهید کنترل دقیق روی دادهٔ صوتی داشته باشید و از سطح بالاتر گزینههایی مانند pydub فراتر بروید. با دانستن پارامترهای فایل WAV، روش خواندن و نوشتن فریمها و رعایت نکات حافظه و کارایی، میتوانید برنامههای تحلیل صوتی، تولید صدا یا تبدیل کانالها را به راحتی بنویسید.
آیا این مطلب برای شما مفید بود ؟




