অডিও কাইমস

এই কন্টেন্টে হাই অ্যাভেইলেবিলিটি রেন্ডারার (HAR)-এ চাইম প্লেব্যাক সম্পর্কে বর্ণনা করা হয়েছে। একটি Audio ক্রেট HAR অ্যাপের কাছে AudioManager উন্মুক্ত করে, যা চাইম প্লেব্যাক নিয়ন্ত্রণ করে।

লেটেন্সি কম রাখতে, প্লেব্যাক থ্রেডগুলো অ্যাপের পুরো জীবনকাল জুড়ে চলতে থাকে এবং কোনো অডিও না চললে নিষ্ক্রিয় হয়ে পড়ে ও কাজ থেকে বিরত থাকে।

পরিভাষা

সম্পদ
AudioAsset বলতে প্লে করা যায় এমন অডিওকে বোঝায়। অ্যাসেটগুলো সাধারণত পরিচিত এবং অ্যাপ রানটাইমে বিদ্যমান থাকে।
ডিভাইস
AudioDevice বলতে অডিও প্লেব্যাকের জন্য একটি পৃথক বাসকে বোঝায়। ডিভাইস হলো সিস্টেম দ্বারা অ্যাক্সেস করা হার্ডওয়্যার সম্পর্কিত সবচেয়ে সূক্ষ্ম একক। স্ট্যান্ডার্ড SDVM বাস্তবায়নে, AudioDevice বলতে একটি একক অ্যাডভান্সড লিনাক্স সাউন্ড আর্কিটেকচার (ALSA) PCM-কে বোঝায়।
স্রোত
ডিভাইসে কোনো অ্যাসেটের প্লেব্যাকের একটি দৃষ্টান্ত। স্ট্রিমগুলো শিডিউল করার মুহূর্ত থেকে শুরু করে সম্পূর্ণ, বাতিল বা ত্রুটির কারণে শেষ না হওয়া পর্যন্ত চলতে থাকে।

উপাদান

চিত্র ১-এ চিমের উপাদান চিত্র দেখানো হয়েছে:

উপাদান ডায়াগ্রাম

চিত্র ১। উপাদান চিত্র।

অডিও ডিভাইস এবং পিসিএম

অডিও হার্ডওয়্যার কনফিগারেশন স্ট্যান্ডার্ড HAR প্ল্যাটফর্ম অ্যাবস্ট্রাকশন লেয়ার ডিজাইন অনুসরণ করে, এবং har-platform-api এটি অন্তর্ভুক্ত রয়েছে।

HAR Audio ক্রেটটি AudioDevice জন্য একটি নতুন কাঠামো সংজ্ঞায়িত করে, যা অভ্যন্তরীণ HAR Audio ক্রেট এবং প্লেব্যাককে প্রভাবিত করে এমন সমস্ত ডেটা স্ট্রাকচারের জন্য ফিল্ড নির্ধারণ করে। AudioDevice সম্ভাব্য প্ল্যাটফর্ম-নির্দিষ্ট অতিরিক্ত প্যারামিটারগুলোকে র‍্যাপ করার জন্য জেনেরিকও ব্যবহার করে। tinyalsa এর ক্ষেত্রে, PlatformAudioDevice একটি ALSA PCM-এর ডেসক্রিপ্টর এবং প্রোপার্টিগুলো থাকে।

/// NOTE: The following code is a sample definition to help understanding, it is not a
/// representation of the final code/implementation.

AudioDevice<PlatformAudioDevice> {
  /// Internal HAR Identifier for the device.
  AudioDeviceID,

  /// The size (in bytes) for chunks of audio data to stream to the device.
  ChunkSize,

  /// Properties necessary to control volume (details in "Mixer control" section).
  VolumeControl,

  /// Properties necessary to control spatialization (details in "Mixer control"
  /// section).
  SpatialControl,

  /// Platform specific data for the AudioDevice.
  /// E.g. ALSA properties and reference to opened PCM.
  PlatformAudioDevice
}

/// Elaboration of the previously mentioned VolumeControl
VolumeControl {
  /// Identifier for the control used to change volume.
  ControlID,

  /// Mapping between Decibel and control values. (see Mixer control section)
  VolumeOutputIndex
}

অডিও সম্পদ

এই অংশে অডিও অ্যাসেটগুলো কীভাবে কনফিগার ও ইমপ্লিমেন্ট করা হয় তা বর্ণনা করা হয়েছে।

কনফিগারেশন

