תוספים ל-Android

OpenSL ES ל-Android מרחיב את ההפניה למפרט OpenSL ES כדי שיהיה תואם ל Android, ולנצל את העוצמה והגמישות של פלטפורמת Android.

הגדרת ה-API לתוספים ל-Android נמצאת ב-OpenSLES_Android.h ואת קובצי הכותרות שכלולים בו. התייעצות עם OpenSLES_Android.h אפשר למצוא פרטים על התוספים האלה. קובץ זה נמצא מתחת לרמה הבסיסית (root) של ההתקנה, ספריית sysroot/usr/include/SLES. אלא אם כן הערה: כל הממשקים הם מפורשים.

התוספים האלה מגבילים את ניידות האפליקציה ל- הטמעות אחרות של OpenSL ES, כי הן ספציפיות ל-Android. אפשר לצמצם את הבעיה באמצעות להימנע משימוש בתוספים או על ידי שימוש ב-#ifdef כדי להחריג אותם בזמן הידור.

בטבלה הבאה מוצגים הממשקים ומאתרי הנתונים הספציפיים ל-Android שבהם יש תמיכה ב-Android OpenSL ES לכל סוג אובייקט. ערכי Yes בתאים מציינים את הממשקים והנתונים. מכלים שזמינים לכל סוג אובייקט.

תכונה נגן אודיו הקלטת אודיו מנוע תמהיל הפלט
התור של מאגר הנתונים הזמני ב-Android כן: מקור (פענוח) לא לא לא
תצורה של Android כן כן לא לא
אפקט ל-Android כן לא לא כן
יכולות אפקטים ב-Android לא לא כן לא
שליחת אפקט Android כן לא לא לא
תור פשוט למאגר נתונים זמני ב-Android כן: מקור (הפעלה) או sink (פענוח) כן לא לא
מאתר הנתונים בתור מאגר הנתונים הזמני ב-Android כן: מקור (פענוח) לא לא לא
מאתר נתונים של מתאר קובץ Android כן: מקור לא לא לא
מאתר הנתונים בתור מאגר נתונים זמני פשוט ב-Android כן: מקור (הפעלה) או sink (פענוח) כן: כיור לא לא

ממשק התצורה של Android

ממשק התצורה של Android מספק אמצעי להגדיר פרמטרים ספציפיים לפלטפורמה של אובייקטים. הממשק הזה שונה מפרוטוקולים אחרים של OpenSL ממשקי 1.0.1 שבהם האפליקציה יכולה להשתמש בו לפני יצירת האובייקט התואם. כך, אפשר להגדיר את האובייקט לפני יצירת האובייקט. קובץ כותרת מסוג OpenSLES_AndroidConfiguration.h, שנמצא בכתובת /sysroot/usr/include/SLES, מתעד את הערכים ומפתחות התצורה הזמינים הבאים:

  • סוג הסטרימינג לנגני אודיו (ברירת מחדל: SL_ANDROID_STREAM_MEDIA).
  • הקלטת פרופיל לרשמקולים (ברירת מחדל: SL_ANDROID_RECORDING_PRESET_GENERIC).

בקטע הקוד הבא מוצגת דוגמה להגדרת הסוג של שידור האודיו ל-Android באודיו שחקן:

// CreateAudioPlayer and specify SL_IID_ANDROIDCONFIGURATION
// in the required interface ID array. Do not realize player yet.
// ...
SLAndroidConfigurationItf playerConfig;
result = (*playerObject)->GetInterface(playerObject,
    SL_IID_ANDROIDCONFIGURATION, &playerConfig);
assert(SL_RESULT_SUCCESS == result);
SLint32 streamType = SL_ANDROID_STREAM_ALARM;
result = (*playerConfig)->SetConfiguration(playerConfig,
    SL_ANDROID_KEY_STREAM_TYPE, &streamType, sizeof(SLint32));
assert(SL_RESULT_SUCCESS == result);
// ...
// Now realize the player here.

אפשר להשתמש בקוד דומה כדי להגדיר את ההגדרה הקבועה מראש של מקליט אודיו:

// ... obtain the configuration interface as the first four lines above, then:
SLuint32 presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION;
result = (*playerConfig)->SetConfiguration(playerConfig,
    RECORDING_PRESET, &presetValue, sizeof(SLuint32));

ממשקי אפקטים ב-Android

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

אפליקציות ניידות צריכות להשתמש בממשקי API של OpenSL ES 1.0.1 ליצירת אפקטים קוליים במקום ב-Android תוספי אפקטים.

מאתר נתונים של מתאר קובץ Android

מאתר הנתונים של מתאר הקובץ ב-Android מאפשר לציין את המקור של נגן אודיו כמתאר קובץ פתוח עם גישת קריאה. פורמט הנתונים חייב להיות MIME.

התוסף הזה שימושי במיוחד בשילוב עם מנהל הנכסים המקורי, מכיוון האפליקציה קוראת נכסים מה-APK באמצעות מתאר קובץ.

ממשק וכלי לאיתור נתונים בתור מאגר נתונים זמני ל-Android

