אודיו בזמן אחזור קצר

אודיו עם זמן אחזור קצר גורם למשחקים להיראות מציאותיים ורספונסיביים יותר.

צריך להשלים את רשימת המשימות הבאה כדי להפעיל אודיו עם זמן אחזור קצר במשחק Android:

  1. שימוש ב-Oboe
  2. בקשת מצב ביצועים 'זמן אחזור קצר'
  3. בקשת מצב שיתוף 'בלעדי'
  4. משתמשים ב-48,000 Hz או בממיר תדירות הדגימה של Oboe
  5. הגדרת השימוש ל-AAUDIO_USAGE_GAME
  6. שימוש בקריאות חוזרות (callbacks) של נתונים
  7. הימנעות מפעולות חסימה בקריאה החוזרת (callback)
  8. כוונון הגודל של מאגר הנתונים הזמני ל'מאגר נתונים זמני כפול'

1. שימוש ב-Oboe API

ה-API של Oboe הוא wrapper של C++ שקורא אודיו ב-Android 8.1 (API ברמה 27) ומעלה. בגרסאות קודמות של Android, Oboe משתמש ב-OpenSL ES.

Oboe זמין ב-GitHub או בשם קובץ בינארי שנוצר מראש. ל-Oboe יש גם QuirksManager שמתקן בעיות במכשירים ספציפיים, שמאפשר לאפליקציה שלכם להתאים למכשירים רבים יותר. אם לא ניתן להשתמש ב-Oboe, השתמשו אודיו ישיר.

2. שליחת בקשה למצב זמן אחזור קצר

באמצעות אבוב או אודיו, אפשר לבקש מצב זמן אחזור נמוך. אחרת, תקבל כברירת מחדל.

אבוב

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

אודיו

AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);

3. בקשת מצב בלעדי

אפשר גם לבקש גישה בלעדית למאגר הנתונים הזמני של MMAP. יכול להיות שהאפליקציה לא תקבל לגישה בלעדית, אבל אם זה קורה, האפליקציה כותבת ישירות במאגר נתונים זמני נקרא על ידי DSP, ולכן זמן האחזור של האפליקציה הוא הקצר ביותר שאפשר.

אבוב

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

אודיו

AAudioStreamBuilder_setSharingMode(builder, AAUDIO_SHARING_MODE_EXCLUSIVE);

4. הימנעות מהמרת תדירות דגימה

השתמשו בקצב הדגימה הטבעי של המכשיר. אפשר לעשות זאת אם לא מציינים וסביר להניח שתקבלו 48, 000 Hz. אם תציינו דוגמה היא שולחת את הנתונים לנתיב אחר, בזמן אחזור ארוך בהרבה.

אם צריך להשתמש בקצב דגימה אחר, משתמשים ב-Oboe כדי לבצע את קצב הדגימה conversion:

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

5. הצהרה נכונה על התרחיש לדוגמה שלכם

חשוב לציין את הסיבה להפעלת אודיו באפליקציה כדי שהמערכת תוכל ליישם אותה את הגדרות הניתוב, הנפח והביצועים הנכונים. לדוגמה, במשחקים לציין את השימוש ב-AAUDIO_USAGE_GAME כדי להפיק את המרב מזמן האחזור אופטימיזציות, במיוחד כאשר מחוברים לאוזניות Bluetooth.

אבוב

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

אודיו

AAudioStreamBuilder_setUsage(builder, AAUDIO_USAGE_GAME);

6. שימוש בפונקציית קריאה חוזרת

להשתמש בקריאה חוזרת (callback) לזרם הפלט. אם אתם משתמשים בחסימת כתיבה ואתם מפעילים במכשיר שלא תומך במצב AAudio MMAP, זמן האחזור עשוי להיות גבוהה יותר.

אבוב

builder.setDataCallback(&myCallbackObject);

אודיו

AAudioStreamBuilder_setDataCallback(builder, &my_callback_proc);

7. הימנעות מחסימה ב-callback

כשמשתמשים בשידור חי עם זמן אחזור קצר, משך הזמן בין הקריאה החוזרת עשוי להיות קצר, רק כמה אלפיות שנייה. לכן חשוב מאוד שלא לעשות כל פעולה בקריאה החוזרת (callback) שעלולה לחסום למשך זמן רב. אם הקריאה החוזרת היא חסום, יש זרימה מתחת למאגר הנתונים הזמני והתקלות באודיו.

יש להימנע מהפעולות הבאות בקריאה חוזרת (callback):

  • הקצאה או פינוי של זיכרון
  • קלט/פלט בקובץ או ברשת
  • בהמתנה ל-mutex או למנעול
  • שינה
  • חישובים כבדים של מעבד (CPU) חד-פעמיים

הקריאות החוזרות (callback) צריכות לבצע מתמטיקה בקצב שווה כדי לאפשר הפעלה חלקה ללא אחרות.

8. כוונון הגודל של מאגר הנתונים הזמני

אחרי שהאפליקציה פותחת את שידור האודיו, צריך לכוונן את הגודל של מאגר הנתונים הזמני שאפשר להשתמש בו לזמן אחזור אופטימלי. אבוב מגדיר אוטומטית את גודל מאגר הנתונים הזמני לשני רצפים. אבל באודיו, ברירת המחדל היא הרבה יותר גבוהה. משתמשים בתהליך אגירת נתונים כפולה על ידי הגדרה של שטח האחסון הזמני כפול מגודל הרצף. גודל הרצף הוא הערך המקסימלי לקריאה חוזרת (callback) גודל.

אודיו:

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

אם מאגר הנתונים הזמני קטן מדי, יכול להיות שיהיו תקלות שנגרמות על ידי מאגר הנתונים הזמני מתחת למילים. אפשר לקבל את מספר התקלות בטלפון AAudioStream_getXRunCount(stream) מגדילים את מאגר הנתונים הזמני לפי הצורך.

לצפייה מסמכי GitHub Oboe כדי לקבל הסבר על מונחים שקשורים למאגר הנתונים הזמני.

OpenSL ES

אם במכשיר שלכם יש תמיכה בגרסאות Android שקודמות לגרסה 8.1, צריך להשתמש OpenSL ES. אם משתמשים ב-Oboe, אפשר להגדיר את האפליקציה כדי לשפר את השירות את זמן האחזור. צפייה השגת זמן אחזור אופטימלי במסמכי GitHub.

תוצאות של רשימת משימות

הטבלה הבאה מכילה OboeTester מדידות של זמן האחזור הלוך ושוב (מקלט לפלט).

הגדרות אישיות זמן אחזור (באלפיות שנייה)
ביצוע כל ההמלצות 20
מצב ביצועים לא זמן אחזור קצר 205
לא בלעדי (משותפת) 26
44,100 Hz (AAudio) 160
44,100 Hz (Oboe SRC) 23
לא נעשה שימוש בקריאה חוזרת (callback) של פלט (MMAP) 21
לא נעשה שימוש בקריאה חוזרת (callback) של פלט (לא MMAP) 62
הגודל של מאגר הנתונים הזמני מוגדר למקסימום 53