প্রাথমিক HAR অডিও ইমপ্লিমেন্টেশনটি স্ট্যাটিক্যালি কনফিগার করা অডিও অ্যাসেট সমর্থন করে। একটি JSON কনফিগ নির্ধারণ করে দেয় কোন অ্যাসেটগুলো উপলব্ধ এবং কোন অ্যাসেটগুলো WAV ফাইল হিসেবে সংজ্ঞায়িত।

এই বাস্তবায়নটি একটি আরও সাধারণ অ্যাসেট বাস্তবায়নের মাধ্যমে সিন্থেসাইজড এবং স্ট্রিমড অডিও অ্যাসেটগুলোকেও সমর্থন করে, যা অডিও ডেটা তৈরি করার জন্য একটি ফাংশন গ্রহণ করে।

বাস্তবায়ন

AudioAsset এবং AudioStream এই দুটি পৃথক কাঠামো ব্যবহার করে অ্যাসেট তৈরি করুন।

AudioAsset একটি অ্যাসেটের স্থির বৈশিষ্ট্যসমূহ এবং অ্যাসেট-সম্পর্কিত সম্ভাব্য অভ্যন্তরীণ ডেটার জন্য একটি ধারক নির্ধারণ করে। AudioAsset AudioStream তৈরি করা যায়, যা অ্যাসেটটির একটি একক স্ট্রিমযোগ্য ইনস্ট্যান্স। AudioStream একক স্ট্রিম প্লেব্যাকের সাথে সম্পর্কিত একটি অভ্যন্তরীণ অবস্থা থাকে।

/// NOTE: The following code is a sample definition to help understanding, it is not a
/// representation of the final code/implementation.

/// Static properties and definition of an Asset.
AudioAsset {
  /// Perform optional initialization steps, e.g. load bytes from file into memory.
  /// Can also define lazy loading, to load data at first playback instead.
  fn initialize(LazyLoad);

  /// Create a new AudioStream from the asset.
  fn create_stream() -> AudioStream;

  /// More functions for metadata etc. of the asset.
  ...
}

/// Single streamable instance of an AudioAsset
AudioStream {
  /// Gets the next bytes to play from the Asset together with if the current chunk of
  /// bytes contains any control signals (e.g. fade-out).
  fn get_playback(num_bytes: usize) -> ([u8], ControlSignals);

  /// Gets playback Mode details used to handle special states of playback
  /// e.g. when a chime gets is interrupted and put in "fade-out" mode.
  fn playback_mode() -> PlaybackMode;

  /// [0.0, 1.0] indication of how much of the stream was played.
  fn progress() -> f32;

  /// Reset the stream, e.g. if it should play again.
  fn reset();

  /// Time of which the stream was created.
  fn created_at() -> Instant;

  /// Additional metadata etc. for the stream.
  ...
}

ঘণ্টার শব্দ বাজানো

এই বিভাগে একটি চাইম প্লেব্যাকের জন্য এপিআই এবং পদ্ধতি বর্ণনা করা হয়েছে। একটি একক চাইম প্লেব্যাককে স্ট্রিম বলা হয়।

একটি স্ট্রিমের জীবনচক্র

চিত্র ২-এ একটি স্ট্রিমের জীবনচক্র দেখানো হয়েছে:

স্ট্রিম প্লেব্যাক এবং ইভেন্টগুলি

চিত্র ২। স্ট্রিম প্লেব্যাক এবং ইভেন্টসমূহ।

চিত্র ২-এ এই ধাপগুলো বর্ণনা করা হয়েছে:

  1. প্লে: প্লে করার জন্য স্ট্রিম শিডিউল করুন।

  2. অগ্রাধিকার দিন: প্লেব্যাক অগ্রাধিকার নির্ধারণ করে যে:

    • এখন ঘণ্টা বাজান (প্রথম বাইটগুলো বাজলে ইভেন্টটি শুরু হবে)
    • পরে ঘণ্টা বাজান (ইভেন্ট থামানো বা পুনরায় চালু করা হলে)
    • ঘণ্টাধ্বনিকে (বাতিলকৃত ইভেন্ট) অগ্রাধিকার থেকে বাদ দিন
  3. মিক্সার কন্ট্রোল: প্রয়োজনে, কনফিগার করা আচরণ অনুযায়ী মিক্সার কন্ট্রোলগুলো আপডেট করুন।

  4. বাইট লিখুন: AudioDevice এ একগুচ্ছ বাইট লিখুন।

  5. আরও ডেটা: যদি স্ট্রিমে আরও ডেটা থাকে, তাহলে ধাপ ২-এ ফিরে যান।

  6. পুনরাবৃত্তি: যদি স্ট্রিমটির পুনরাবৃত্তি করার প্রয়োজন হয়, তাহলে রিসেট করুন এবং ধাপ ২-এ ফিরে যান (পুনরায় শুরু হওয়া ইভেন্ট)।

  7. সম্পন্ন: স্ট্রিমটি সফলভাবে সম্পন্ন হয়েছে ( FinishedSuccessfully ইভেন্ট)।

