音频频谱分析与 VU 表处理组件,统一管理软件回采、硬件回采、频谱分析和左右声道 VU 显示。
implementation("io.github.qytech:spectrum:0.2.3")
SpectrumVuProcessorStereoSpectrumVuProcessorSpectrumCaptureRuntime 统一管理回采生命周期AUTO、SOFTWARE、HARDWARE、OFF 四种回采模式LOUDNESS 真实响度与 PEAK 峰值两种显示方式private val spectrumRuntime = SpectrumCaptureRuntime()
fun initializeSpectrum() {
spectrumRuntime.setListener(object : SpectrumVuUpdateListener {
override fun onSpectrumDataUpdated(dbList: DoubleArray) {
// 更新频谱 UI
}
override fun onVuDataUpdated(vuData: VuData) {
// 更新左右声道 VU UI
}
})
spectrumRuntime.setPolicy(SpectrumCapturePolicy.AUTO)
}
fun setSpectrumActive(active: Boolean) {
spectrumRuntime.setSignalActive(active)
}
fun setSpectrumMode(policy: SpectrumCapturePolicy) {
spectrumRuntime.setPolicy(policy)
}
fun setVuMode(mode: VuMeterMode) {
spectrumRuntime.setVuMeterMode(mode)
}
fun releaseSpectrum() {
spectrumRuntime.close()
}
AUTO 默认使用硬件回采。用户明确选择 SOFTWARE、HARDWARE 或 OFF 后,运行时以用户设置为准。
VU 表新增两种显示方式,可根据产品的视觉风格和使用场景选择:
LOUDNESS:显示音频的短时真实响度,变化更平稳,适合观察音乐整体强弱。PEAK:显示左右声道峰值,对鼓点、瞬态和强音响应更明显,适合需要更大指针摆幅的界面。默认使用 LOUDNESS,升级后不会改变现有显示效果。需要更明显的摆动时,可在创建运行时对象时选择 PEAK:
import com.qytech.spectrum.capture.SpectrumCaptureRuntime
import com.qytech.spectrum.capture.VuMeterMode
private val spectrumRuntime = SpectrumCaptureRuntime(
vuMeterMode = VuMeterMode.PEAK,
)
也可以在应用运行期间切换。例如,将该方法连接到应用设置页:
fun applyVuMode(usePeak: Boolean) {
spectrumRuntime.setVuMeterMode(
if (usePeak) VuMeterMode.PEAK else VuMeterMode.LOUDNESS,
)
}
模式切换只影响 VU 表数据,不会改变频谱柱、回采来源或当前播放状态。
LOUDNESS 与 PEAK 两种 VU 显示方式,客户可按产品界面选择真实响度或峰值响应LOUDNESS,现有应用升级后无需修改即可继续使用原有显示方式PEAK 模式可增强鼓点和瞬态信号的显示幅度,让 VU 指针或灯条响应更明显SpectrumCaptureRuntime,统一管理回采模式、启停、监听和资源释放AUTO 默认使用硬件回采;用户选择 SOFTWARE、HARDWARE 或 OFF 时以用户设置为准fftSize = 4096 效果更好SpectrumVuProcessor 和 StereoSpectrumVuProcessor 改为单例,避免可能出现的节点占用情况SpectrumVuProcessor.getInstance(fftSize = 1024)
StereoSpectrumVuProcessor.getInstance(fftSize = 1024)
BaseSpectrumVuCapture 新增 setVolumeCompensationGain(gain: Double) 接口StereoSpectrumVuProcessor 用于处理左右声道分离的频谱显示class StereoSpectrumVuProcessor(
sampleRate: Int = 44100,
fftSize: Int = 1024,
windowType: WindowType = WindowType.HANNING,
muteThreshold: Double = 5e-4,
private val bandCount: Int = 128,
private val minFreq: Double = 50.0,
private val maxFreq: Double = 20000.0,
)
StereoSpectrumVuView(context).apply {
setBarCount(128)
}
private var spectrumVuProcessor: StereoSpectrumVuProcessor? = null
fun startRecord() {
spectrumVuProcessor = StereoSpectrumVuProcessor(bandCount = 128)
spectrumVuProcessor?.setStereoSpectrumListener(object : StereoSpectrumVuUpdateListener {
override fun onStereoSpectrumUpdated(
leftDbList: DoubleArray,
rightDbList: DoubleArray,
) {
_dbLeftList.value = leftDbList
_dbRightList.value = rightDbList
}
override fun onVuDataUpdated(vuData: VuData) {
_vuData.value = vuData
}
})
spectrumVuProcessor?.setCapturePriority(LoopbackPriority.PRIORITY_SOFTWARE_ONLY)
spectrumVuProcessor?.start()
}
fun stopRecord() {
spectrumVuProcessor?.removeStereoSpectrumListener()
spectrumVuProcessor?.stop()
spectrumVuProcessor?.release()
}
PRIORITY_AUTOenum class LoopbackPriority {
PRIORITY_AUTO,
PRIORITY_SOFTWARE_FIRST,
PRIORITY_HARDWARE_FIRST,
PRIORITY_SOFTWARE_ONLY,
PRIORITY_HARDWARE_ONLY
}
class SpectrumVuProcessor {
fun setCapturePriority(priority: LoopbackPriority)
}
LoopbackProcessor;如需库直接处理数据,请使用 SpectrumVuProcessorLoopbackProcessor 新增 release 方法,组件销毁时必须调用