Flutter oyununuza ses ve müzik ekleyin

1. Başlamadan önce

Oyunlar görsel işitsel deneyimlerdir. Flutter, etkileyici görseller ve sağlam kullanıcı arayüzleri oluşturmak için mükemmel bir araçtır. Bu sayede, görsel açıdan çok daha iyi sonuçlar elde edebilirsiniz. Geriye kalan eksik bileşen sestir. Bu codelab'de, projenize düşük gecikmeli ses ve müzik eklemek için flutter_soloud eklentisini nasıl kullanacağınızı öğreneceksiniz. Doğrudan ilginç bölümlere atlayabilmek için temel bir iskeletle başlarsınız.

El çizimi bir kulaklık resmi.

Elbette burada öğrendiklerinizi yalnızca oyunlara değil, uygulamalarınıza da ses eklemek için kullanabilirsiniz. Ancak neredeyse tüm oyunlarda ses ve müzik gerekirken çoğu uygulamada bu gerekli değildir. Bu nedenle bu kod laboratuvarı oyunlara odaklanır.

Ön koşullar

  • Flutter hakkında temel düzeyde bilgi sahibi olmanız gerekir.
  • Flutter uygulamalarının nasıl çalıştırılacağını ve hata ayıklayacağını bilme

Öğrenecekleriniz

  • Tek seferlik sesleri çalma
  • Ara vermeden müzik döngüleri çalma ve özelleştirme.
  • Sesleri yavaşça artırma ve azaltma
  • Seslere çevresel efektler uygulama
  • İstisnalar nasıl ele alınır?
  • Bu özelliklerin tümünü tek bir ses kontrol cihazına yerleştirme.

İhtiyacınız olanlar

  • Flutter SDK'sı
  • Tercih ettiğiniz bir kod düzenleyici

2. Kur

  1. Aşağıdaki dosyaları indirin. Bağlantınız yavaşsa endişelenmeyin. Asıl dosyalara daha sonra ihtiyacınız olacağından, siz çalışırken dosyaların indirilmesine izin verebilirsiniz.
  1. İstediğiniz adı kullanarak bir Flutter projesi oluşturun.
  1. Projede bir lib/audio/audio_controller.dart dosyası oluşturun.
  2. Dosyaya aşağıdaki kodu girin:

lib/audio/audio_controller.dart

import 'dart:async';

import 'package:logging/logging.dart';

class AudioController {
  static final Logger _log = Logger('AudioController');

  Future<void> initialize() async {
    // TODO
  }

  void dispose() {
    // TODO
  }

  Future<void> playSound(String assetKey) async {
    _log.warning('Not implemented yet.');
  }

  Future<void> startMusic() async {
    _log.warning('Not implemented yet.');
  }

  void fadeOutMusic() {
    _log.warning('Not implemented yet.');
  }

  void applyFilter() {
    // TODO
  }

  void removeFilter() {
    // TODO
  }
}

Gördüğünüz gibi bu, gelecekteki işlevler için yalnızca bir iskelettir. Bunların hepsini bu kod laboratuvarının sırasında uygulayacağız.

  1. Ardından, lib/main.dart dosyasını açıp içeriğini aşağıdaki kodla değiştirin:

lib/main.dart

import 'dart:developer' as dev;

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';

import 'audio/audio_controller.dart';

void main() async {
  // The `flutter_soloud` package logs everything
  // (from severe warnings to fine debug messages)
  // using the standard `package:logging`.
  // You can listen to the logs as shown below.
  Logger.root.level = kDebugMode ? Level.FINE : Level.INFO;
  Logger.root.onRecord.listen((record) {
    dev.log(
      record.message,
      time: record.time,
      level: record.level.value,
      name: record.loggerName,
      zone: record.zone,
      error: record.error,
      stackTrace: record.stackTrace,
    );
  });

  WidgetsFlutterBinding.ensureInitialized();

  final audioController = AudioController();
  await audioController.initialize();

  runApp(MyApp(audioController: audioController));
}

class MyApp extends StatelessWidget {
  const MyApp({required this.audioController, super.key});