যেকোনো সময় কল পজ, রিজুম বা স্টপ করার মাধ্যমে ঘণ্টার ধ্বনিটি থামানো যেতে পারে।

চিম অগ্রাধিকার

এই লজিকটি চিমের অগ্রাধিকার নির্ধারণ করে:

  1. প্লেব্যাক মোড ওভাররাইড করে। উদাহরণস্বরূপ, ফেড আউট মোডে একটি চাইম ফেড আউট সম্পূর্ণ না হওয়া পর্যন্ত সর্বদা সর্বোচ্চ অগ্রাধিকার পায়।

  2. নির্দিষ্ট অগ্রাধিকার।

  3. সমান অগ্রাধিকারের ঘটনাটি যদি সাম্প্রতিক হয়, তবে ঘণ্টার শব্দ প্রথমে বাজবে।

যখন ঘণ্টাধ্বনিগুলোর অগ্রাধিকার সমান হয়, তখন AudioManager একটি enum মান দিয়ে ইনস্ট্যানশিয়েট করা হয়।

এপিআই

ইভেন্টগুলি

চিম শুরু হওয়ার সময় যদি একটি ইভেন্ট চ্যানেল প্রদান করা হয়, তাহলে HAR Audio প্লেব্যাক চলাকালীন বেশ কিছু ইভেন্ট নির্গত করে। সমর্থিত ইভেন্টগুলো এই উদাহরণে দেখানো হলো:

/// NOTE: The following code is a sample definition to help understanding, it is not a
/// representation of the final code/implementation.

StreamBehaviors<PlatformStreamBehaviors> {
  /// What should happen if the stream is interrupted for a higher priority stream.
  /// e.g. pause-and-resume or cancel, will also define preference for fade-out.

  OverrunBehavior,
  /// Urgency, if interrupted streams are allowed to "fade-out", or if the stream should
  /// urgently disrupt any other playback.
  Optional<Urgency>,

  /// Priority for the stream (or minimum if not specified).
  Optional<StreamPriority>
  /// Descriptor if a stream should be played on repeat.
  Optional<RepeatBehavior>
  /// Volume, if the stream should play at a specific volume.
  Optional<Volume>
  /// Spatialization, if the stream should play with specific spatialization.
  Optional<Spatialization>

  /// Optional generic for future expandability of the API, or pass-through of platform
  /// specific Stream Behaviors
  Optional<PlatformStreamBehaviors>
}

/// Plays a chime on specified device with given behaviors. StreamEvents are delivered
/// using the provided event transmitter. This method won't wait for any events.
fn play(AudioDeviceID, AssetID, StreamBehaviors, Option<EventTransmitter>) -> StreamController

/// Object used to control a Stream.
StreamController {
  /// Gets the current state/metadata of a stream (e.g. ID, progress, playback_state).
  fn metadata() -> StreamMetadata

  /// Stops the stream.
  fn stop()

  /// Pauses a given stream, if the specified duration expires the stream is cancelled.
  /// Timeout is required to make sure there are no paused streams left indefinitely
  /// pending resumption.
  fn pause(TimeoutDuration)

  /// Resumes a paused stream.
  fn resume()

  /// Updates the spatialization of a playing stream.
  fn set_spatialization(Spatialization)

  /// Updates the volume of a playing stream.
  fn set_volume(Volume)
}

মিক্সার নিয়ন্ত্রণ

এই অংশে আয়তন এবং স্থানিকীকরণ কীভাবে নিয়ন্ত্রণ করা হয় তা বর্ণনা করা হয়েছে।

ভলিউম

HAR ধারাবাহিকভাবে মিলিবেলে ভলিউম নির্ধারণ করে। har-platform-api ক্রেটটি মিলিবেল থেকে কন্ট্রোল সিগন্যালে রূপান্তরের কাজটি করে।

