שליטה במשרעת בעזרת מעצב עוצמת הקול

אפשר להשתמש ב-VolumeShaper באפליקציית אודיו כדי לבצע עמעום הדרגתי, דהייה מעברים שונים. המחלקה VolumeShaper זמינה ב-Android 8.0 (רמת API 26) ובהמשך.

כדי ליצור VolumeShaper, מפעילים את createVolumeShaper() במופע של AudioTrack או MediaPlayer. האפליקציה VolumeShaper פועלת רק באודיו שנוצר על ידי AudioTrack או MediaPlayer. שיצר אותה.

Volume shaper.Configuration

ההתנהגות של VolumeShaper מוגדרת לפי VolumeShaper.Configuration. התצורה מציינת *עקומת עוצמת הקול, סוג האינטרפולטור וגם משך הזמן.*

עקומת עוצמת הקול

עקומת הנפח מייצגת שינוי במשרעת לאורך זמן. מוגדר באמצעות צמד של מערכים צפים, x[] ו-y[] שמגדירים סדרה של נקודות בקרה. כל אחד (x, y) מייצג זמן ונפח בהתאמה. המערכים צריכים להיות באורך שווה והם כוללים לפחות 2 ולא יותר מ-16 ערכים. (אורך העקומה המקסימלי הוא הוגדרה ב-getMaximumCurvePoints()).

קואורדינטות הזמן ניתנות לאורך הרווח [0.0, 1.0]. בפעם הראשונה הנקודה חייבת להיות 0.0, האחרונה חייבת להיות 1.0, והזמנים חייבים להיות מונוטוניים הולכת וגדלה.

קואורדינטות הנפח נקראות בקנה מידה לינארי לאורך המרווח [0.0, 1.0].

סוג אינטרפולטור

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

  • Volumeshar.Configuration.INTERPOLATOR_TYPE_STEP
  • Volume shaper.Configuration.INTERPOLATOR_TYPE_LINEAR
  • Volume shaper.Configuration.INTERPOLATOR_TYPE_CUBIC
  • Volume shaper.Configuration.INTERPOLATOR_TYPE_CUBIC_MONOTONIC

משך הזמן

נקודות הזמן שצוינו במרווח [0.0, 1.0] מוקטנות אל משך הזמן שתציינו באלפיות השנייה. ההגדרה הזו קובעת את האורך בפועל של עקומת הנפח כשהמעצב פועל ומחילים את העקומה את פלט האודיו.

שימוש בכלי לעיצוב נפח

יצירת מערך הגדרות אישיות

לפני שיוצרים VolumeShaper, צריך ליצור מכונה של VolumeShaper.Configuration. כדי לעשות את זה באמצעות VolumeShaper.Configuration.Builder():

Kotlin

val config: VolumeShaper.Configuration = VolumeShaper.Configuration.Builder()
        .setDuration(3000)
        .setCurve(floatArrayOf(0f, 1f), floatArrayOf(0f, 1f))
        .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR)
        .build()

Java

VolumeShaper.Configuration config =
  new VolumeShaper.Configuration.Builder()
      .setDuration(3000)
      .setCurve(new float[] {0.f, 1.f}, new float[] {0.f, 1.f})
      .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR)
      .build();

With no arguments the VolumeShaper.Configuration.Builder constructor returns a builder that creates a configuration with default settings: INTERPOLATOR_TYPE_CUBIC, a one second duration, and no curve. You must add a curve to the builder before calling build().

The framework provides constants for configurations with pre-built curves, each with one second duration:

  • VolumeShaper.Configuration.LINEAR_RAMP
  • VolumeShaper.Configuration.CUBIC_RAMP
  • VolumeShaper.Configuration.SINE_RAMP
  • VolumeShaper.Configuration.SCURVE_RAMP

Creating a VolumeShaper

To create a VolumeShaper, call createVolumeShaper() on an instance of the appropriate class, passing in a VolumeShaper.Configuration:

Kotlin

volumeShaper = myMediaPlayer.createVolumeShaper(config)
volumeShaper = myAudioTrack.createVolumeShaper(config)

Java

volumeShaper = myMediaPlayer.createVolumeShaper(config);
volumeShaper = myAudioTrack.createVolumeShaper(config);

A single track or media player can have many shapers attached to it, and you can control each shaper separately. The outputs of all the shapers on a track or player are multiplied together. A VolumeShaper cannot be shared between AudioTracks or MediaPlayers, but you can use the same configuration in calls to createVolumeShaper to build identical shapers on multiple AudioTracks or MediaPlayers.

When you create the shaper, its first control point (at t = 0) is applied to the audio stream. If the initial volume is not 1.0 and your app is playing material at create time, your audio might have an abrupt change in volume. Best practice is to start playing audio from silence and use a VolumeShaper to implement a fade-in when playback starts. Create a VolumeShaper that starts at 0 volume and fades up. For example:

setCurve(new float[] {0.f, 1.f}, new float[] {0.f, 1.f})

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

הרצת מעצב עוצמת הקול

למרות שרמת עוצמת הקול של נקודת הבקרה הראשונה חלה על נתיב האודיו לאחר יצירת המעצב, המעצב לא מתקדם לאורך העקומה עד שקוראים ל-method apply() עם VolumeShaper.Operation.PLAY. אחרי כשיוצרים את המעצב, ההפעלה הראשונה של apply() חייבת לציין את PLAY הפעולה כדי להתחיל את המעצב. פעולה זו מריצה את העקומה מהראשון עד נקודות בקרה אחרונות:

Kotlin

shaper.apply(Volumeshar.Operation.PLAY)

Java

shaper.apply(VolumeFormr.Operation.PLAY);

בזמן שהכלי לעיצוב פועל אפשר ליצור הפעלות apply() מתחלפות. פעולות REVERSE ו-PLAY. זה משנה את הכיוון של הקריאה נקודות הבקרה בכל פעם.

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

כשפג תוקף המעצב, עוצמת הקול נשארת בהגדרה האחרונה, שיכולה להיות בנקודת הבקרה הראשונה או האחרונה. אפשר להתקשר אל VolumeShaper.getVolume() למשך עוצמת הקול הנוכחית בכל שלב.

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

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

שינוי העקומה

אפשר להשתמש בשיטה replace() כדי לשנות את העקומה של VolumeShaper. השיטה הזו הגדרה, פעולה ופרמטר איחוד. אפשר לקרוא ל- replace() בכל שלב, בזמן שהמעצב פועל או לאחר שהתוקף שלו פג:

Kotlin

val newConfig = Volume shaper.Configuration.Builder()
        .setDuration(1000)
        .setCurve(floatArrayOf(0f, 0.5f), floatArrayOf(0f, 1f))
        .setInterpolatorType(VolumeFormr.Configuration.INTERPOLATOR_TYPE_LINEAR)
        .build()
val join = true
shaper.replace(newConfig, Volume shaper.Operation.PLAY, join)

Java

Volumeshar.Configuration newConfig =
  new Volume shaper.Configuration.Builder()
    .setDuration(1000)
    .setCurve(new float[] {0.f, 0.5f}, float חדש[] {0.f, 1.f})
    .setInterpolatorType(VolumeFormr.Configuration.INTERPOLATOR_TYPE_LINEAR)
    .build();
איחוד בוליאני = true;
shaper.replace(newConfig, VolumeFormr.Operation.PLAY, join);

כשתתבצע קריאה למספר replace() בזמן שהכלי לעיצוב פועל, הוא מפסיק לשנות את ונשאר בערך הנוכחי שלו. לאחר מכן, המעצב ינסה להתחיל מנקודת הבקרה הראשונה. זה אומר שהארגומנט של הפעולה המדיניות קובעת אם המעצב יפעל אחרי השיחה. יש לציין את PLAY ל- להתחיל מיד את העקומה החדשה, לציין REVERSE כדי להשאיר את המעצב מושהה את הנפח של נקודת הבקרה הראשונה בעקומה החדשה. אפשר להתחיל את כלי המעצבים מאוחר יותר עם apply(VolumeShaper.Operation.PLAY).

כשקוראים לפונקציה replace() עם join = false, המעצב מתחיל בעקומה הרמה שצוינה בנקודת הבקרה הראשונה. הדבר עלול לגרום לאי-רציפות בעוצמת הקול. כדי להימנע מכך, אפשר להתקשר למספר replace() באמצעות join = true. הפעולה הזו מגדירה את נקודת הבקרה הראשונה של העקומה החדשה לרמה הנוכחית של ומשנה את הגודל של עוצמת הקול של כל נקודות הבקרה בין האחרון לשמור על הצורה היחסית של העקומה החדשה (נקודת הבקרה האחרונה ללא שינוי). פעולת ההתאמה לעומס (scaling) משנה באופן סופי את נקודות הבקרה העקומה החדשה של המעצבים.

הסרת מעצב עוצמת קול

המערכת נסגרת ונאספת אשפה על ידי VolumeShaper כאשר AudioTrack או MediaPlayer הושק או לא נמצא יותר בשימוש. אפשר לבצע קריאה ל-method close() עם מעצב אומנותי כדי להרוס אותו מיד. המערכת מסירה את המעצב בתוך כ-20 אלפיות השנייה. חשוב להיזהר כשסוגרים VolumeShaper בזמן שהאודיו נשמע. אם עוצמת הקול של המעצב היא פחות מ-1.0 כשמתקשרים close(), סולם עוצמת הקול של המעצב ישתנה ל-1.0. הדבר עלול לגרום בנפח גבוה יותר.