将 AudioEffect 附加到全局混音的首选方式?

Posted

技术标签:

【中文标题】将 AudioEffect 附加到全局混音的首选方式?【英文标题】:Preferred way to attach AudioEffect to global mix? 【发布时间】:2012-03-13 08:52:45 【问题描述】:

android 的 AudioEffect API 中,所有内置效果(例如均衡器)都带有警告

“注意:不推荐使用会话 0 将均衡器附加到全局音频输出混合。”

如果不推荐使用,那么替代 API 是什么?我的目标为全局输出组合附加一个效果...

【问题讨论】:

【参考方案1】:

是的,它已被弃用,因为side-effects isues。

Android 开发者网站声明 Equalizer 类的第二个参数应该是:

系统范围内的唯一音频会话标识符。均衡器将是 附加到同一音频会话中的 MediaPlayer 或 AudioTrack。

你应该改用这个:

MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource( _your_data_source_ );
Equalizer equalizer = new Equalizer(0, mediaPlayer.getAudiosessionId());
equalizer.setEnabled(true);
/* Do your stuff ... */
mediaPlayer.start();

【讨论】:

如链接中的一个 cmets 中所述,如果您想将均衡器或其他效果应用于现有流或所有流,这不是一种解决方法。 现在您仍然可以通过Equalizer 使用全局音频会话。没有替代品,弃用并不总是伴随着替代品。他们只是认为这似乎效果不佳,并决定继续支持这一点,直到进一步的 Android 版本发布。在您的情况下,解决方法是将均衡器附加到您的应用程序中的每个 MediaPlayer 实例。如果没有,请冒险将Equalizer 附加到全局音频会话,因为知道它肯定不会在以后的版本中运行。 你好 Halim,如何将 eqaulizer 附加到每个 MediaPlayer 实例?请分享更多信息。还有什么是在 ICS 中全局附加效果的替代方法?【参考方案2】:

没有其他方法可以将 AudioEffect 附加到全局输出。您应该做的是注册一个接收所有音频会话的广播接收器,以便您可以对其应用音频效果。可以在here 找到一个示例。在此 BroadcastReceiver 中获取包含会话 ID 的意图。请记住,这仅在您在清单中注册接收器时才有效。 或者,您可以像这样在您的服务 onCreate() 中以编程方式注册接收器:

IntentFilter()
    .apply  addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) 
    .apply  addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION) 
    .run  registerReceiver(mAudioSessionReceiver, this)  `

mAudioSessionReceiver 看起来像这样:

private val mAudioSessionReceiver = object : BroadcastReceiver() 
    override fun onReceive(context: Context?, intent: Intent?) 
        if (intent == null || context == null) 
            return
        

        val sessionStates = arrayOf(
            AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION,
            AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION
        )
        if (sessionStates.contains(intent.action)) 
            val service = Intent(context, WaveletService::class.java)
            val sessionID = intent.getIntExtra(AudioEffect.EXTRA_AUDIO_SESSION, AudioEffect.ERROR)
            service
                .apply  action = intent.action 
                .apply  putExtra(AudioEffect.EXTRA_AUDIO_SESSION, sessionID) 
            context.startService(service)
        
    
`

然后,就可以在onStartCommand中获取intent:

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int 
    if (intent == null)
        return START_STICKY

    val sessionID = intent.getIntExtra(AudioEffect.EXTRA_AUDIO_SESSION, AudioEffect.ERROR)

    when (intent.action) 
        AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION -> 
            // create new instance of the AudioEffect using the sessionID
        
        AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION -> 
            // Release instance of the AudioEffect connected to this sessionID 
        
    

    return START_REDELIVER_INTENT
`

最后,不要忘记在 onDestroy() 中取消注册接收器:

unregisterReceiver(mAudioSessionReceiver)`

【讨论】:

【参考方案3】:

根据Android,您可以使用 ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION 来接收正在播放的音频会话的 id:

意图向效果控制应用程序或服务发出新音频会话已打开并需要应用音频效果的信号。

我尝试在清单中添加常量,但没有成功:

<receiver android:name=".receivers.AudioSessionReceiver">
        <intent-filter>
            <action android:name="android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION"/>
        </intent-filter>
</receiver>

如果您知道如何使用该常量,则 Intent 将包含音频会话 ID,您可以使用它来应用所需的均衡器设置。 (如果你在这些年里找到了解决方法,你介意分享一下吗?)

【讨论】:

这仅适用于 Spotify,您对此有任何线索吗?

以上是关于将 AudioEffect 附加到全局混音的首选方式?的主要内容,如果未能解决你的问题,请参考以下文章

Android上一种效果奇好的混音方法介绍

flstudio怎么把eq混音电平放到音轨上

音频混音是啥

音频处理和混音工具Waves Complete 10详细安装教程

Alamofire 访问将数据附加到全局变量

形而上的音乐学习