মিলিবল এবং হার্ডওয়্যার পাওয়ার আউটপুটের মধ্যে সম্পর্কটি লগারিদমিক, এবং এটি বিভিন্ন হার্ডওয়্যার ও স্পিকার সেটআপের উপর নির্ভর করে ব্যাপকভাবে পরিবর্তিত হয়। ফলস্বরূপ, AudioDevice ( অডিও ডিভাইস এবং পিসিএম ) কনফিগারেশনের অংশ হিসাবে মানগুলির মধ্যে কনফিগারেশন প্রদান করুন, এবং প্ল্যাটফর্ম লেয়ার কল করার আগে এই রূপান্তর অবশ্যই সম্পন্ন করতে হবে।

ফলস্বরূপ, PAL API-তে বাস্তবায়ন দুটি ফাংশন সংজ্ঞায়িত করে।

fn set_volume_millibel(AudioDeviceID, Millibel) {
  /// Default implementation with conversion using DeviceConfig.
}

fn set_volume_control(AudioDeviceID, ControlValue);

set_volume_millibel এর ডিফল্ট ইমপ্লিমেন্টেশনটি AudioDevice জন্য প্রদত্ত কনফিগারেশন ব্যবহার করে, যার মধ্যে রেফারেন্স মিলিবল - কন্ট্রোল-এর জন্য এক সেট কী-ভ্যালু পেয়ার অন্তর্ভুক্ত থাকে, যা মিলিবলকে কন্ট্রোল ভ্যালুতে রূপান্তর করে এবং তারপর রূপান্তরিত মান দিয়ে set_volume_control ফাংশনটিকে কল করে।

এই ডিজাইনটি একটি ডিফল্ট মান প্রদান করে এবং পরবর্তী বাস্তবায়নগুলোকে সেই ডিফল্ট ম্যাপিংকে ওভাররাইড করার সুযোগ দেয়।

HAR অডিও প্রবাহ

চিত্র ৩। HAR অডিও প্রবাহ।

স্থানিকীকরণ

অডিও এপিআই (Audio API) অডিও ডেটা কোন স্থানিক এলাকায় প্লে হবে তা নিয়ন্ত্রণ করার কার্যকারিতা প্রদান করে। এই প্যারামিটারগুলো PAL লেয়ারে পাঠানো হয় এবং হার্ডওয়্যার কন্ট্রোল ব্যবহার করে ডাউনস্ট্রিমে প্রয়োগ করা হয়। PAL এপিআই-এর অংশ হিসেবে অপশনগুলো নিম্নরূপে সংজ্ঞায়িত করা হয়:

/// NOTE: The following code is a sample definition to help understanding, it is not a
/// representation of the final code/implementation.

enum Spatialization {
  Front,
  FrontLeft,
  FrontRight,
  Center, // No spatialization
  Rear,
  RearLeft,
  RearRight,
  Right,
  Left
}

মিক্সার নিয়ন্ত্রণ স্তর

আপনি একটি অ্যাসেট এবং একটি স্ট্রিমের জন্য ভলিউম ও স্পেশিয়ালাইজেশন নির্ধারণ করতে পারেন। যদি আপনি একটি স্ট্রিম প্রায়োরিটি নির্ধারণ করেন, তবে স্ট্রিমটি অ্যাসেট দ্বারা নির্ধারিত নিয়ন্ত্রণগুলোকে ওভাররাইড করে।

থ্রেড ব্যবস্থাপনা

অডিও ম্যানেজার প্রতিটি AudioDevice ইনস্ট্যান্সের জন্য একটি করে থ্রেড পরিচালনা করে। প্রতিটি থ্রেড স্বাধীনভাবে কাজ করে। AudioManager এবং প্লেব্যাক থ্রেডের মধ্যে মিথস্ক্রিয়া প্রায়োরিটি অনুসারে সাজানো একটি শেয়ার্ড স্ট্রিম কিউ ব্যবহার করে।

ডেটা কখন ডাইজেস্ট করা হবে তা নির্ধারণ করতে ALSA কলগুলো পোলিং সহ ASYNC রাইট ব্যবহার করে।

থ্রেড ম্যানেজমেন্ট সিকোয়েন্স

চিত্র ৪। থ্রেড ব্যবস্থাপনার ক্রম।

পোলিং চলাকালীন নিয়ন্ত্রণ সংকেত

