Android SoundPool

一、SoundPool介绍

SoundPool 一般用来播放密集,急促而又短暂的音效。

SoundPool 对象可以看作是一个可以从 APK 中导入资源 或者从文件系统中载入文件的样本集合。

它利用 MediaPlayer 服务为音频解码为一个原始16位 PCM流。这个特性使得应用程序可以进行流压缩,而无须忍受在播放音频时解压所带来的 CPU 负载和延时。SoundPool 使用音效池的概念来管理多个播放流,如果超过流的最大数目, SoundPool 会基于优先级自动停止先前播放的流,另外,SoundPool 还支持自行设置声音的品质、 音量、 播放比率等参数。

在我们车机能想到的使用场景就是播放beep音和警告音等用户提示音。

二、SoundPool相关类

JAVA类

SoundPool

SoundPool是Android平台上的一个类,用于播放短时、急促、密集的提示音。它适用于需要快速播放音频的场景,比如支付收款的到账通知等。SoundPool支持异步初始化,可以导入本地音频文件并解码。但需要注意的是,如果资源未加载完全时播放,则可能会出现不完整的情况。SoundPool由java类和C++类。

JAVA类

SoundPool代码位于:

frameworks/base/media/java/android/media/SoundPool.java

SoundPool的定义:

public class SoundPool extends PlayerBase {
    private final class EventHandler extends Handler {}
    public static class Builder {}
}

PlayerBase

PlayerBase是一个Android平台的抽象类,是MediaPlayer和AudioTrack等音视频播放器的基类,提供了部分公共的属性和方法。PlayerBase中封装了播放器的状态以及状态转换的方法,同时提供了一个Handler用于处理内部的消息,保证了内部交互的同步性和可靠性。另外,PlayerBase中也提供了一些常用的变量。子类可以继承并实现PlayerBase的抽象方法,然后使用该类提供的状态的变化来实现相应的逻辑。

PlayerBase代码位于:

frameworks/base/media/java/android/media/PlayerBase.java

PlayerBase的定义:

public abstract class PlayerBase {}

AudioAttributes

AudioAttributes用于描述音频属性,如下为几种常见属性设置:

setAllowedCapturePolicy:设置允许捕获音频的策略

  • public static final int ALLOW_CAPTURE_BY_ALL = 1:Indicates that the audio may be captured by any app.

  • public static final int ALLOW_CAPTURE_BY_SYSTEM = 2:Indicates that the audio may only be captured by system apps.

  • public static final int ALLOW_CAPTURE_BY_NONE = 3:Indicates that the audio is not to be recorded by any app, even if it is a system app.

setContentType:设置内容类型

  • public final static int CONTENT_TYPE_UNKNOWN = 0:Content type value to use when the content type is unknown, or other than the ones defined.

  • public final static int CONTENT_TYPE_SPEECH = 1:Content type value to use when the content type is speech.

  • public final static int CONTENT_TYPE_MUSIC = 2:Content type value to use when the content type is music.

  • public final static int CONTENT_TYPE_MOVIE = 3:Content type value to use when the content type is a soundtrack, typically accompanying a movie or TV program Content type value to use when the content type is a soundtrack, typically accompanying a movie or TV program.

  • public final static int CONTENT_TYPE_SONIFICATION = 4:Content type value to use when the content type is a sound used to accompany a user action, such as a beep or sound effect expressing a key click, or event, such as the type of a sound for a bonus being received in a game. These sounds are mostly synthesized or short Foley sounds.

  • public static final int CONTENT_TYPE_ULTRASOUND = 1997:Content type value to use when the content type is ultrasound.

