یک وظیفهی دیگر از Webnevisan روی همان اپلیکیشن تست لپتاپ کار تشخیص پورت — اینبار نیازمندی این بود که تأیید شود میکروفون و هر دو بلندگوی یک لپتاپ واقعاً کار میکنند، خودکار، بدون اینکه کسی هدفون بزند یا برای بررسی داخل میکروفون صحبت کند.
چالش: بدون نظارت اثبات شود که میکروفون صدای واقعی ضبط میکند و هرکدام از دو بلندگو — چپ و راست، جداگانه — واقعاً صدا تولید میکند. هیچ انسانی حضور ندارد تا بگوید «بله، آن را شنیدم» یا «بله، صدایم را شنید».

یک تست که دو چیز را همزمان اثبات میکند
بینشی که همهچیز دیگر را شکل داد: میکروفون و بلندگوها را بهعنوان دو پروب جداگانه تست نکنید. بگذارید خود بلندگوی لپتاپ چیز خاصی بگوید، و خود میکروفون لپتاپ سعی کند آن را بشنود. اگر میکروفون چیزی نزدیک به آنچه واقعاً گفته شده را رونویسی کند، همان یک رفتوبرگشت هردو نیمه را همزمان اثبات میکند — بلندگو صدای قابلشنیدن تولید کرد، و میکروفون صدای قابلاستفاده ضبط کرد. هیچکدام از نتایج بدون دیگری معنایی ندارد، پس یک تست هر دو را تأیید میکند بهجای دو تست ضعیفتر که هیچچیز را تأیید نمیکنند.
ساختن عبارتی که هیچچیز دیگری نمیتوانست گفته باشد
خود عبارت از شمارهی سریال دستگاه مشتق میشود، پس به همان دستگاه فیزیکی دقیق گره خورده بهجای یک رشتهی ثابت که هر واحد آن را تکرار کند. اپلیکیشن سریال را میگیرد، هرچه حرف یا رقم نیست را حذف میکند، ۳ کاراکتر آخر را نگه میدارد، آنها را بزرگ میکند، و آن قطعهی ۳کاراکتری را سه بار تکرار میکند — یک عبارت عبور ۹کاراکتری ساختهشده از یک هستهی ۳کاراکتری، که به تشخیصگر سیگنال بیشتری برای چنگ زدن میدهد تا یک انفجار کوتاه تکی.
حروف را مثل حروف بهنظر برساند، نه همآواها
دادن یک حرف لخت به یک موتور گفتار، دعوت به دردسر است — «C» را بلند بگویید و یک شنونده (انسان یا ماشین) «see» میشنود، نه خود حرف. پس هر کاراکتر در عبارت عبور قبل از گفتهشدن ترجمه میشود: رقمها همان رقم میمانند، چون یک موتور TTS آنها را تمیز تلفظ میکند، اما هر حرف با یک کلمهی کامل که با آن شروع میشود جایگزین میشود، از یک فهرست ثابت ۲۶کلمهای — C میشود cat، K میشود key، و همینطور. هم اپلیکیشن کلاینت و هم تشخیصگر از همان فهرست کلمات کار میکنند، پس حرفی که بهشکل یک کلمه بیرون میرود، در سمت دیگر بهمعنای همان حرف برمیگردد.
صحبت از یک بلندگو در هر لحظه
تبدیل عبارت عبور به صدا مختص هر پلتفرم است: در ویندوز، پکیج say صدای داخلی SAPI را هدایت میکند؛ در لینوکس، espeak-ng مستقیماً صدا زده میشود، عمداً کندشده با فاصلهی اضافه بین کلمات برای وضوح. در هر دو حالت نتیجه یک فایل WAV است، رمزگشاییشده از طریق Web Audio API و مسیردهیشده از یک StereoPannerNode که بهشدت چپ (-1) یا راست (+1) پن شده — پس اساساً فقط از یک بلندگوی فیزیکی در هر لحظه پخش میشود. کل توالی دوبار اجرا میشود، یکبار برای هر کانال، هرکدام با ضبط میکروفون مستقل خودش، پس یک بلندگوی راست ناموفق پشت یک بلندگوی چپ موفق پنهان نمیشود.
یک تشخیصگر گفتار آفلاین و محدودشده
کلیپ ضبطشده برای هر کانال به یک API کوچک Flask آپلود میشود، با pydub/ffmpeg به PCM تککاناله ۱۶کیلوهرتز و ۱۶بیتی تبدیل میشود، و به Vosk داده میشود — یک تشخیصگر گفتار آفلاین ساختهشده روی موتور تشخیص C++ کالدی، در معرض یک wrapper پایتون. آفلاین بودن اینجا اهمیت دارد: این بدون نظارت در برابر سختافزار واقعی لپتاپ و نویز محیط اجرا میشود، بدون هیچ رفتوبرگشتی به یک API گفتار ابری برای وابستگی. گرامر Vosk هم فقط به واژگانی محدود شده که ممکن است واقعاً ظاهر شود — ۲۶ کلمهی حرفی بهعلاوه کلمات گفتاری اعداد — بهجای رمزگشایی در برابر یک واژگان باز، که برای عبارتی به این کوتاهی و اینقدر ثابت در شکل، دقت را معنادار بهبود میدهد.
مقایسهی آنچه گفته شد با آنچه شنیده شد
هم عبارت مورد انتظار و هم رونویسی Vosk، قبل از مقایسه از همان نرمالساز رد میشوند — تاکردن کلمات گفتاری اعداد به ارقام، تاکردن اشتباهات شنیداری رایج («TOO»/«TO» به ۲، «FOR»/«FUR» به ۴، «ATE» به ۸)، و تاکردن شکل رونویسیشدهی هر کلمهی حرفی به تکحرف خودش، پس «key» که از تشخیصگر برمیگردد دوباره «K» میشود — مستقیماً قابلمقایسه با قطعهی سریال مورد انتظار. دو رشتهی نرمالشده بعد با یک نسبت شباهت مبتنی بر Levenshtein نمرهدهی میشوند (fuzzywuzzy، پشتیبانیشده با افزونهی کامپایلشدهی python-Levenshtein برای سرعت)، با آستانهی تطابق که عمداً سخاوتمندانه تنظیم شده — سختافزار واقعی، نویز محیط، و یک صدای مصنوعی، یک رونویسی دقیق را غیرواقعبینانه میکند، پس معیار «واضحاً همین عبارت» است، نه «کاراکتربهکاراکتر بینقص».
نتیجهی نهایی
اپلیکیشن تست لپتاپ یک نتیجه بهازای هر کانال میگیرد — قبولی یا شکست بلندگوی چپ، قبولی یا شکست بلندگوی راست، تأیید کارکرد میکروفون — بهجای یک چکباکس مبهم «صدا: خوب است»، کاملاً بدون اینکه کسی بشنود یا صحبت کند. این کنار کار تشخیص پورت منتشر شد، بهعنوان بخشی از همان تلاش گستردهتر برای تست سختافزاری که خود سیستمعامل قابلاعتماد برای گزارش صادقانهاش نبود.
چه چیزی از این تجربه یاد گرفتم
- وقتی دو چیز فقط میتوانند با هم تأیید شوند، یک تست طراحی کنید که هردو را اثبات کند — یک نتیجهی میکروفون فقط وقتی معنایی دارد که بدانید یک صدای واقعی هم واقعاً برای شنیدن تولید شده.
- یک گرامر محدودشده برای عبارتی که شکلش را از قبل کامل میدانید، از یک مدل گفتار عمومی بهتر است — برای واژگان بازی که یک عبارت عبور با فرمت ثابت هرگز به آن نیاز ندارد، هزینه ندهید.
- وقتی یک ماشین باید چیزی بگوید که قرار است دقیقاً فهمیده شود، به املای واقعی اعتماد نکنید — عبارت را حول آنچه یک شنونده واقعاً میشنود طراحی کنید، نه آنچه فنی نوشته شده.