  final AudioController audioController;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter SoLoud Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.brown),
      ),
      home: MyHomePage(audioController: audioController),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.audioController});

  final AudioController audioController;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  static const _gap = SizedBox(height: 16);

  bool filterApplied = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Flutter SoLoud Demo')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            OutlinedButton(
              onPressed: () {
                widget.audioController.playSound('assets/sounds/pew1.mp3');
              },
              child: const Text('Play Sound'),
            ),
            _gap,
            OutlinedButton(
              onPressed: () {
                widget.audioController.startMusic();
              },
              child: const Text('Start Music'),
            ),
            _gap,
            OutlinedButton(
              onPressed: () {
                widget.audioController.fadeOutMusic();
              },
              child: const Text('Fade Out Music'),
            ),
            _gap,
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                const Text('Apply Filter'),
                Checkbox(
                  value: filterApplied,
                  onChanged: (value) {
                    setState(() {
                      filterApplied = value!;
                    });
                    if (filterApplied) {
                      widget.audioController.applyFilter();
                    } else {
                      widget.audioController.removeFilter();
                    }
                  },
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
  1. Ses dosyaları indirildikten sonra projenizin kökünde assets adlı bir dizin oluşturun.
  2. assets dizininde biri music, diğeri sounds adlı iki alt dizin oluşturun.
  3. İndirilen dosyaları projenize taşıyın. Şarkı dosyası assets/music/looped-song.ogg dosyasında, cemaatten gelen sesler ise aşağıdaki dosyalarda yer almalıdır:
  • assets/sounds/pew1.mp3
  • assets/sounds/pew2.mp3
  • assets/sounds/pew3.mp3

Projenizin yapısı şu şekilde görünecektir:

&quot;android&quot;, &quot;ios&quot; gibi klasörleri ve &quot;README.md&quot;, &quot;analysis_options.yaml&quot; gibi dosyaları içeren projenin ağaç görünümü.   Bunlar arasında &quot;music&quot; ve &quot;sounds&quot; alt dizinlerini içeren &quot;assets&quot; dizini, &quot;main.dart&quot; ve &quot;audio_controller.dart&quot; içeren bir &quot;audio&quot; alt dizini ve &quot;pubspec.yaml&quot; dosyası görülebilir.  Oklar, yeni dizinleri ve şu ana kadar dokunduğunuz dosyaları gösterir.

Dosyalar artık orada olduğuna göre Flutter'a bu dosyaları bildirmeniz gerekir.

  1. pubspec.yaml dosyasını açın ve ardından dosyanın en altındaki flutter: bölümünü aşağıdakiyle değiştirin:

pubspec.yaml

...

flutter:
  uses-material-design: true

  assets:
    - assets/music/
    - assets/sounds/
  1. flutter_soloud ve logging paketlerine bağımlılık ekleyin.
flutter pub add flutter_soloud logging

pubspec.yaml dosyanızda artık flutter_soloud ve logging paketlerine yönelik ek bağımlılıklar olmalıdır.

pubspec.yaml

...

dependencies:
  flutter:
    sdk: flutter

  flutter_soloud: ^3.1.10
  logging: ^1.3.0

...
  1. Projeyi çalıştırın. İşlevleri aşağıdaki bölümlere eklediğiniz için henüz hiçbir şey çalışmıyor.

10f0f751c9c47038.png

3. Başlatma ve kapatma

Ses çalmak için flutter_soloud eklentisini kullanırsınız. Bu eklenti, Nintendo SNES Classic'ın da aralarında bulunduğu oyunlar için C++ ses motoru olan SoLoud projesini temel alır.

7ce23849b6d0d09a.png

SoLoud ses motorunu başlatmak için aşağıdaki adımları uygulayın:

  1. audio_controller.dart dosyasında flutter_soloud paketini içe aktarın ve sınıfa özel bir _soloud alanı ekleyin.

lib/audio/audio_controller.dart

import 'dart:async';

import 'package:flutter_soloud/flutter_soloud.dart';  //  Add this...
import 'package:logging/logging.dart';

class AudioController {
  static final Logger _log = Logger('AudioController');

  SoLoud? _soloud;                                    //  ... and this.

  Future<void> initialize() async {
    // TODO
  }

  ...

Ses denetleyici, temel SoLoud motorunu bu alan üzerinden yönetir ve tüm çağrıları ona yönlendirir.

  1. initialize() yöntemine aşağıdaki kodu girin:

lib/audio/audio_controller.dart

...

  Future<void> initialize() async {
    _soloud = SoLoud.instance;
    await _soloud!.init();
  }

...

Bu işlem, _soloud alanını doldurur ve başlatmayı bekler. Aşağıdakileri göz önünde bulundurun:

  • SoLoud, tekil bir instance alanı sağlar. Birden fazla SoLoud örneği oluşturmak mümkün değildir. C++ motoru buna izin vermez. Bu nedenle Dart eklentisi de buna izin vermez.
  • Eklentinin başlatılması eşzamansızdır ve init() yöntemi döndürülene kadar tamamlanmaz.
  • Bu örnekte kısalık olması için try/catch bloğundaki hataları yakalamıyorsunuz. Üretim kodunda bunu yapmak ve hataları kullanıcıya bildirmek istersiniz.
  1. dispose() yöntemine aşağıdaki kodu girin:

lib/audio/audio_controller.dart

...

  void dispose() {
    _soloud?.deinit();
  }

...

Uygulamadan çıktığınızda SoLoud'u kapatmak iyi bir uygulamadır ancak bunu yapmasanız bile her şey sorunsuz şekilde çalışır.

  1. AudioController.initialize() yönteminin main() işlevinden zaten çağrıldığına dikkat edin. Yani projeyi sıcak yeniden başlatmak SoLoud'u arka planda başlatır ancak ses çalmadan önce hiçbir işe yaramaz.

4. Tek seferlik sesler çalma

Bir öğeyi yükleyip oynatma

SoLoud'un başlangıçta başlatıldığını bildiğinize göre ses çalmasını isteyebilirsiniz.

SoLoud, bir sesi tanımlamak için kullanılan veriler ve meta veriler olan ses kaynağı ile aslında çalınan sesler olan "ses örnekleri" arasında ayrım yapar. Ses kaynağına örnek olarak, belleğe yüklenen, çalınmaya hazır ve AudioSource sınıfının bir örneğiyle temsil edilen bir MP3 dosyası verilebilir. Bu ses kaynağını her oynattığınızda SoLoud, SoundHandle türüyle temsil edilen bir "ses örneği" oluşturur.

Yükleyerek bir AudioSource örneği elde edersiniz. Örneğin, öğelerinizde bir mp3 dosyanız varsa AudioSource almak için bu dosyayı yükleyebilirsiniz. Ardından SoLoud'a bu AudioSource parçayı çalmasını söylersiniz. Aynı anda bile birçok kez oynayabilirsiniz.

Kullanmadığınız ses kaynaklarını SoLoud.disposeSource() yöntemiyle imha edin.

Bir öğeyi yüklemek ve oynatmak için aşağıdaki adımları uygulayın:

  1. AudioController sınıfının playSound() yöntemine aşağıdaki kodu girin:

lib/audio/audio_controller.dart

  ...

  Future<void> playSound(String assetKey) async {
    final source = await _soloud!.loadAsset(assetKey);
    await _soloud!.play(source);
  }

  ...
  1. Dosyayı kaydedin, anında yeniden yükleyin ve ardından Ses çal'ı seçin. Aptalca bir "pew" sesi duyarsınız. Aşağıdakileri göz önünde bulundurun:
  • Sağladığınız assetKey bağımsız değişkeni assets/sounds/pew1.mp3 gibidir. Image.asset() widget'ı gibi öğe yükleyen diğer Flutter API'lerine sağlayacağınız dizeyle aynıdır.
  • SoLoud örneği, Flutter projesinin öğelerinden bir ses dosyasını eşzamansız olarak yükleyen ve AudioSource sınıfının bir örneğini döndüren bir loadAsset() yöntemi sağlar. Dosya sisteminin yanı sıra ağ üzerinden URL'den dosya yüklemek için eşdeğer yöntemler (loadFile() ve loadUrl() yöntemleri) vardır.
  • Ardından yeni edinilen AudioSource örneği SoLoud'un play() yöntemine iletilir. Bu yöntem, yeni çalınan sesi temsil eden SoundHandle türündeki bir örnek döndürür. Bu tutamak, sesin duraklatılması, durdurulması veya ses düzeyinin değiştirilmesi gibi işlemler yapmak için diğer SoLoud yöntemlerine iletilebilir.
  • play(), eşzamansız bir yöntem olsa da oynatma işlemi temelde anında başlar. flutter_soloud paketi, C kodunu doğrudan ve senkronize olarak çağırmak için Dart'ın yabancı işlev arayüzünü (FFI) kullanır. Çoğu Flutter eklentisinin özelliği olan Dart kodu ile platform kodu arasında gidip gelen mesajlaşmalar hiçbir yerde bulunamaz. Bazı yöntemlerin asenkron olmasının tek nedeni, eklentinin kodunun bir kısmının kendi izolasyonunda çalışması ve Dart izolasyonları arasındaki iletişimin asenkron olmasıdır.
  • _soloud! ile _soloud alanının boş olmadığını iddia ediyorsunuz. Bu, yine kısalık içindir. Üretim kodu, geliştiricinin ses denetleyicisi tam olarak başlatılmadan önce ses çalmayı denediği durumları sorunsuz bir şekilde ele almalıdır.

İstisnalarla başa çıkma

Olası istisnaları bir kez daha göz ardı ettiğinizi fark etmiş olabilirsiniz. Bu yöntemi öğrenme amacıyla düzeltme zamanı geldi. (Codelab'de kısalık olması için bu bölümden sonra istisnaları yoksaymaya geri dönülür.)

  • Bu durumdaki istisnalarla başa çıkmak için playSound() yönteminin iki satırını bir try/catch bloğuna sarın ve yalnızca SoLoudException örneklerini yakalayın.

lib/audio/audio_controller.dart

  ...

  Future<void> playSound(String assetKey) async {
    try {
      final source = await _soloud!.loadAsset(assetKey);
      await _soloud!.play(source);
    } on SoLoudException catch (e) {
      _log.severe("Cannot play sound '$assetKey'. Ignoring.", e);
    }
  }

  ...

SoLoud, SoLoudNotInitializedException veya SoLoudTemporaryFolderFailedException istisnaları gibi çeşitli istisnalar atar. Her yöntemin API dokümanlarında, atılabilen istisna türleri listelenir.

SoLoud, ses motorunun işlevselliğiyle ilgili tüm hataları yakalayabilmeniz için tüm istisnaları için bir üst sınıf (SoLoudException istisnası) da sağlar. Bu, özellikle ses oynatmanın kritik olmadığı durumlarda yararlıdır. Örneğin, yalnızca "pıt-pıt" seslerinden biri yüklenemediği için oyuncunun oyun oturumunu kilitlemek istemediğinizde.

Muhtemelen tahmin edebileceğiniz gibi, var olmayan bir öğe anahtarı sağlarsanız loadAsset() yöntemi de FlutterError hatası verebilir. Oyunla birlikte paketlenmemiş öğeleri yüklemeye çalışmak genellikle çözmeniz gereken bir sorundur. Bu nedenle hata olarak değerlendirilir.

Farklı sesler çalma

Yalnızca pew1.mp3 dosyasını çaldığınızı fark etmiş olabilirsiniz ancak öğeler dizininde sesin iki başka sürümü de vardır. Oyunlarda aynı sesin birkaç versiyonu varsa ve farklı versiyonlar rastgele veya dönüşümlü olarak çalınır. Bu durum genellikle daha doğal bir ses verir. Bu sayede, örneğin ayak sesleri ve silah sesleri çok tekdüze ve dolayısıyla sahte gelmez.

  • İsteğe bağlı bir alıştırma olarak, düğmeye her dokunulduğunda farklı bir bip sesi çalacağı şekilde kodu değiştirin.

5. Müzikleri döngü şeklinde çalma

Daha uzun süreli sesleri yönetme

Bazı sesler uzun süre boyunca çalmak için tasarlanmıştır. Müzik en bariz örnektir ancak birçok oyunda koridorlarda esen rüzgar, uzaktan gelen rahiplerin mantraları, yüzyıllık metalin gıcırtısı veya hastaların uzaktan gelen öksürmeleri gibi ambiyans sesleri de çalınır.

Bunlar, oynatma süreleri dakika cinsinden ölçülebilen ses kaynaklarıdır. Gerektiğinde duraklatabilmeniz veya durdurabilmeniz için bu işlemleri takip etmeniz gerekir. Ayrıca genellikle büyük dosyalarla desteklenir ve çok fazla bellek tüketebilir. Bu nedenle, artık ihtiyaç duymadığınız AudioSource örneklerini kaldırmak için de bu örnekleri izlemeniz gerekir.

Bu nedenle, AudioController için yeni bir özel alan eklersiniz. Çalan şarkının herkese açık kullanıcı adı (varsa). Aşağıdaki satırı ekleyin:

lib/audio/audio_controller.dart

...

class AudioController {
  static final Logger _log = Logger('AudioController');

  SoLoud? _soloud;

  SoundHandle? _musicHandle;    // ← Add this.

  ...

Müziği başlatma

Müzik çalmak, tek seferlik bir ses çalmaktan farklı değildir. Yine de önce assets/music/looped-song.ogg dosyasını AudioSource sınıfının bir örneği olarak yüklemeniz, ardından SoLoud'un play() yöntemini kullanarak çalabileceğiniz bir dosya oluşturmanız gerekir.

Ancak bu kez, play() yönteminin döndürdüğü ses mülkünü ele alarak ses çalırken ses üzerinde işlem yapabilirsiniz.

  • Dilerseniz AudioController.startMusic() yöntemini kendiniz uygulayabilirsiniz. Bazı ayrıntıları doğru şekilde paylaşamayabilirsiniz. Önemli olan, Müzik başlat'ı seçtiğinizde müziğin başlamasıdır.

Referans uygulamayı aşağıda bulabilirsiniz:

lib/audio/audio_controller.dart

...

  Future<void> startMusic() async {
    if (_musicHandle != null) {
      if (_soloud!.getIsValidVoiceHandle(_musicHandle!)) {
        _log.info('Music is already playing. Stopping first.');
        await _soloud!.stop(_musicHandle!);
      }
    }
    final musicSource = await _soloud!.loadAsset(
      'assets/music/looped-song.ogg',
      mode: LoadMode.disk,
    );
  }

...

Müzik dosyasını disk modunda (LoadMode.disk enum) yüklediğinizi unutmayın. Bu, dosyanın yalnızca gerektiğinde parçalara ayrılarak yüklendiği anlamına gelir. Daha uzun süreli sesler için genellikle disk modunda yükleme yapmak en iyisidir. Kısa ses efektlerini belleğe yükleyip sıkıştırmak (varsayılan LoadMode.memory enum) daha mantıklıdır.

Ancak birkaç sorununuz var. İlk olarak, müzik çok yüksek sesli ve diğer sesleri bastırıyor. Çoğu oyunda müzik çoğu zaman arka planda yer alır. Böylece konuşma ve ses efektleri gibi daha bilgilendirici sesler ön plana çıkar. Bu, play yönteminin ses parametresini kullanarak düzeltmek içindir. Örneğin, şarkıyı% 60 ses seviyesinde çalmak için _soloud!.play(musicSource, volume: 0.6)'ü deneyebilirsiniz. Alternatif olarak, ses seviyesini daha sonra _soloud!.setVolume(_musicHandle, 0.6) gibi bir ifadeyle ayarlayabilirsiniz.

İkinci sorun ise şarkının aniden durması. Bunun nedeni, şarkının döngü şeklinde çalınması gerektiği ve döngünün başlangıç noktasının ses dosyasının başı olmaması.

88d2c57fffdfe996.png

Bu, şarkının doğal bir girişle başladığı ve ardından belirgin bir döngü noktası olmadan gerektiği kadar uzun süre çaldığı anlamına geldiği için oyun müzikleri için popüler bir seçimdir. Oyunun çalmakta olan şarkıdan çıkması gerektiğinde şarkının sesi yavaş yavaş azaltılır.

Neyse ki SoLoud, sesleri döngü şeklinde çalma yöntemleri sunuyor. play() yöntemi, looping parametresi için bir boole değeri ve loopingStartAt parametresi olarak da döngünün başlangıç noktasının değerini alır. Elde edilen kod aşağıdaki gibi görünür:

lib/audio/audio_controller.dart

...

_musicHandle = await _soloud!.play(
  musicSource,
  volume: 0.6,
  looping: true,
  //  The exact timestamp of the start of the loop.
  loopingStartAt: const Duration(seconds: 25, milliseconds: 43),
);

...

loopingStartAt parametresi ayarlanmazsa varsayılan olarak Duration.zero (yani ses dosyasının başlangıcı) olur. Girişsiz, mükemmel bir döngüye sahip bir müzik parçanız varsa bu seçeneği tercih edebilirsiniz.

  • Ses kaynağının çalınması bittikten sonra düzgün bir şekilde kaldırıldığını doğrulamak için her ses kaynağının sağladığı allInstancesFinished akışını dinleyin. Günlük çağrıları eklenmiş startMusic() yöntemi şu şekilde görünür:

lib/audio/audio_controller.dart

...

  Future<void> startMusic() async {
    if (_musicHandle != null) {
      if (_soloud!.getIsValidVoiceHandle(_musicHandle!)) {
        _log.info('Music is already playing. Stopping first.');
        await _soloud!.stop(_musicHandle!);
      }
    }
    _log.info('Loading music');
    final musicSource = await _soloud!.loadAsset(
      'assets/music/looped-song.ogg',
      mode: LoadMode.disk,
    );
    musicSource.allInstancesFinished.first.then((_) {
      _soloud!.disposeSource(musicSource);
      _log.info('Music source disposed');
      _musicHandle = null;
    });

    _log.info('Playing music');
    _musicHandle = await _soloud!.play(
      musicSource,
      volume: 0.6,
      looping: true,
      loopingStartAt: const Duration(seconds: 25, milliseconds: 43),
    );
  }

...

Sesi azaltma

Bir sonraki sorununuz, müziğin hiç bitmemesi. Şimdi bir solma efekti uygulama zamanı.

Sessizleştirmeyi uygulamanın bir yolu, Ticker veya Timer.periodic gibi saniyede birkaç kez çağrılan bir tür işlev kullanmak ve müziğin sesini küçük adımlarla düşürmektir. Bu yöntem işe yarar ancak çok fazla iş gerektirir.

Neyse ki SoLoud, bunu sizin için yapan kullanışlı bir "kullan ve unut" yöntemi sunar. Aşağıdaki adımları uygulayarak müziğin sesini beş saniye içinde yavaş yavaş azaltabilir ve CPU kaynaklarını gereksiz yere tüketmemesi için ses örneğini durdurabilirsiniz. fadeOutMusic() yöntemini şu kodla değiştirin:

lib/audio/audio_controller.dart

...

  void fadeOutMusic() {
    if (_musicHandle == null) {
      _log.info('Nothing to fade out');
      return;
    }
    const length = Duration(seconds: 5);
    _soloud!.fadeVolume(_musicHandle!, 0, length);
    _soloud!.scheduleStop(_musicHandle!, length);
  }

...

6. Efekt uygulama

Kullanabileceğiniz uygun bir ses motorunun en büyük avantajlarından biri, bazı sesleri yankı, ekolayzer veya düşük geçiş filtresi üzerinden yönlendirme gibi ses işleme işlemleri yapabilmenizdir.

Oyunlarda bu, konumların işitsel olarak ayırt edilmesi için kullanılabilir. Örneğin, bir alkış sesi ormanda beton bir sığınağa kıyasla farklı duyulur. Ormanlar sesin dağılmasına ve emilmesine yardımcı olurken sığınağın çıplak duvarları ses dalgalarını geri yansıtarak yankıya neden olur. Benzer şekilde, insanların sesleri bir duvardan duyulduğunda farklı gelir. Bu seslerin yüksek frekansları, katı ortamda ilerledikçe daha fazla zayıflar ve bu da düşük geçiren filtre etkisine neden olur.

Bir odada konuşan iki kişinin resmi. Ses dalgaları yalnızca bir kişiden diğerine doğrudan gitmekle kalmaz, duvarlardan ve tavandan da sekerek ilerler.

SoLoud, sese uygulayabileceğiniz çeşitli ses efektleri sunar.

  • Oyuncularınızın sesi katedral veya mağara gibi büyük bir odadan geliyormuş gibi yapmak için SoLoud.filters alanını kullanın:

lib/audio/audio_controller.dart

...

  void applyFilter() {
    _soloud!.filters.freeverbFilter.activate();
    _soloud!.filters.freeverbFilter.wet.value = 0.2;
    _soloud!.filters.freeverbFilter.roomSize.value = 0.9;
  }

  void removeFilter() {
    _soloud!.filters.freeverbFilter.deactivate();
  }

...

SoLoud.filters alanı, tüm filtre türlerine ve parametrelerine erişim sağlar. Her parametrenin kademeli olarak sönme ve salınım gibi yerleşik işlevleri de vardır.

Not: _soloud!.filters, genel filtreleri gösterir. Tek bir kaynağa filtre uygulamak istiyorsanız aynı işlevi gören karşılığı AudioSource.filters kullanın.

Önceki kodla şunları yapabilirsiniz:

  • Freeverb filtresini genel olarak etkinleştirin.
  • Wet (Sıcak) parametresini 0.2 olarak ayarlayın. Bu durumda, ortaya çıkan sesin% 80'i orijinal, %20'si ise yankı efektinin çıkışı olur. Bu parametreyi 1.0 olarak ayarlarsanız yalnızca odanın uzak duvarlarından size gelen ses dalgalarını duyarsınız ve orijinal sesin hiçbirini duymazsınız.
  • Oda Boyutu parametresini 0.9 olarak ayarlayın. Bu parametreyi dilediğiniz gibi ayarlayabilir veya dinamik olarak değiştirebilirsiniz. 1.0 büyük bir mağara, 0.0 ise banyodur.
  • Kodu değiştirip aşağıdaki filtrelerden birini veya bunların bir kombinasyonunu uygulayabilirsiniz:
  • biquadFilter (düşük geçiren filtre olarak kullanılabilir)
  • pitchShiftFilter
  • equalizerFilter
  • echoFilter
  • lofiFilter
  • flangerFilter
  • bassboostFilter
  • waveShaperFilter
  • robotizeFilter

7. Tebrikler

Ses çalan, müziği döngüde çalan ve efekt uygulayan bir ses denetleyicisi uyguladınız.

Daha fazla bilgi

  • Ses kontrol cihazını, başlangıçta sesleri önceden yükleme, şarkıları sırayla çalma veya zaman içinde kademeli olarak filtre uygulama gibi özelliklerle daha da ileriye taşımayı deneyin.
  • flutter_soloud'nin paket belgelerini okuyun.
  • Temel C++ kitaplığının ana sayfasını okuyun.
  • C++ kitaplığıyla arayüz oluşturmak için kullanılan teknoloji olan Dart FFI hakkında daha fazla bilgi edinin.
  • İlham almak için oyun ses programlama hakkında Guy Somberg'in konuşmasını izleyin. (Daha uzun bir sürüm de vardır.) Guy, "ara yazılım"dan bahsederken SoLoud ve FMOD gibi kitaplıkları kastetmektedir. Kodun geri kalanı her oyuna özgüdür.
  • Oyununuzu oluşturun ve yayınlayın.

Kulaklık resmi