setFlags:

  • public final static int FLAG_AUDIBILITY_ENFORCED = 0x1 << 0:Flag defining a behavior where the audibility of the sound will be ensured by the system. To ensure sound audibility, the system only uses built-in speakers or wired headphones and specifically excludes wireless audio devices.

  • public final static int FLAG_SECURE = 0x1 << 1:Flag defining a behavior where the playback of the sound is ensured without degradation only when going to a secure sink.

  • public final static int FLAG_SCO = 0x1 << 2:Flag to enable when the stream is associated with SCO usage. Internal use only for dealing with legacy STREAM_BLUETOOTH_SCO

  • public final static int FLAG_BEACON = 0x1 << 3:Flag defining a behavior where the system ensures that the playback of the sound will be compatible with its use as a broadcast for surrounding people and/or devices. Ensures audibility with no or minimal post-processing applied.

  • public final static int FLAG_HW_AV_SYNC = 0x1 << 4:Flag requesting the use of an output stream supporting hardware A/V synchronization.

  • public final static int FLAG_HW_HOTWORD = 0x1 << 5:Flag requesting capture from the source used for hardware hotword detection. To be used with capture preset MediaRecorder.AudioSource.HOTWORD or MediaRecorder.AudioSource.VOICE_RECOGNITION.

  • public final static int FLAG_BYPASS_INTERRUPTION_POLICY = 0x1 << 6:Flag requesting audible playback even under limited interruptions.

  • public final static int FLAG_BYPASS_MUTE = 0x1 << 7:Flag requesting audible playback even when the underlying stream is muted.

  • public final static int FLAG_LOW_LATENCY = 0x1 << 8:Flag requesting a low latency path when creating an AudioTrack. When using this flag, the sample rate must match the native sample rate of the device. Effects processing is also unavailable.

  • public final static int FLAG_DEEP_BUFFER = 0x1 << 9:Flag requesting a deep buffer path when creating an {@code AudioTrack}. A deep buffer path, if available, may consume less power and is suitable for media playback where latency is not a concern.

  • public static final int FLAG_NO_MEDIA_PROJECTION = 0x1 << 10:Flag specifying that the audio shall not be captured by third-party apps with a MediaProjection.

  • public static final int FLAG_MUTE_HAPTIC = 0x1 << 11:Flag indicating force muting haptic channels. public static final int FLAG_NO_SYSTEM_CAPTURE = 0x1 << 12:Flag specifying that the audio shall not be captured by any apps, not even system apps.

  • public static final int FLAG_CAPTURE_PRIVATE = 0x1 << 13:Flag requesting private audio capture. When set in audio attributes passed to an AudioRecord, this prevents a privileged Assistant from capturing audio while this AudioRecord is active.

  • public static final int FLAG_CONTENT_SPATIALIZED = 0x1 << 14:Flag indicating the audio content has been processed to provide a virtual multichannel audio experience

  • public static final int FLAG_NEVER_SPATIALIZE = 0x1 << 15:Flag indicating the audio content is to never be spatialized

  • public static final int FLAG_CALL_REDIRECTION = 0x1 << 16:Flag indicating the audio is part of a call redirection. Valid for playback and capture.

setUsage:设置使用场景:

  • private static final int USAGE_INVALID = -1: Invalid value, only ever used for an uninitialized usage value

  • public final static int USAGE_UNKNOWN = 0:Usage value to use when the usage is unknown.

  • public final static int USAGE_MEDIA = 1:Usage value to use when the usage is media, such as music, or movie soundtracks.

  • public final static int USAGE_VOICE_COMMUNICATION = 2:Usage value to use when the usage is voice communications, such as telephony or VoIP.

  • public final static int USAGE_VOICE_COMMUNICATION_SIGNALLING = 3:Usage value to use when the usage is in-call signalling, such as with a "busy" beep, or DTMF tones.

  • public final static int USAGE_ALARM = 4:Usage value to use when the usage is an alarm (e.g. wake-up alarm).

  • public final static int USAGE_NOTIFICATION = 5:Usage value to use when the usage is notification. See other notification usages for more specialized uses.

  • public final static int USAGE_NOTIFICATION_RINGTONE = 6:Usage value to use when the usage is telephony ringtone.

  • public final static int USAGE_NOTIFICATION_COMMUNICATION_REQUEST = 7:Usage value to use when the usage is a request to enter/end a communication, such as a VoIP communication or video-conference.

  • public final static int USAGE_NOTIFICATION_COMMUNICATION_INSTANT = 8:Usage value to use when the usage is notification for an "instant" communication such as a chat, or SMS.

  • public final static int USAGE_NOTIFICATION_COMMUNICATION_DELAYED = 9:Usage value to use when the usage is notification for a non-immediate type of communication such as e-mail.

  • public final static int USAGE_NOTIFICATION_EVENT = 10:Usage value to use when the usage is to attract the user's attention, such as a reminder or low battery warning.

  • public final static int USAGE_ASSISTANCE_ACCESSIBILITY = 11:Usage value to use when the usage is for accessibility, such as with a screen reader.

  • public final static int USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12:Usage value to use when the usage is driving or navigation directions.

  • public final static int USAGE_ASSISTANCE_SONIFICATION = 13:Usage value to use when the usage is sonification, such as with user interface sounds.

  • public final static int USAGE_GAME = 14:Usage value to use when the usage is for game audio.

  • public final static int USAGE_VIRTUAL_SOURCE = 15:Usage value to use when feeding audio to the platform and replacing "traditional" audio source, such as audio capture devices.

  • public final static int USAGE_ASSISTANT = 16:Usage value to use for audio responses to user queries, audio instructions or help utterances.

  • public static final int USAGE_CALL_ASSISTANT = 17:Usage value to use for assistant voice interaction with remote caller on Cell and VoIP calls.