במפרט העזר של OpenSL ES 1.0.1, אפשר להשתמש בתורים למאגר נתונים זמני לנגני אודיו בלבד, תואמים ל-PCM ולפורמטים אחרים של נתונים. מאתר הנתונים הפשוט של מאגר הנתונים הזמני ומפרטי הממשק של Android זהה למפרט העזר, למעט שני יוצאים מן הכלל:

  • אתם יכולים להשתמש בתורים פשוטים למאגר נתונים זמני ב-Android עם מכשירי הקלטת אודיו ונגני אודיו.
  • אפשר להשתמש בפורמט הנתונים PCM רק בתורים האלה.

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

ההפעלה מתבצעת באותו אופן. לקוד מקור עתידי עם זאת, אנחנו ממליצים שאפליקציות ישתמשו ב-Android תורי מאגר נתונים זמני במקום תורי מאגר נתונים זמני של OpenSL ES 1.0.1.

ההתנהגות של מאגר הנתונים הזמני

ההטמעה ב-Android לא כוללת את הדרישה במפרט של ההפניה שסמן ההפעלה יחזור להתחלה של מאגר הנתונים הזמני שמופעל כשההפעלה נכנסת אל SL_PLAYSTATE_STOPPED . אופן הפעולה הזה יכול להתאים להתנהגות הזו, או שהוא עשוי להשאיר את המיקום של ההפעלה הסמן ללא שינוי. כתוצאה מכך, האפליקציה לא יכולה להניח שהתנהגות כזו מתרחשת. לכן, צריך לקרוא באופן מפורש ל-method BufferQueue::Clear() לאחר מעבר אל SL_PLAYSTATE_STOPPED. הפעולה הזו מגדירה את התור של מאגר הנתונים הזמני למצב ידוע.

באופן דומה, אין מפרט שקובע אם ההפעלה של קריאה חוזרת בתור מאגר נתונים זמני להיות מעבר אל SL_PLAYSTATE_STOPPED או ביצוע של BufferQueue::Clear(). לכן מומלץ לא ליצור תלות אחד או השני; במקום זאת, האפליקציה שלך צריכה להיות מסוגלת לטפל בשניהם.

ממשקים דינמיים ביצירת אובייקט

לנוחיותכם, תוכלו להטמיע את OpenSL ES 1.0.1 ב-Android. מאפשרת לאפליקציה לציין ממשקים דינמיים כשהיא יוצרת אובייקט. זו חלופה לשימוש ב-DynamicInterfaceManagement::AddInterface() כדי להוסיף את הממשקים האלה אחרי יצירת אובייקט.

דיווח על תוספים

יש שלוש שיטות לברר אם הפלטפורמה תומכת בתוספים ל-Android. האלה אלה הן:

  • Engine::QueryNumSupportedExtensions()
  • Engine::QuerySupportedExtension()
  • Engine::IsExtensionSupported()

כל אחת מהשיטות האלה מחזירה את הערך ANDROID_SDK_LEVEL_<API-level>, כאשר API-level הוא רמת ה-API של הפלטפורמה. לדוגמה, ANDROID_SDK_LEVEL_23. כשרמת ה-API של הפלטפורמה היא 9 ומעלה, הפלטפורמה תומכת בתוספים.

פענוח הקוד של אודיו ל-PCM

בקטע הזה מתואר תוסף ספציפי ל-Android שהוצא משימוש ל-OpenSL ES 1.0.1 לפענוח של זרם מקודד ל-PCM ללא הפעלה מיידית. בטבלה הבאה מפורטות המלצות לשימוש בתוסף הזה ובחלופות.

רמת ממשק API: אפשרויות אחרות
15 ומטה קודק קוד פתוח עם רישיון מתאים
16 עד 20 המחלקה MediaCodec או קודק קוד פתוח עם רישיון מתאים
21 ומעלה NDK MediaCodec בקובצי הכותרת של <media/NdkMedia*.h>, הכיתה MediaCodec, או קודק קוד פתוח עם רישיון מתאים

הערה: אין כרגע תיעוד לגרסת ה-NDK של ה-API של MediaCodec. אבל, לפעמים אפשר לעיין את הקוד לדוגמה של Native codec.

נגן אודיו סטנדרטי מופעל במכשיר אודיו, ומגדיר את תמהיל הפלט ומוגדר כ-data sink. ההבדל בין התוסף ל-Android לבין נגן האודיו הזה משמש כמפענח אם האפליקציה ציינה את מקור הנתונים כ-URI או כ-Android מאתר הנתונים של מתאר קובץ המתואר באמצעות פורמט נתוני MIME. במקרה כזה, ה-sink נתונים מאתר נתונים פשוט של תור מאגר נתונים זמני ב-Android שמשתמש בפורמט הנתונים PCM.

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

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

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

פורמט נתוני ה-PCM של ה-sink בדרך כלל תואם לפורמט של מקור הנתונים המקודד ביחס לקצב הדגימה, למספר הערוצים ולעומק הסיביות. אבל אפשר לפענח תדירות הדגימה, מספר הערוצים או עומק הסיביות. למידע נוסף על הוראה לזיהוי פורמט ה-PCM בפועל, ראו קביעת הפורמט של נתוני PCM מפוענחים באמצעות מטא-נתונים.

