کنترل دامنه با VolumeShaper

می‌توانید از VolumeShaper در برنامه صوتی برای انجام محو تدریجی، ظاهر شدن تدریجی، محو متقاطع، کاهش صدای پس‌زمینه، و دیگر انتقال‌های خودکار کوتاه صدا استفاده کنید. کلاس VolumeShaper در Android 8.0 (سطح API‏ ۲۶) و نسخه‌های جدیدتر دردسترس است.

با فراخوانی createVolumeShaper() در نمونه‌ای از AudioTrack یا MediaPlayer، VolumeShaper ایجاد می‌کنید. VolumeShaper فقط روی صدای تولیدشده توسط AudioTrack یا MediaPlayer که آن را ایجاد کرده است عمل می‌کند.

VolumeShaper.Configuration

رفتار VolumeShaper با VolumeShaper.Configuration آن تعریف می‌شود. پیکربندی *منحنی حجم، نوع درون‌یاب، و مدت* را مشخص می‌کند.

منحنی میزان صدا

منحنی میزان صدا نشان‌دهنده تغییر دامنه درطول زمان است. این منحنی با جفتی از آرایه‌های شناور x[] و y[] تعریف می‌شود که مجموعه‌ای از نقاط کنترل را تعریف می‌کنند. هر جفت (x, y) به‌ترتیب نشان‌دهنده زمان و میزان صدا است. طول آرایه‌ها باید برابر باشد و حداقل ۲ و حداکثر ۱۶ مقدار داشته باشد. (حداکثر طول منحنی در getMaximumCurvePoints() تعریف شده است.)

مختصات زمانی در بازه [0.0, 1.0] ارائه شده است. اولین نقطه زمانی باید ۰٫۰ باشد، آخرین نقطه باید ۱٫۰ باشد، و زمان‌ها باید به‌صورت یکنواخت افزایش یابند.

مختصات حجم صدا در مقیاس خطی در بازه [۰٫۰، ۱٫۰] مشخص شده است.

نوع درون‌یاب

منحنی میزان صدا همیشه از نقاط کنترل مشخص‌شده عبور می‌کند. مقادیر بین نقاط کنترل توسط یک اسپلاین مطابق با نوع درون‌یاب پیکربندی مشتق می‌شوند. چهار ثابت برای انواع میان‌یاب VolumeShaper دردسترس وجود دارد:

  • VolumeShaper.Configuration.INTERPOLATOR_TYPE_STEP
  • VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR
  • VolumeShaper.Configuration.INTERPOLATOR_TYPE_CUBIC
  • VolumeShaper.Configuration.INTERPOLATOR_TYPE_CUBIC_MONOTONIC

مدت

مختصات زمانی مشخص‌شده در بازه [0.0, 1.0] به مدت‌زمانی که برحسب میلی‌ثانیه مشخص می‌کنید مقیاس‌بندی می‌شود. این گزینه طول واقعی منحنی حجم را در زمانی که شکل‌دهنده درحال اجرا است و منحنی را روی خروجی صوتی اعمال می‌کند، تعیین می‌کند.

استفاده از VolumeShaper

درحال ایجاد پیکربندی

قبل‌از ساختن VolumeShaper، باید نمونه‌ای از VolumeShaper.Configuration ایجاد کنید. این کار را بااستفاده از VolumeShaper.Configuration.Builder() انجام دهید:

کاتلین

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})

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

درحال اجرای VolumeShaper

اگرچه سطح صدای اولین نقطه کنترل به‌محض ایجاد شکل‌دهنده بر مسیر صوتی اعمال می‌شود، شکل‌دهنده در امتداد منحنی پیش نمی‌رود تا زمانی که روش apply() را با VolumeShaper.Operation.PLAY فراخوانی کنید. پس‌از ایجاد شکل‌دهنده، اولین فراخوانی apply() باید عملیات PLAY را مشخص کند تا شکل‌دهنده شروع شود. این منحنی را از اولین تا آخرین نقطه کنترل اجرا می‌کند:

کاتلین

shaper.apply(VolumeShaper.Operation.PLAY)

جاوا

shaper.apply(VolumeShaper.Operation.PLAY);

درحالی‌که شکل‌دهنده درحال اجرا است، می‌توانید تماس‌های apply() متناوب صادر کنید و عملیات «معکوس» و «پخش» را مشخص کنید. این کار جهت خواندن نقاط کنترل را هربار تغییر می‌دهد.

شکل‌دهنده به‌طور مداوم میزان صدا را تنظیم می‌کند و از همه نقاط کنترل عبور می‌کند تا زمانی که منقضی شود. این اتفاق زمانی می‌افتد که شکل‌دهنده به آخرین نقطه کنترل (برای عملیات «پخش») یا اولین نقطه کنترل (برای عملیات «معکوس») در منحنی می‌رسد.