AudioAttributes代码位于:

frameworks/base/media/java/android/media/AudioAttributes.java

AudioAttributes的定义:

public final class AudioAttributes implements Parcelable {
    public static class Builder {}
}

SoundEffectsHelper

一个帮助程序类,用于管理 AudioService 使用的声音效果加载/卸载。当在 AudioService 的消息处理程序线程上调用其方法时,实际工作将卸载到专用线程。

这有助于保持 AudioService 的响应速度。

SoundEffectsHelper代码位于:

frameworks/base/service/java/com/android/server/audio/SoundEffectsHelper.java

SoundEffectsHelper的定义:

class SoundEffectsHelper {
    private static final class Resource {}
    private class SfxWorker extends Thread {}
    private class SfxHandler extends Handler {}
    private class SoundPoolLoader implements
            android.media.SoundPool.OnLoadCompleteListener {}
}

C++类

SoundPool

SoundPool代码位于:

frameworks/base/media/jni/SoundPool/SoundPool.h

frameworks/base/media/jni/SoundPool/SoundPool.cpp

SoundPool的定义:

class SoundPool {}

StreamManager

StreamManager 用于管理流(由 Java 中的 StreamID 访问)。

StreamManager代码位于:

frameworks/base/media/jni/SoundPool/StreamManager.h

frameworks/base/media/jni/SoundPool/StreamManager.cpp

StreamManager的定义:

class JavaThread {} //JavaThread is used like std::thread but for threads that may call the JVM.
class ThreadPool {} //The ThreadPool manages thread lifetimes of SoundPool worker threads.
class PerfectHash {} //A Perfect HashTable for IDs (key) to pointers (value).
class StreamMap {} //StreamMap contains the all the valid streams available to SoundPool.
class StreamManager : public StreamMap {} //StreamManager is used to manage the streams (accessed by StreamID from Java).

SoundManager

此类管理 SoundPool 的声音。

SoundManager代码位于:

frameworks/base/media/jni/SoundPool/SoundManager.h

frameworks/base/media/jni/SoundPool/SoundManager.cpp

SoundManager的定义:

class SoundPoolEvent {}
class SoundManager {}
class CallbackHandler {}

Sound

Sound是SoundPool使用的资源,由soundID引用。

Sound 代码位于:

frameworks/base/media/jni/SoundPool/Sound.h

frameworks/base/media/jni/SoundPool/Sound.cpp

Sound 的定义:

class Sound {}

Sound 方法:

int32_t getSoundID() const { return mSoundID; }
int32_t getChannelCount() const { return mChannelCount; }
uint32_t getSampleRate() const { return mSampleRate; }
audio_format_t getFormat() const { return mFormat; }
audio_channel_mask_t getChannelMask() const { return mChannelMask; }
size_t getSizeInBytes() const { return mSizeInBytes; }
sound_state getState() const { return mState; }
uint8_t* getData() const { return static_cast<uint8_t*>(mData->unsecurePointer()); }
sp<IMemory> getIMemory() const { return mData; }