সাউন্ড কার্ড বাইট গ্রহণ করার জন্য অপেক্ষা করার সময়, কন্ট্রোল সিগন্যাল জারি করা যেতে পারে। উদাহরণস্বরূপ, অডিওর ফেড বা স্পেশিয়ালাইজেশন পরিবর্তন করার জন্য। অডিও ডিভাইসের অবস্থা জানার জন্য পোলিং হয় AudioManager লেভেলে কনফিগার করা হয় অথবা ডিফল্ট হিসেবে ১ মিলিসেকেন্ডে সেট করা থাকে। প্রতিটি পোলিং চক্রের পরে, প্লেব্যাক থ্রেড যেকোনো সময়-ভিত্তিক কন্ট্রোল কমান্ড গ্রহণ করে এবং জারি করে।

বাফার ব্যবস্থাপনা

ইন্টারাপশন ল্যাটেন্সি কমানোর জন্য, ডিভাইসে লেখা বাফার সাইজ ছোট রাখা হয়। ডিফল্ট হিসেবে TinyALSA ব্যবহার করার সময়, বাফার সাইজ startup_threshold প্যারামিটারের সমান করে কনফিগার করা হয়। TinyALSA ডিফল্ট হিসেবে সম্পূর্ণ বরাদ্দকৃত ডিভাইস বাফারকে দুই দিয়ে ভাগ করে নির্ধারণ করে

স্ট্রিম বাধা

যখন স্ট্রিম বাধাগ্রস্ত হয়, তখন কার্ডে লেখা ডেটা নিষ্কাশিত না হওয়া পর্যন্ত স্ট্রিমগুলো থ্রেড অগ্রাধিকার বজায় রাখে। ফলে, বাধা এবং নতুন স্ট্রিমের মধ্যে একটি রূপান্তরকালীন সময় অতিবাহিত হয়।

উদাহরণস্বরূপ, HAR-এর কোনো অডিও স্যাম্পলে যদি নিম্নলিখিত বিষয়গুলো ব্যবহৃত হয়:

  • ৩,০৭২ এর আকার
  • ৪৮,০০০ এর হার
  • দুইয়ের নমুনা আকার

পেন্ডিং বাফারটি ৩,০৭২ এবং ৬,১৪৪ ফ্রেম হিসাবে গণনা করা হয়, যার ফলে ৬৪ থেকে ১২৮ মিলিসেকেন্ডের একটি ইন্টারাপশন ডিলে হয়। প্রোডাকশন ইমপ্লিমেন্টেশনের জন্য একটি ছোট বাফারের প্রয়োজন হবে।

ত্রুটি ব্যবস্থাপনা এবং ঝুঁকি

এই অংশে ত্রুটি কীভাবে পরিচালনা করা হয় এবং সম্ভাব্য ঝুঁকিগুলো বর্ণনা করা হয়েছে।

বাসি স্ট্রিম এবং কিউ স্টারভেশন

যেহেতু AudioStream থামানো যায়, এবং প্লেব্যাক শুধুমাত্র সর্বোচ্চ অগ্রাধিকারের AudioStream ইনস্ট্যান্স থেকেই হতে পারে, তাই ক্রমবর্ধমান কিউয়ের কারণে নিম্ন-অগ্রাধিকারের স্ট্রিমগুলো বঞ্চিত হওয়ার ঝুঁকি তৈরি হয়।

এই ঘটনা এড়ানোর জন্য, প্রতিটি কিউ-এর একটি কনফিগারযোগ্য আকার নির্ধারণ করা থাকে। যখন এই মান অতিক্রম করা হয়, তখন সর্বনিম্ন-অগ্রাধিকারের স্ট্রিমটি বাতিল করা হয়।

পর্যবেক্ষণ ও সতর্ক করুন

উৎপাদনের সময়, সেফটি মনিটর অডিও বৈশিষ্ট্যগুলো ট্র্যাক করে যাতে প্লেব্যাক প্রত্যাশা অনুযায়ী হচ্ছে কিনা তা নিশ্চিত করা যায়।

AudioManager ল্যাটেন্সি-সম্পর্কিত অভ্যন্তরীণ পরিসংখ্যান এবং লগিং পারফরম্যান্স নির্ধারণকারী একটি ফ্ল্যাগ পর্যবেক্ষণ করে। এই থ্রেশহোল্ডগুলো সেট করার পর, নিম্নলিখিত ক্ষেত্রে সমস্ত ডিবাগ বিল্ডের জন্য সতর্কতামূলক লগ তৈরি হয়:

  • সময়সূচী নির্ধারণ এবং প্লেব্যাক শুরু হওয়ার মধ্যবর্তী সময় x মিলিসেকেন্ড অতিক্রম করেছে।
  • (একটি নিরবচ্ছিন্ন স্ট্রিমের ক্ষেত্রে) অ্যাসেটের দৈর্ঘ্য এবং প্লেব্যাকের সময়ের মধ্যে পার্থক্য y শতাংশের বেশি।

