صدای تاخیر کم

صدای تاخیر کم باعث می‌شود بازی‌ها واقعی‌تر و پاسخ‌گوتر به نظر برسند.

چک لیست زیر را برای فعال کردن صدای تاخیر کم در بازی خود در اندروید تکمیل کنید:

  1. از ابوا استفاده کنید
  2. درخواست حالت عملکرد "تأخیر کم"
  3. درخواست حالت اشتراک "انحصاری"
  4. از 48000 هرتز یا مبدل نرخ نمونه Oboe استفاده کنید
  5. میزان مصرف را روی AAUDIO_USAGE_GAME تنظیم کنید
  6. از تماس های داده استفاده کنید
  7. از مسدود کردن عملیات در پاسخ به تماس خودداری کنید
  8. تنظیم اندازه بافر به "دبل بافر"

1. از API Oboe استفاده کنید

Oboe API یک بسته بندی C++ است که AAudio را در اندروید 8.1 (سطح API 27) یا بالاتر فراخوانی می کند. در نسخه های قبلی اندروید، Oboe از OpenSL ES استفاده می کند.

Oboe در GitHub یا به عنوان یک باینری از پیش ساخته شده در دسترس است. Oboe همچنین دارای QuirksManager است که مشکلات موجود در دستگاه‌های خاص را تصحیح می‌کند، که برنامه شما را با دستگاه‌های بیشتری سازگار می‌کند. اگر نمی توانید از Oboe استفاده کنید، مستقیماً از AAudio استفاده کنید.

2. حالت تاخیر کم را درخواست کنید

با Oboe یا AAudio، حالت تاخیر کم را درخواست کنید. در غیر این صورت، به طور پیش فرض حالت تاخیر بالاتری دریافت می کنید.

ابوا

builder.setPerformanceMode(oboe::PerformanceMode::LowLatency);

AAaudio

AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);

3. درخواست حالت انحصاری

همچنین می توانید دسترسی انحصاری به بافر MMAP را درخواست کنید. برنامه شما ممکن است دسترسی انحصاری نداشته باشد، اما اگر دسترسی داشته باشد، برنامه شما مستقیماً در بافری می‌نویسد که توسط DSP خوانده می‌شود، که به برنامه شما کمترین تأخیر ممکن را می‌دهد.

ابوا

builder.setSharingMode(oboe::SharingMode::Exclusive);

AAaudio

AAudioStreamBuilder_setSharingMode(builder, AAUDIO_SHARING_MODE_EXCLUSIVE);

4. از تبدیل نرخ نمونه خودداری کنید

از نرخ نمونه طبیعی دستگاه استفاده کنید. شما می توانید این کار را با مشخص نکردن نرخ نمونه انجام دهید و تقریباً مطمئناً 48000 هرتز دریافت خواهید کرد. اگر نرخ نمونه را مشخص کنید، چارچوب صوتی داده‌های شما را در مسیر دیگری ارسال می‌کند که می‌تواند تاخیر بسیار بالاتری داشته باشد.

اگر نیاز به استفاده از نرخ نمونه متفاوت دارید، از Oboe برای انجام تبدیل نرخ نمونه استفاده کنید:

builder->setSampleRateConversionQuality(oboe::SampleRateConversionQuality::Medium);

5. مورد استفاده خود را به درستی اعلام کنید

تعیین دلیل پخش صدا توسط برنامه شما برای اعمال تنظیمات مسیریابی، صدا و عملکرد مناسب بسیار مهم است. برای مثال، بازی‌ها باید استفاده از AAUDIO_USAGE_GAME را نشان دهند تا از بهینه‌سازی‌های تأخیر، به‌ویژه زمانی که به هدست‌های بلوتوث وصل می‌شوند، بهره کامل ببرند.

ابوا

builder.setUsage(oboe::Usage::Game);

AAaudio

AAudioStreamBuilder_setUsage(builder, AAUDIO_USAGE_GAME);

6. از یک تابع callback استفاده کنید

از یک تماس برگشتی برای جریان خروجی استفاده کنید. اگر از نوشته‌های مسدودکننده استفاده می‌کنید و در دستگاهی هستید که از حالت MMAP AAaudio پشتیبانی نمی‌کند، ممکن است تأخیر بسیار بیشتر باشد.

ابوا

builder.setDataCallback(&myCallbackObject);

AAaudio

AAudioStreamBuilder_setDataCallback(builder, &my_callback_proc);

7. از مسدود شدن در پاسخ به تماس خودداری کنید

وقتی از جریانی با تأخیر کم استفاده می کنید، زمان بین تماس ها می تواند بسیار کوتاه باشد، فقط چند میلی ثانیه. بنابراین بسیار مهم است که در تماس برگشتی کاری که می تواند برای مدت طولانی مسدود شود، انجام ندهید. اگر تماس برگشتی مسدود شود، بافر از بین می رود و اشکالاتی در صدا رخ می دهد.

از انجام کارهای زیر در پاسخ به تماس خودداری کنید:

  • تخصیص یا آزادسازی حافظه
  • ورودی/خروجی فایل یا شبکه
  • در انتظار mutex یا قفل
  • بخواب
  • محاسبات سنگین CPU یک بار مصرف

تماس‌های بک باید با سرعت یکنواخت ریاضی را انجام دهند تا پخش روان و بدون اشکال انجام شود.

8. اندازه بافر را تنظیم کنید

هنگامی که برنامه شما جریان صوتی را باز می کند، باید اندازه بافر قابل استفاده را برای تأخیر بهینه تنظیم کنید. Oboe به طور خودکار اندازه بافر را روی دو انفجار تنظیم می کند. اما با AAudio، پیش فرض بسیار بالاتر است. با تنظیم اندازه بافر بر روی دو برابر اندازه انفجار، از بافر مضاعف استفاده کنید. اندازه پشت سر هم حداکثر اندازه پاسخ به تماس است.

AA audio:

int32_t frames = AAudioStream_getFramesPerBurst() * 2;
AAudioStream_setBufferSizeInFrames(stream, frames);

اگر اندازه بافر خیلی کوچک باشد، ممکن است با اشکالاتی ناشی از ریزش بافر مواجه شوید. می توانید با تماس با AAudioStream_getXRunCount(stream) تعداد اشکالات را دریافت کنید. در صورت نیاز اندازه بافر را افزایش دهید.

برای توضیح اصطلاحات مربوط به بافر، به اسناد GitHub Oboe مراجعه کنید.

OpenSL ES

اگر از نسخه های قبل از 8.1 اندروید پشتیبانی می کنید، باید از OpenSL ES استفاده کنید. اگر از Oboe استفاده می کنید، می توانید برنامه خود را برای بهبود تاخیر پیکربندی کنید. به دستیابی به تاخیر بهینه در اسناد GitHub مراجعه کنید.

نتایج چک لیست

جدول زیر شامل اندازه گیری OboeTester تاخیر رفت و برگشت (ورودی به خروجی) است.

پیکربندی تأخیر (ms)
تمام توصیه ها را دنبال کنید 20
حالت عملکرد نه تأخیر کم 205
غیر انحصاری (به اشتراک گذاشته شده) 26
44100 هرتز (AA صوتی) 160
44100 هرتز (Oboe SRC) 23
عدم استفاده از تماس خروجی (MMAP) 21
عدم استفاده از تماس خروجی (نه MMAP) 62
اندازه بافر روی حداکثر تنظیم شده است 53