SoundDecoder

SoundDecoder处理后台解码任务。

SoundDecoder代码位于:

frameworks/base/media/jni/SoundPool/SoundDecoder.h

frameworks/base/media/jni/SoundPool/SoundDecoder.cpp

SoundDecoder的定义:

class SoundDecoder {}

SoundDecoder方法:

void loadSound(int32_t soundID) NO_THREAD_SAFETY_ANALYSIS; // uses unique_lock
void quit();

Stream

soundpool Stream相关处理。

Stream代码位于:

frameworks/base/media/jni/SoundPool/Stream.h

frameworks/base/media/jni/SoundPool/Stream.cpp

Stream的定义:

class Stream : public CSubsystemObject {}

Stream 方法:

bool requestStop(int32_t streamID);
        void stop();
        void clearAudioTrack();
        void pause(int32_t streamID);
        void autoPause();
        void resume(int32_t streamID);
        void autoResume();
        void mute(bool muting);
        Stream* playPairStream(std::vector<std::any>& garbage);
        void setVolume(int32_t streamID, float leftVolume, float rightVolume);
        void setRate(int32_t streamID, float rate);
        void setPriority(int32_t streamID, int priority);
        void setLoop(int32_t streamID, int loop);
        void setPlay(int32_t streamID, const std::shared_ptr<Sound> &sound, int32_t soundID float leftVolume, float rightVolume, int32_t priority, int32_t loop, float rate);
        void setStopTimeNs(int64_t stopTimeNs); 
        int32_t getPriority();
        int32_t getPairPriority();
        int64_t getStopTimeNs();
        int32_t getStreamID();
        int32_t getSoundID();
        bool hasSound();
        Stream* getPairStream() const;
        int getCorrespondingStreamID();

三、SoundPool API

SoundPool(int maxStreams, int streamType, int srcQuality):构造函数

int load(Context context, int resId, int priority):加载声音资源,返回一个声音的ID,后面我们可以通过这个ID来播放指定的声音

int load(String path, int priority):加载声音资源,返回一个声音的ID,后面我们可以通过这个ID来播放指定的声音

int load(FileDescriptor fd, long offset, long length, int priority):加载声音资源,返回一个声音的ID,后面我们可以通过这个ID来播放指定的声音

int load(AssetFileDescriptor afd, int priority):加载声音资源,返回一个声音的ID,后面我们可以通过这个ID来播放指定的声音

int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate):播放

void setVolume(int streamID, float volume):设置音量

void setPriority(int streamID, int priority):设置优先级

void pause(int streamID):暂停

void resume(int streamID):重播

void stop(int streamID):停止

void release() :释放资源

参数介绍:

maxStreams 同时播放流的最大数量,当播放的流的数目大于此值,则会选择性停止优先级较低的流

streamType 流类型,比如 STREAM_MUSIC

srcQuality 采样率转换器质量,目前没有什么作用,默认填充0

context:上下文

resId:资源id

priority:没什么用的一个参数,建议设置为1,保持和未来的兼容性

path:文件路径

FileDescriptor:貌似是流吧,这个我也不知道

AssetFileDescriptor:从asset目录读取某个资源文件,用法: AssetFileDescriptor descriptor = - assetManager.openFd(“biaobiao.mp3”);

soundID:Load()返回的声音ID号

leftVolume:左声道音量设置

rightVolume:右声道音量设置

priority:指定播放声音的优先级,数值越高,优先级越大。

loop:指定是否循环:-1表示无限循环,0表示不循环,其他值表示要重复播放的次数

rate:指定播放速率:1.0的播放率可以使声音按照其原始频率,而2.0的播放速率,可以使声音按照其 原始频率的两倍播放。如果为0.5的播放率,则播放速率是原始频率的一半。播放速率的取值范围是0.5至2.0。

四、SoundPool流程分析

SoundPool 创建流程分析

Android13 SoundPool 创建流程分析-CSDN博客

SoundPool load流程分析

Android13 SoundPool load流程分析-CSDN博客

SoundPool play流程分析

Android13 SoundPool play流程分析-CSDN博客

  • 15
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值