ডিভাইস ব্লক করা হয়েছে

একটি অডিও ডিভাইস সাড়া দেওয়া বন্ধ করে দেওয়ার একটি সামান্য ঝুঁকি সবসময়ই থাকে, উদাহরণস্বরূপ, যদি সিস্টেমের অন্য কোনো প্রসেস এটিকে বরাদ্দ করে এবং এতে লেখে। যেহেতু প্লেব্যাক আলাদা থ্রেডে অ্যাসিঙ্ক্রোনাসভাবে চলে, এবং চিমস পরে বাজানোর জন্য সারিবদ্ধ করা যায়, তাই এই বিষয়টি কলিং অ্যাপের কাছে সম্পূর্ণ অদৃশ্য থাকে।

এটি শনাক্ত করার জন্য, যখনই কোনো নতুন চিম বাজানোর জন্য নির্ধারিত হয়, তখন একটি থ্রেড হেলথ চেক করা হয়। যদি কোনো প্লেব্যাক থ্রেডের কিউ পূর্ণ থাকে এবং গত এক সেকেন্ডে কোনো নতুন বাইট গ্রহণ না করে থাকে, তবে এটি একটি এরর রিটার্ন করে।

ভবিষ্যতের প্রয়োজনে ডিভাইসগুলো রিস্টার্ট বা চালু করার চেষ্টা করার দরকার হতে পারে, কিন্তু প্রাথমিক বাস্তবায়নের ক্ষেত্রে ত্রুটিগুলো অদৃশ্য থাকা উচিত নয়।

কোড কাঠামো

উচ্চ স্তরে, চিমস প্লেব্যাক সম্পর্কিত কোড নিম্নলিখিত ক্রেটগুলিতে বিদ্যমান:

CRATE: display-safety/crates/(harry-app|harry)

বিদ্যমান HAR অ্যাপটি, যা ঘণ্টা বাজানোর জন্য আহ্বান জানায়।

NEW CRATE: display-safety/crates/audio

নতুন: অডিও নিয়ন্ত্রণ এবং প্লেব্যাক পরিচালনার জন্য ক্রেট (অধিকাংশ কার্যকারিতা এখানেই রয়েছে)।

CRATE: display-safety/crates/har-platform-api/audio

অডিওর জন্য প্রয়োজনীয় সকল সিস্টেম কল সহ PAL।

CRATE: display-safety/crates/har-platform-(android|linux)/audio

TinyALSA ব্যবহার করে প্লেব্যাকের জন্য tinyalsa-rs কে কল করা হয়। প্রাথমিক সলিউশনে QNX সাপোর্ট অন্তর্ভুক্ত করা হয়নি, এবং আরও প্ল্যাটফর্ম সমর্থিত হওয়ার সাথে সাথে এটিও যুক্ত হবে।

TINYALSA PAL: display-safety/crates/tinyalsa-audio

প্লেব্যাকের জন্য TinyALSA-এর নিজস্ব কোড। এটি অ্যান্ড্রয়েড এবং লিনাক্স প্ল্যাটফর্মের বাস্তবায়নে ব্যবহৃত হয়।

CRATE: display-safety/crates/tinyalsa-rs

TinyALSA C বাস্তবায়নের জন্য রাস্ট বাইন্ডিং

রাস্ট বাস্তবায়নের বিবরণ

বাস্তবায়নের কিছু নির্দিষ্ট বিবরণ:

  • সমস্ত API ফাংশন Result<X, AudioError> রিটার্ন করে, যেখানে X হলো () অথবা একটি রিটার্ন ভ্যালু।
  • কোনো API ফাংশনকেই unsafe হিসেবে চিহ্নিত করা হয়নি।
  • মিউটেক্স এবং সিঙ্ক্রোনাইজেশন প্রক্রিয়াগুলো অভ্যন্তরীণ এবং AudioManager API-তে প্রকাশ করা হয় না।

