betacode

Воспроизведение звуковых эффектов в Android с помощью SoundPool

View more Tutorials:

Следуйте за нами на нашей фан-странице, чтобы получать уведомления каждый раз, когда появляются новые статьи. Facebook

1- SoundPool & AudioManager

Для начала, я создам ситуацию, вы создаете игру, игра проигрывает такие звуки как выстрелы, бомбы, это звуковые эффекты в игре. Android предоставляет вам класс SoundPool, похожий на хранилице звуков и готовый проигрывать их при запросе.

SoundPool содержит набор музыки, звуков из файла музыки в приложении или из файла в системе,.. SoundPool помогает проигрывать разные звуки одновременно. 

SourcePool использует сервис MediaPlayer, чтобы сделать звуки.
Вы можете настроить SoundPool проигрывать звуки при определенных stream (поток). Есть следующие виды stream:
Вид потока звуков Описание
AudioManager.STREAM_ALARM Аудио звуков сирены
AudioManager.STREAM DTMF Аудио DTMF тонов
AudioManager.STREAM_MUSIC Аудио для перепроигрывания звуков
AudioManager.STREAM_NOTIFICATION Аудио звука уведомления
AudioManager.STREAM_RING Аудио звука звона телефона
AudioManager.STREAM_SYSTEM Аудио системных звуков
AudioManager.STREAM_VOICE_CALL Аудио телефонного вызова
AudioManager позволяет вам поменять громкость на разных потоках (stream) звуков. Например вы слушаете песню на устройстве, когда играете в игры, вы можете поменять громкость звуков игры не влияя на громкость песни.
Другой вопрос это какое устройство производит звук.

Используя STREAM_MUSIC звук будет произведен через одно звуковое устройтсво (телефонный динамик, наушники, динамик bluetooth и др.) соединенные с телефоном.

Используя STREAM_RING  звук будет произведен через все звуковые устройтсва соединенные с телефоном. Это поведение может отличаться на каждом устройстве.

SoundPool API:

Метод Описание
int play(int soundID, float leftVolume, float rightVolume,
            int priority, int loop, float rate)
Воспроизведение источника звука, с возвращением ID нового воспроизведенного потока (streamID).
void pause(int streamID)  Пауза звукового потока с  ID streamID.
void stop(int streamID) Остановка звукового потока с streamID.
void setVolume(int streamID, float leftVolume, float rightVolume) Установка громкости звукового потока  с ID streamID
void setLoop(int streamID, int loop) Установка номер цикла для звукового потока с ID streamID.

2- Пример с SoundPool

Создать новый project SoundPoolDemo.
  • Name: SoundPoolDemo
  • Package name: org.o7planning.soundpooldemo
Создать папку raw, которая является подпапкой res. Скопировать 2 файла звука в папку raw, здесь я скопировал 2 звуковых файла: звук разрушения (destroy.wav) и звук выстрелов (gun.wav). Заметьте, вы можете использовать звуковой файл формата mp3 или wav.
Интерфейс приложения.
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button_destroy"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:layout_marginLeft="32dp"
        android:layout_marginTop="50dp"
        android:text="Destroy"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button_gun"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="50dp"
        android:text="Gun"
        app:layout_constraintStart_toEndOf="@+id/button_destroy"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java

package org.o7planning.soundpooldemo;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {


    private SoundPool soundPool;

    private AudioManager audioManager;
    private Button buttonDestroy;
    private Button buttonGun;

    // Maximumn sound stream.
    private static final int MAX_STREAMS = 5;

    // Stream type.
    private static final int streamType = AudioManager.STREAM_MUSIC;

    private boolean loaded;

    private int soundIdDestroy;
    private int soundIdGun;
    private float volume;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.buttonDestroy = (Button) this.findViewById(R.id.button_destroy);
        this.buttonGun = (Button) this.findViewById(R.id.button_gun);

        this.buttonDestroy.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playSoundDestroy();
            }
        });

        this.buttonGun.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playSoundGun();
            }
        });

        // AudioManager audio settings for adjusting the volume
        audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);

        // Current volumn Index of particular stream type.
        float currentVolumeIndex = (float) audioManager.getStreamVolume(streamType);

        // Get the maximum volume index for a particular stream type.
        float maxVolumeIndex  = (float) audioManager.getStreamMaxVolume(streamType);

        // Volumn (0 --> 1)
        this.volume = currentVolumeIndex / maxVolumeIndex;

        // Suggests an audio stream whose volume should be changed by
        // the hardware volume controls.
        this.setVolumeControlStream(streamType);

        // For Android SDK >= 21
        if (Build.VERSION.SDK_INT >= 21 ) {
            AudioAttributes audioAttrib = new AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_GAME)
                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                    .build();

            SoundPool.Builder builder= new SoundPool.Builder();
            builder.setAudioAttributes(audioAttrib).setMaxStreams(MAX_STREAMS);

            this.soundPool = builder.build();
        }
        // for Android SDK < 21
        else {
            // SoundPool(int maxStreams, int streamType, int srcQuality)
            this.soundPool = new SoundPool(MAX_STREAMS, AudioManager.STREAM_MUSIC, 0);
        }

        // When Sound Pool load complete.
        this.soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
            @Override
            public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                loaded = true;
            }
        });

        // Load sound file (destroy.wav) into SoundPool.
        this.soundIdDestroy = this.soundPool.load(this, R.raw.destroy,1);

        // Load sound file (gun.wav) into SoundPool.
        this.soundIdGun = this.soundPool.load(this, R.raw.gun,1);

    }



    // When users click on the button "Gun"
    public void playSoundGun( )  {
        if(loaded)  {
            float leftVolumn = volume;
            float rightVolumn = volume;
            // Play sound of gunfire. Returns the ID of the new stream.
            int streamId = this.soundPool.play(this.soundIdGun,leftVolumn, rightVolumn, 1, 0, 1f);
        }
    }

    // When users click on the button "Destroy"
    public void playSoundDestroy( )  {
        if(loaded)  {
            float leftVolumn = volume;
            float rightVolumn = volume;

            // Play sound objects destroyed. Returns the ID of the new stream.
            int streamId = this.soundPool.play(this.soundIdDestroy,leftVolumn, rightVolumn, 1, 0, 1f);
        }
    }

}

 
Запуск приложения:

View more Tutorials:

Maybe you are interested

Это онлайн курс вне вебсайта o7planning, который мы представляем, он включает бесплатные курсы или курсы со скидкой.