התכונה של OpenSL ES לפענוח PCM של Android תומכת בהשהיה ובדילוג ראשוני; הוא לא תומך בקרת עוצמת הקול, אפקטים, הפעלה בלופ או קצב ההפעלה.

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

הערה: כדי לפענח שידור מקודד ל-PCM אך לא להפעיל אותו באופן מיידי, באפליקציות שפועלות Android 4.x (רמות API 16-20), מומלץ להשתמש במחלקה MediaCodec. לאפליקציות חדשות שפועלות ב-Android 5.0 (רמת API 21) ומעלה, מומלץ להשתמש ב-NDK המקבילה: <NdkMedia*.h>. קובצי הכותרות האלה נמצאים ב- הספרייה media/ מתחת לרמה הבסיסית (root) של ההתקנה.

פענוח קוד של סטרימינג של ADTS AAC ל-PCM

נגן אודיו משמש כמפענח בסטרימינג אם מקור הנתונים הוא מאתר הנתונים בתור מאגר נתונים זמני של Android שמשתמש בפורמט נתוני MIME sink הוא כלי לאיתור נתונים בתור מאגר נתונים פשוט ל-Android, שמשתמש בפורמט של נתוני PCM. מגדירים את פורמט נתוני MIME באופן הבא:

  • מאגר: SL_CONTAINERTYPE_RAW
  • מחרוזת סוג MIME: SL_ANDROID_MIME_AACADTS

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

  • מקור האודיו הדחוס הוא זרם של פריימים מסוג AAC שכלולים בכותרות ADTS.
  • האפליקציה מנהלת את עדכוני התוכן האלה. הנתונים לא נמצאים בתוך משאב רשת שהמזהה שלו הוא URI או בתוך קובץ מקומי שהמזהה שלו מתאר קובץ.

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

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

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

למרות הדמיון בשמות, תור למאגר נתונים זמני של Android לא זהה לתור פשוט למאגר נתונים זמני ב-Android. הכלי לפענוח סטרימינג משתמשת בשני הסוגים של תורי מאגר נתונים למאגר נתונים ב-Android: תור למאגר נתונים זמני של Android ל-ADTS מקור נתונים AAC ותור של מאגר נתונים זמני פשוט ב-Android לנתוני ה-PCM ל-sink. מידע נוסף על ממשק ה-API של 'הבאים בתור' למאגר נתונים פשוט ב-Android זמין ב-Android ממשק ואיתור נתונים פשוט של תור מאגר נתונים זמני. למידע נוסף על ה-API של תור מאגר הנתונים הזמני ב-Android, אפשר לעיין בקובץ index.html ב- בספרייה docs/Additional_library_docs/openmaxal/ מתחת לרמה הבסיסית (root) של ההתקנה.

קביעת הפורמט של נתוני PCM מפוענחים באמצעות מטא-נתונים

הממשק של SLMetadataExtractionItf הוא חלק ממפרט ההפניה. עם זאת, מפתחות המטא-נתונים שמציינים את הפורמט בפועל של נתוני PCM מפוענחים הם ספציפיים Android. קובץ הכותרת OpenSLES_AndroidMetadata.h מגדיר את מפתחות המטא-נתונים האלה. קובץ הכותרת נמצא ברמה הבסיסית (root) של ההתקנה, במסגרת ספריית /sysroot/usr/include/SLES.

מדדי המפתח של המטא-נתונים זמינים מיד אחרי פעולת ה-method Object::Realize() מסיימת לפעול. אבל הערכים המשויכים לא רק אחרי שהאפליקציה מפענחת את הנתונים המקודדים הראשונים. טובה היא לבצע שאילתה על מדדי המפתח ב-thread הראשי אחרי קריאה ל-method של Object::Realize, ולקרוא את ערכי המטא-נתונים של פורמט ה-PCM בשיטה הפשוטה של Android ה-handler של קריאה חוזרת בתור מאגר נתונים זמני כשקוראים לו בפעם הראשונה. נכנסים ל- דוגמה לקוד חבילת NDK לדוגמאות לעבודה עם הממשק הזה.

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

נתוני נקודות צפות

אפליקציה שפועלת ב-Android 5.0 (רמת API 21) ואילך יכולה לספק נתונים לנגן אודיו ב פורמט מדויק עם נקודה צפה (floating-point).

בקוד לדוגמה הבא, השיטה Engine::CreateAudioPlayer() יוצרת נגן אודיו שמשתמשת בנתוני נקודה צפה (floating-point):

#include <SLES/OpenSLES_Android.h>
...
SLAndroidDataFormat_PCM_EX pcm;
pcm.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
pcm.numChannels = 2;
pcm.sampleRate = SL_SAMPLINGRATE_44_1;
pcm.bitsPerSample = 32;
pcm.containerSize = 32;
pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
pcm.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
...
SLDataSource audiosrc;
audiosrc.pLocator = ...
audiosrc.pFormat = &pcm;
מידע נוסף על אודיו עם נקודה צפה (floating-point) בדף 'דגימת אודיו'.