মালিকানা মডেল এবং অডিওম্যানেজার

  • অডিও সিস্টেমের সাথে অ্যাপের সমস্ত ইন্টারঅ্যাকশন AudioManager অথবা AudioManager থেকে রিটার্ন করা অবজেক্টের মাধ্যমে সম্পন্ন হয়।

  • AudioManager থ্রেড সেফ।

  • Looper মালিকানা পাওয়ার জন্য AudioManager HARry অ্যাপে একবার ইনস্ট্যানশিয়েট করা হয় এবং Moved

  • AudioManager তার চালু থাকা প্লেব্যাক থ্রেডগুলো পরিচালনা করতে একটি tokio_util::CancellationToken টোকেন ব্যবহার করে, যা নিশ্চিত করে যে AudioManager Dropped হলে থ্রেডগুলো বন্ধ হয়ে যায় এবং রিসোর্সগুলো মুক্ত হয়।

  • AudioManager একাধিক ইনস্ট্যান্স তৈরি হওয়াকে স্পষ্টভাবে বাধা দেয় না। যদি একাধিক ইনস্ট্যান্স বিদ্যমান থাকে, তবে এটি সতর্কীকরণ স্তরের ( warn level) সাথে লগ করে।

যৌথ মালিকানা

বেশ কিছু অবজেক্টের যৌথ মালিকানা রয়েছে যা এক্সক্লুসিভ অ্যাক্সেস দ্বারা আবৃত ও সিঙ্ক্রোনাইজ করা থাকে। এই পদ্ধতিগুলো AudioManager API-তে প্রকাশ করা হয়নি, বরং এগুলো অডিও এবং PAL ইমপ্লিমেন্টেশনের অভ্যন্তরীণ বিষয়।

  • AudioDevice - প্রতিটি হার্ডওয়্যার রেফারেন্স (উদাহরণস্বরূপ, TinyALSA PCM) যা খোলা হয় (যার একটি হ্যান্ডেল আছে), তার এক্সক্লুসিভ অ্যাক্সেস থাকে। SMP ডিজাইন দেখুন।

  • প্লেব্যাকের জন্য শিডিউল করার পর AudioStream ইনস্ট্যান্সগুলো একচেটিয়া অ্যাক্সেস পায়, কারণ সেগুলোকে অ্যাপ দ্বারা নিয়ন্ত্রণ করা যায় এবং একই সাথে প্লেব্যাক থ্রেডও অ্যাক্সেস করতে পারে।

    প্লেব্যাক থ্রেডটি প্লেব্যাকের সময় কোনো লক ধরে রাখে না, বরং পরবর্তী যে বাফারটি প্লে করা হবে তার একটি অপরিবর্তনীয় স্ন্যাপশট তৈরি করে এবং পরবর্তী বাফারটি ডাইজেস্ট না হওয়া পর্যন্ত কোনো পরিবর্তন বিবেচনা করে না।

  • প্রতিটি প্লেব্যাক থ্রেডের একটি প্লেব্যাক কিউ থাকে, যা AudioManager এবং প্লেব্যাক থ্রেডের মধ্যে একটি শেয়ার্ড রেফারেন্স। ফলে, মিউটেশনের জন্য থ্রেডটির এক্সক্লুসিভ অ্যাক্সেস প্রয়োজন হয়।

  • যেসব থ্রেডে কোনো স্ট্রিম নেই, সেগুলো নতুন ডেটা শনাক্ত হলে ওয়েকআপ ইভেন্ট গ্রহণ করার জন্য Condvar ভেরিয়েবলের মাধ্যমে নিষ্ক্রিয় হয়ে যায়। এই ব্যবস্থায় যৌথ মালিকানা রয়েছে।

নির্ভরশীলতা

অ্যান্ড্রয়েড সোর্স ট্রিতে বিল্ড করার জন্য অনুমোদিত নয় এমন ক্রেটগুলোর উপর নির্ভরতা কমাতে ক্রেট এবং অডিও ক্রেট ডিজাইন করা হয়েছে। অন্তর্ভুক্ত ক্রেটগুলোর এই তালিকাটি দেখুন।

অ্যান্ড্রয়েড এবং লিনাক্সের জন্য ডাউনস্ট্রিম প্ল্যাটফর্ম বাস্তবায়ন TinyALSA এবং বিদ্যমান ডিসপ্লে সুরক্ষা tinyalsa-rs ক্রেটের উপর নির্ভর করে।

গুণগত বৈশিষ্ট্য

নির্ভরযোগ্যতা