وقتی شکل‌دهنده منقضی می‌شود، میزان صدا در آخرین تنظیم باقی می‌ماند که ممکن است اولین یا آخرین نقطه کنترل باشد. هرزمان بخواهید می‌توانید با VolumeShaper.getVolume() تماس بگیرید تا میزان صدای فعلی را بشنوید.

پس‌از منقضی شدن شکل‌دهنده، می‌توانید فراخوانی apply() دیگری برای اجرای منحنی در جهت مخالف صادر کنید. برای مثال، اگر شکل‌دهنده درحین اجرای PLAY منقضی شده باشد، apply() بعدی باید REVERSE باشد. فراخوانی PLAY پس‌از منقضی شدن PLAY، یا REVERSE پس‌از منقضی شدن REVERSE تأثیری ندارد.

باید عملیات PLAY و REVERSE را به‌صورت متناوب انجام دهید. هیچ راهی برای پخش منحنی از اولین تا آخرین نقطه کنترل و سپس بازراه‌اندازی آن از اولین نقطه کنترل وجود ندارد. می‌توانید از روش replace() که در بخش بعدی توضیح داده شده است برای جایگزین کردن منحنی با نسخه‌ای از خودش استفاده کنید. این کار شکل‌دهنده را بازنشانی می‌کند، و برای شروع مجدد آن به عملیات PLAY نیاز است.

تغییر دادن منحنی

از روش replace() برای تغییر منحنی VolumeShaper استفاده کنید. این روش یک پیکربندی، یک عملیات، و یک پارامتر پیوستن را می‌گیرد. هرزمان که بخواهید، درحین اجرای شکل‌دهنده یا پس‌از منقضی شدن آن، می‌توانید روش replace() را فراخوانی کنید:

کاتلین

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

جاوا

VolumeShaper.Configuration newConfig =
  new VolumeShaper.Configuration.Builder()
    .setDuration(1000)
    .setCurve(new float[] {0.f, 0.5f}, new float[] {0.f, 1.f})
    .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR)
    .build();
boolean join = true;
shaper.replace(newConfig, VolumeShaper.Operation.PLAY, join);

وقتی replace() را درحین اجرای شکل‌دهنده فراخوانی می‌کنید، تغییر میزان صدا متوقف می‌شود و روی مقدار فعلی باقی می‌ماند. سپس شکل‌دهنده سعی می‌کند منحنی جدید را از اولین نقطه کنترل شروع کند. این یعنی آرگومان عملیات کنترل می‌کند که آیا شکل‌دهنده پس‌از تماس اجرا شود یا نه. PLAY را برای شروع فوری منحنی جدید مشخص کنید، REVERSE را برای توقف موقت شکل‌دهنده در میزان صدای اولین نقطه کنترل در منحنی جدید مشخص کنید. می‌توانید بعداً با apply(VolumeShaper.Operation.PLAY) شکل‌دهنده را شروع کنید.

وقتی replace() را با join = false فراخوانی می‌کنید، شکل‌دهنده منحنی خود را در سطحی که با اولین نقطه کنترل آن مشخص شده است شروع می‌کند. این امر می‌تواند باعث ناپیوستگی در میزان صدا شود. با تماس گرفتن با replace() ازطریق join = true می‌توانید از این مشکل جلوگیری کنید. این کار اولین نقطه کنترل منحنی جدید را روی سطح فعلی شکل‌دهنده تنظیم می‌کند و حجم همه نقاط کنترل بین اولین و آخرین نقطه را مقیاس‌بندی می‌کند تا شکل نسبی منحنی جدید حفظ شود (آخرین نقطه کنترل بدون تغییر باقی می‌ماند). عملیات مقیاس‌بندی نقاط کنترل را در منحنی جدید شکل‌دهنده برای همیشه تغییر می‌دهد.

Removing a VolumeShaper

وقتی AudioTrack یا MediaPlayer مربوط به VolumeShaper آزاد شود یا دیگر استفاده نشود، سیستم آن را می‌بندد و زباله جمع‌آوری می‌کند. می‌توانید روش close() را روی شکل‌دهنده فراخوانی کنید تا فوراً آن را ازبین ببرید. سیستم شکل‌دهنده را ظرف حدود ۲۰ میلی‌ثانیه از خط لوله صوتی برمی‌دارد. هنگام بستن VolumeShaper درحین پخش صدا مراقب باشید. اگر هنگام فراخوانی close()، حجم شکل‌دهنده کمتر از ۱٫۰ باشد، مقیاس حجم شکل‌دهنده به ۱٫۰ تغییر می‌کند. این کار می‌تواند باعث افزایش ناگهانی صدا شود.