تولید صدای بوق (موج سینوسی) با پایتون

اشتراک‌گذاری

صدای بوق ممتد از لحاظ فنی همان موج سینوسی با فرکانسی (بسامد) ثابت است. در این مطلب یک کد ساده و کوتاه پایتون ارائه می‌دهم که بدون استفاده از کتاب‌خانه‌های اضافی، می‌تواند یک بوق را با هر فرکانسی تولید کند و در یک فایل صوتی wave ذخیره کند.

import wave
import struct
import math

def gen_sine(t, freq):
    return math.sin(2  * freq * t)


w = wave.open("sine.wav", "w") 
w.setsampwidth(2)
w.setframerate(8000)
w.setnchannels(1)

freq = 4600

for t in range(18000):
    r = int(gen_sine(t, freq) * 2**15)
    b = struct.pack("<h", r)
    w.writeframes(b)

w.close()

همان‌طور که در کد بالا مشاهده می‌کنید تنها سه کتاب‌خانه که از کتاب‌خانه‌هایی هستند که معمولاً همراه پایتون ارائه می‌شوند، استفاده شده است.

  • متغیر freq فرکانس بوق تولیدی را مشخص می‌کند.
  • ماژول wave برای نوشتن یک فایل صوتی wave که فایلی خام است استفاده شده است.
  • همان‌طور که می‌بینید، طول هر نمونه ۲ بایت می‌باشد و هر نمونه یک عدد صحیح علامت‌دار ۱۶ بیتی است.
  • تعداد کانال‌ها تک است و در نتیجه صدای راست و چپ نداریم. اصطلاحاً فایل صوتی مونو تولید می‌شود.
  • ۸۰۰۰ نمونه در یک ثانیه وجود دارد.
  • حلقهٔ for تعداد ۱۸۰۰۰ نمونه تولید می‌کند و با توجه به وجود ۸۰۰۰ نمونه در یک ثانیه، فایل تولیدی کمی بیش‌تر از ۲ ثانیه خواهد بود.
  • ابتدا با استفاده از تابع gen_sine براساس زمان فعلی (یا دقیق‌تر: شمارهٔ نمونه فعلی) و فرکانس مقدار عددی نمونه را محاسبه می‌کند.
  • با توجه به این که مقدار محاسبه شدهٔ این تابع یک عدد اعشاری است و با یک عدد صحیح ۱۶ بیتی نیاز داریم، خروجی تابع در ۳۲۷۶۸ (یا ۲ به توان ۱۵) ضرب می‌شود و قسمت اعشاری‌اش دور انداخته می‌شود.
  • سپس با استفاده از تابع pack از ماژول struct عدد صحیح به بایت تبدیل می‌شود. علامت «کوچک‌تر از» نشان‌دهنده little endian بودن بایت‌های تولیدی است. همچین حرف h نشان‌دهندهٔ این است که ورودی تابع pack یک عدد صحیح ۱۶ بیتی علامت‌دار است.
  • نهایتاً فریم‌های تولیدی به روی فایل صوتی نوشته می‌شوند و در نهایت فایل بسته می‌شود.

مستندات

اشتراک‌گذاری