যদিও অডিও প্লেব্যাক নিরাপত্তার জন্য অত্যন্ত গুরুত্বপূর্ণ, এই নকশায় নিরাপত্তা পর্যবেক্ষণের ব্যবস্থা অন্তর্ভুক্ত করা হয়নি। হার্ডওয়্যারে এবং উৎপাদনে অডিও প্লেব্যাকের নির্ভরযোগ্যতা যাচাই করার জন্য, এটি একটি পৃথক উদ্যোগ হিসেবে বাস্তবায়ন করুন।

পরিমাপযোগ্যতা

প্রতিটি ডিভাইসের জন্য একটি থ্রেড পদ্ধতিটি বিভিন্ন হার্ডওয়্যার সেটআপের সাথে খাপ খাইয়ে নেওয়ার জন্য তৈরি করা হয়েছে। যেহেতু প্রতিটি থ্রেড মূলত নিষ্ক্রিয় থাকে, ডেটার জন্য অপেক্ষা করে, অথবা ডিভাইসটির লেখা ডেটা গ্রহণ করার জন্য অপেক্ষা করে, তাই এটি প্রসেসরের উপর চাপ সৃষ্টি করবে না বা সিস্টেমের পারফরম্যান্সের উপরও বেশি চাপ ফেলবে না।

শুধুমাত্র একটি ডিভাইসে ডেটা পাঠানোর নকশাগত সিদ্ধান্ত এবং পরবর্তী সকল আউটপুট নিয়ন্ত্রণের জন্য মিক্সার কন্ট্রোল কমান্ডের ব্যবহার নিশ্চিত করে যে, সঠিক আউটপুটটি সাউন্ড হার্ডওয়্যার দ্বারা পরিচালিত হবে এবং এটি ভবিষ্যতের সিস্টেমগুলোর জন্যও সম্প্রসারণযোগ্য হবে।

লেটেন্সি

অডিও সিস্টেমের জন্য ল্যাটেন্সি অত্যন্ত গুরুত্বপূর্ণ, তাই বাস্তবায়নের পরে সিস্টেমের ল্যাটেন্সির জন্য এক সেট সার্ভিস-লেভেল অবজেক্টিভস (SLOs) নির্ধারণ করা হয়। ল্যাটেন্সির অবস্থা ক্রমাগত পর্যবেক্ষণ করার জন্য, সমস্ত ডিবাগ বিল্ডে সিস্টেম লগে নির্ধারিত SLO পূরণ না হওয়া পর্যবেক্ষণ করা হয়।

প্রোডাকশন সংস্করণগুলোর ক্ষেত্রে, লগের উপর নির্ভর না করে মনিটরিং ডেটা অডিও ইমপ্লিমেন্টেশনের বাইরের কোনো সিস্টেমে পাঠানো হয়।

পরীক্ষা এবং পরীক্ষার কৌশল

ক্রেইটগুলো এবং অডিও ক্রেইটটি টেস্ট কভারেজ মাথায় রেখে ডিজাইন করা হয়েছে। সমস্ত সক্ষমতা পরীক্ষিত হয়েছে কিনা, তা নিশ্চিত করার জন্য আমরা একটি মক প্ল্যাটফর্ম ইমপ্লিমেন্টেশন যুক্ত করেছি।

হার্ডওয়্যার এবং বাইন্ডিংয়ের জটিলতার কারণে প্ল্যাটফর্ম ইমপ্লিমেন্টেশনগুলোর জন্য ব্যাপক টেস্ট কভারেজ সম্ভব হয় না। আমরা হার্ডওয়্যারে এবং কাটলফিশ এমুলেটরে সলিউশনটি ম্যানুয়ালি পরীক্ষা করার জন্য নমুনা ইমপ্লিমেন্টেশন সরবরাহ করি।

ডকুমেন্টেশন

Audio crates/audio তে থাকা README.md ফাইলে AudioManager কীভাবে ব্যবহার করতে হয় তা বর্ণনা করা আছে। crates/audio/examples এ নিম্নলিখিত বিষয়গুলির উদাহরণ রয়েছে:

  • একটি প্ল্যাটফর্ম বাস্তবায়ন করুন।
  • AudioManager এর একটি ইনস্ট্যান্স তৈরি করুন।
  • WavAsset চালান।
  • একটি কাস্টম ফাংশন অ্যাসেট বারবার চালান।
  • প্লেব্যাক ইভেন্টগুলো লগ করুন।