feat: 新增 42 个 Android API 模块
新增模块覆盖: 系统层 (14): system, security, print, opengl, renderscript, transition, test, service_notification, service_controls, service_quicksettings, service_wallpaper, service_autofill, service_dreams, service_vr 应用层 (13): app_admin, app_backup, app_job, app_usage, app_role, app_people, appwidget, companion, credentials, mtp, sip, telecom, speech 硬件媒体层 (15): hardware_display, hardware_fingerprint, hardware_usb, hardware_input, media_audiofx, media_browse, media_session, media_tv, media_midi, media_projection, uwb, se, view_autofill, view_textclassifier, view_translation 总计 94 个模块,75,342 行代码
This commit is contained in:
1 parent
8ad62be068
commit
506f9ac725
43 files changed
+16704
-23
No files matched your search
@@ -0,0 +1,547 @@
|
||||
"""
|
||||
Android media.audiofx 组件 — AudioEffect, Equalizer, BassBoost, Virtualizer 等
|
||||
方法签名完全对齐 Android SDK
|
||||
"""
|
||||
|
||||
import math
|
||||
from typing import Any, Callable, Dict, List, Optional, Tuple
|
||||
|
||||
from .._core import Stub, AndroidOnlyError
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# AudioEffect
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class AudioEffect(Stub):
|
||||
"""AudioEffect — 音频效果基类"""
|
||||
|
||||
EFFECT_SUCCESS = 0
|
||||
EFFECT_ERROR = -1
|
||||
EFFECT_ALREADY_EXISTS = -2
|
||||
EFFECT_NO_MORE_SESSION = -3
|
||||
EFFECT_REQUEST_INIT = -4
|
||||
EFFECT_INIT_FAILED = -5
|
||||
|
||||
EFFECT_INSERT = 1
|
||||
EFFECT_AUXILIARY = 2
|
||||
EFFECT_PRE_PROCESSING = 4
|
||||
EFFECT_POST_PROCESSING = 8
|
||||
|
||||
CONTENT_TYPE_MUSIC = 2
|
||||
CONTENT_TYPE_MOVIE = 3
|
||||
CONTENT_TYPE_GAME = 4
|
||||
CONTENT_TYPE_VOICE = 1
|
||||
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
# Descriptor
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
|
||||
class Descriptor(Stub):
|
||||
"""AudioEffect.Descriptor — 效果描述符"""
|
||||
|
||||
def __init__(self, type: str = "", uuid: str = "",
|
||||
connectMode: str = "", name: str = "",
|
||||
implementor: str = ""):
|
||||
super().__init__()
|
||||
self.type = type
|
||||
self.uuid = uuid
|
||||
self.connectMode = connectMode
|
||||
self.name = name
|
||||
self.implementor = implementor
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"Descriptor(type={self.type}, uuid={self.uuid}, name={self.name})"
|
||||
|
||||
def __init__(self, effectType: str = "", priority: int = 0,
|
||||
audioSession: int = 0):
|
||||
super().__init__()
|
||||
self._enabled = False
|
||||
self._effect_type = effectType
|
||||
self._priority = priority
|
||||
self._audio_session = audioSession
|
||||
self._id = hash(self) & 0x7FFFFFFF
|
||||
self._control_status_listener: Optional[Callable] = None
|
||||
self._enable_status_listener: Optional[Callable] = None
|
||||
|
||||
def getEnabled(self) -> bool:
|
||||
return self._enabled
|
||||
|
||||
def setEnabled(self, enabled: bool) -> int:
|
||||
self._enabled = enabled
|
||||
return AudioEffect.EFFECT_SUCCESS
|
||||
|
||||
def getId(self) -> int:
|
||||
return self._id
|
||||
|
||||
def getDescriptor(self) -> Descriptor:
|
||||
return AudioEffect.Descriptor(
|
||||
type=self._effect_type,
|
||||
uuid="",
|
||||
connectMode="",
|
||||
name=self.__class__.__name__,
|
||||
implementor="Android-pyApi"
|
||||
)
|
||||
|
||||
def release(self):
|
||||
self._enabled = False
|
||||
|
||||
def setControlStatusListener(self, listener: Callable):
|
||||
self._control_status_listener = listener
|
||||
|
||||
def setEnableStatusListener(self, listener: Callable):
|
||||
self._enable_status_listener = listener
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Equalizer
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class Equalizer(AudioEffect):
|
||||
"""Equalizer — 均衡器"""
|
||||
|
||||
PARAM_CURRENT_PRESET = 0
|
||||
PARAM_GET_BAND = 1
|
||||
PARAM_STRING_SIZE_MAX = 2
|
||||
PARAM_BAND_LEVEL = 3
|
||||
PARAM_LEVEL_RANGE = 4
|
||||
PARAM_NUM_BANDS = 5
|
||||
PARAM_BAND_FREQ_RANGE = 6
|
||||
PARAM_CENTER_FREQ = 7
|
||||
PARAM_GET_PRESET_NAME = 8
|
||||
PARAM_NUM_PRESETS = 9
|
||||
PARAM_PROPERTIES = 10
|
||||
|
||||
def __init__(self, priority: int = 0, audioSession: int = 0):
|
||||
super().__init__("Equalizer", priority, audioSession)
|
||||
self._num_bands = 5
|
||||
self._band_levels: Dict[int, int] = {}
|
||||
self._presets = [
|
||||
"Normal", "Classical", "Dance", "Flat", "Folk",
|
||||
"Heavy Metal", "Hip Hop", "Jazz", "Pop", "Rock"
|
||||
]
|
||||
self._current_preset = 0
|
||||
self._band_freq_ranges: Dict[int, Tuple[int, int]] = {
|
||||
0: (60, 200), 1: (200, 600), 2: (600, 2400),
|
||||
3: (2400, 8000), 4: (8000, 16000)
|
||||
}
|
||||
|
||||
def getNumberOfBands(self) -> int:
|
||||
return self._num_bands
|
||||
|
||||
def getBand(self, frequency: int) -> int:
|
||||
for band, (low, high) in self._band_freq_ranges.items():
|
||||
if low <= frequency <= high:
|
||||
return band
|
||||
return 0
|
||||
|
||||
def getBandLevel(self, band: int) -> int:
|
||||
return self._band_levels.get(band, 0)
|
||||
|
||||
def setBandLevel(self, band: int, level: int):
|
||||
self._band_levels[band] = level
|
||||
|
||||
def getBandLevelRange(self) -> List[int]:
|
||||
return [-1500, 1500]
|
||||
|
||||
def getCenterFreq(self, band: int) -> int:
|
||||
if band in self._band_freq_ranges:
|
||||
low, high = self._band_freq_ranges[band]
|
||||
return (low + high) // 2
|
||||
return 0
|
||||
|
||||
def getNumberOfPresets(self) -> int:
|
||||
return len(self._presets)
|
||||
|
||||
def getPresetName(self, preset: int) -> str:
|
||||
if 0 <= preset < len(self._presets):
|
||||
return self._presets[preset]
|
||||
return "Unknown"
|
||||
|
||||
def usePreset(self, preset: int):
|
||||
if 0 <= preset < len(self._presets):
|
||||
self._current_preset = preset
|
||||
|
||||
def getCurrentPreset(self) -> int:
|
||||
return self._current_preset
|
||||
|
||||
def getProperties(self) -> Any:
|
||||
return None
|
||||
|
||||
def setProperties(self, properties: Any):
|
||||
pass
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"Equalizer(preset={self._presets[self._current_preset]}," \
|
||||
f" bands={self._num_bands})"
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# BassBoost
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class BassBoost(AudioEffect):
|
||||
"""BassBoost — 低音增强"""
|
||||
|
||||
PARAM_STRENGTH = 1
|
||||
PARAM_STRENGTH_SUPPORTED = 2
|
||||
|
||||
def __init__(self, priority: int = 0, audioSession: int = 0):
|
||||
super().__init__("BassBoost", priority, audioSession)
|
||||
self._strength: int = 0
|
||||
|
||||
def setStrength(self, strength: int):
|
||||
self._strength = max(0, min(1000, strength))
|
||||
|
||||
def getRoundedStrength(self) -> int:
|
||||
return self._strength
|
||||
|
||||
def getStrengthSupported(self) -> bool:
|
||||
return True
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"BassBoost(strength={self._strength})"
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Virtualizer
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class Virtualizer(AudioEffect):
|
||||
"""Virtualizer — 虚拟器 (空间音频)"""
|
||||
|
||||
PARAM_STRENGTH = 1
|
||||
PARAM_STRENGTH_SUPPORTED = 2
|
||||
PARAM_VIRTUALIZATION_MODE = 3
|
||||
PARAM_FORCE_VIRTUALIZATION_MODE = 4
|
||||
|
||||
VIRTUALIZATION_MODE_AUTO = 0
|
||||
VIRTUALIZATION_MODE_OFF = 1
|
||||
VIRTUALIZATION_MODE_TRANSAURAL = 2
|
||||
VIRTUALIZATION_MODE_BINAURAL = 3
|
||||
|
||||
def __init__(self, priority: int = 0, audioSession: int = 0):
|
||||
super().__init__("Virtualizer", priority, audioSession)
|
||||
self._strength: int = 0
|
||||
self._virtualization_mode = Virtualizer.VIRTUALIZATION_MODE_AUTO
|
||||
|
||||
def setStrength(self, strength: int):
|
||||
self._strength = max(0, min(1000, strength))
|
||||
|
||||
def getRoundedStrength(self) -> int:
|
||||
return self._strength
|
||||
|
||||
def canVirtualize(self, channelMask: int, virtualizationMode: int) -> bool:
|
||||
return True
|
||||
|
||||
def getVirtualizationMode(self) -> int:
|
||||
return self._virtualization_mode
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"Virtualizer(strength={self._strength}, mode={self._virtualization_mode})"
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# PresetReverb
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class PresetReverb(AudioEffect):
|
||||
"""PresetReverb — 预设混响"""
|
||||
|
||||
PRESET_NONE = 0
|
||||
PRESET_SMALLROOM = 1
|
||||
PRESET_MEDIUMROOM = 2
|
||||
PRESET_LARGEROOM = 3
|
||||
PRESET_MEDIUMHALL = 4
|
||||
PRESET_LARGEHALL = 5
|
||||
PRESET_PLATE = 6
|
||||
|
||||
PARAM_PRESET = 0
|
||||
|
||||
def __init__(self, priority: int = 0, audioSession: int = 0):
|
||||
super().__init__("PresetReverb", priority, audioSession)
|
||||
self._preset = PresetReverb.PRESET_NONE
|
||||
self._preset_names = {
|
||||
PresetReverb.PRESET_NONE: "None",
|
||||
PresetReverb.PRESET_SMALLROOM: "Small Room",
|
||||
PresetReverb.PRESET_MEDIUMROOM: "Medium Room",
|
||||
PresetReverb.PRESET_LARGEROOM: "Large Room",
|
||||
PresetReverb.PRESET_MEDIUMHALL: "Medium Hall",
|
||||
PresetReverb.PRESET_LARGEHALL: "Large Hall",
|
||||
PresetReverb.PRESET_PLATE: "Plate",
|
||||
}
|
||||
|
||||
def setPreset(self, preset: int):
|
||||
if preset in self._preset_names:
|
||||
self._preset = preset
|
||||
|
||||
def getPreset(self) -> int:
|
||||
return self._preset
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"PresetReverb(preset={self._preset_names.get(self._preset, 'Unknown')})"
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# EnvironmentalReverb
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class EnvironmentalReverb(AudioEffect):
|
||||
"""EnvironmentalReverb — 环境混响"""
|
||||
|
||||
def __init__(self, priority: int = 0, audioSession: int = 0):
|
||||
super().__init__("EnvironmentalReverb", priority, audioSession)
|
||||
self._decay_time = 1500
|
||||
self._decay_hf_ratio = 500
|
||||
self._density = 500
|
||||
self._diffusion = 500
|
||||
self._reverb_level = 0
|
||||
self._room_level = 0
|
||||
self._room_hf_level = 0
|
||||
self._reflections_delay = 20
|
||||
self._reflections_level = -500
|
||||
self._reverb_delay = 40
|
||||
|
||||
def setDecayTime(self, decayTime: int):
|
||||
self._decay_time = decayTime
|
||||
|
||||
def getDecayTime(self) -> int:
|
||||
return self._decay_time
|
||||
|
||||
def setDecayHFRatio(self, decayHFRatio: int):
|
||||
self._decay_hf_ratio = decayHFRatio
|
||||
|
||||
def getDecayHFRatio(self) -> int:
|
||||
return self._decay_hf_ratio
|
||||
|
||||
def setDensity(self, density: int):
|
||||
self._density = density
|
||||
|
||||
def getDensity(self) -> int:
|
||||
return self._density
|
||||
|
||||
def setDiffusion(self, diffusion: int):
|
||||
self._diffusion = diffusion
|
||||
|
||||
def getDiffusion(self) -> int:
|
||||
return self._diffusion
|
||||
|
||||
def setReverbLevel(self, reverbLevel: int):
|
||||
self._reverb_level = reverbLevel
|
||||
|
||||
def getReverbLevel(self) -> int:
|
||||
return self._reverb_level
|
||||
|
||||
def setRoomLevel(self, roomLevel: int):
|
||||
self._room_level = roomLevel
|
||||
|
||||
def getRoomLevel(self) -> int:
|
||||
return self._room_level
|
||||
|
||||
def setRoomHFLevel(self, roomHFLevel: int):
|
||||
self._room_hf_level = roomHFLevel
|
||||
|
||||
def getRoomHFLevel(self) -> int:
|
||||
return self._room_hf_level
|
||||
|
||||
def setReflectionsDelay(self, reflectionsDelay: int):
|
||||
self._reflections_delay = reflectionsDelay
|
||||
|
||||
def getReflectionsDelay(self) -> int:
|
||||
return self._reflections_delay
|
||||
|
||||
def setReflectionsLevel(self, reflectionsLevel: int):
|
||||
self._reflections_level = reflectionsLevel
|
||||
|
||||
def getReflectionsLevel(self) -> int:
|
||||
return self._reflections_level
|
||||
|
||||
def setReverbDelay(self, reverbDelay: int):
|
||||
self._reverb_delay = reverbDelay
|
||||
|
||||
def getReverbDelay(self) -> int:
|
||||
return self._reverb_delay
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"EnvironmentalReverb(decayTime={self._decay_time}," \
|
||||
f" density={self._density})"
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# LoudnessEnhancer
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class LoudnessEnhancer(AudioEffect):
|
||||
"""LoudnessEnhancer — 响度增强器"""
|
||||
|
||||
PARAM_TARGET_GAIN_MB = 0
|
||||
|
||||
def __init__(self, audioSession: int = 0):
|
||||
super().__init__("LoudnessEnhancer", 0, audioSession)
|
||||
self._target_gain = 0
|
||||
|
||||
def setTargetGain(self, gainMillibels: int):
|
||||
self._target_gain = gainMillibels
|
||||
|
||||
def getTargetGain(self) -> int:
|
||||
return self._target_gain
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"LoudnessEnhancer(targetGain={self._target_gain} mB)"
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# DynamicsProcessing
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class DynamicsProcessing(AudioEffect):
|
||||
"""DynamicsProcessing — 动态处理"""
|
||||
|
||||
class Stage(Stub):
|
||||
"""DynamicsProcessing.Stage — 处理阶段"""
|
||||
|
||||
def __init__(self, enabled: bool = True):
|
||||
super().__init__()
|
||||
self._enabled = enabled
|
||||
self._in_use = True
|
||||
|
||||
def isEnabled(self) -> bool:
|
||||
return self._enabled
|
||||
|
||||
def setEnabled(self, enabled: bool):
|
||||
self._enabled = enabled
|
||||
|
||||
class EQBand(Stage):
|
||||
"""DynamicsProcessing.EQBand — EQ 频段"""
|
||||
|
||||
def __init__(self, enabled: bool = True):
|
||||
super().__init__(enabled)
|
||||
self._gain = 0.0
|
||||
self._center_freq = 1000.0
|
||||
|
||||
def setGain(self, gain: float):
|
||||
self._gain = gain
|
||||
|
||||
def getGain(self) -> float:
|
||||
return self._gain
|
||||
|
||||
def setCenterFreq(self, freq: float):
|
||||
self._center_freq = freq
|
||||
|
||||
def getCenterFreq(self) -> float:
|
||||
return self._center_freq
|
||||
|
||||
class EQ(Stage):
|
||||
"""DynamicsProcessing.EQ — 均衡器"""
|
||||
|
||||
def __init__(self, enabled: bool = True, bandCount: int = 6):
|
||||
super().__init__(enabled)
|
||||
self._bands = [EQBand() for _ in range(bandCount)]
|
||||
|
||||
def getBand(self, band: int) -> "DynamicsProcessing.EQBand":
|
||||
if 0 <= band < len(self._bands):
|
||||
return self._bands[band]
|
||||
raise IndexError(f"Band {band} out of range")
|
||||
|
||||
class MBCBand(Stage):
|
||||
"""DynamicsProcessing.MBCBand — 多频段压缩频段"""
|
||||
|
||||
def __init__(self, enabled: bool = True):
|
||||
super().__init__(enabled)
|
||||
self._gain = 0.0
|
||||
|
||||
def setGain(self, gain: float):
|
||||
self._gain = gain
|
||||
|
||||
def getGain(self) -> float:
|
||||
return self._gain
|
||||
|
||||
class MBC(Stage):
|
||||
"""DynamicsProcessing.MBC — 多频段压缩"""
|
||||
|
||||
def __init__(self, enabled: bool = True, bandCount: int = 6):
|
||||
super().__init__(enabled)
|
||||
self._bands = [MBCBand() for _ in range(bandCount)]
|
||||
|
||||
def getBand(self, band: int) -> "DynamicsProcessing.MBCBand":
|
||||
if 0 <= band < len(self._bands):
|
||||
return self._bands[band]
|
||||
raise IndexError(f"Band {band} out of range")
|
||||
|
||||
class Limiter(Stage):
|
||||
"""DynamicsProcessing.Limiter — 限制器"""
|
||||
|
||||
def __init__(self, enabled: bool = True):
|
||||
super().__init__(enabled)
|
||||
|
||||
class Channel(Stub):
|
||||
"""DynamicsProcessing.Channel — 处理通道"""
|
||||
|
||||
def __init__(self, stageCount: int = 1):
|
||||
super().__init__()
|
||||
self._stage_count = stageCount
|
||||
|
||||
class Config(Stub):
|
||||
"""DynamicsProcessing.Config — 处理配置"""
|
||||
|
||||
def __init__(self, channelCount: int = 1, preEqCount: int = 1,
|
||||
mbcCount: int = 1, postEqCount: int = 1,
|
||||
limiterCount: int = 1, prefEqBandCount: int = 6,
|
||||
postEqBandCount: int = 6, mbcBandCount: int = 6):
|
||||
super().__init__()
|
||||
self._channels = [DynamicsProcessing.Channel(0)
|
||||
for _ in range(channelCount)]
|
||||
|
||||
def __init__(self, audioSession: int = 0):
|
||||
super().__init__("DynamicsProcessing", 0, audioSession)
|
||||
self._channel_count = 1
|
||||
self._post_constraints: List[Any] = []
|
||||
self._pre_eqs: List[DynamicsProcessing.EQ] = [DynamicsProcessing.EQ()]
|
||||
self._post_eqs: List[DynamicsProcessing.EQ] = [DynamicsProcessing.EQ()]
|
||||
self._mbcs: List[DynamicsProcessing.MBC] = [DynamicsProcessing.MBC()]
|
||||
self._limiters: List[DynamicsProcessing.Limiter] = [DynamicsProcessing.Limiter()]
|
||||
self._mbands: List[Any] = []
|
||||
self._channel_stage: List[Any] = []
|
||||
|
||||
def getChannelCount(self) -> int:
|
||||
return self._channel_count
|
||||
|
||||
def getPostConstraints(self) -> List[Any]:
|
||||
return self._post_constraints
|
||||
|
||||
def getPreEQs(self) -> List[EQ]:
|
||||
return self._pre_eqs
|
||||
|
||||
def getMbands(self) -> List[Any]:
|
||||
return self._mbands
|
||||
|
||||
def getPostEQs(self) -> List[EQ]:
|
||||
return self._post_eqs
|
||||
|
||||
def getLimiters(self) -> List[Limiter]:
|
||||
return self._limiters
|
||||
|
||||
def getMbc(self) -> List[MBC]:
|
||||
return self._mbcs
|
||||
|
||||
def getChannelStage(self) -> List[Any]:
|
||||
return self._channel_stage
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"DynamicsProcessing(channels={self._channel_count})"
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# __all__
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
__all__ = [
|
||||
"AudioEffect",
|
||||
"Equalizer",
|
||||
"BassBoost",
|
||||
"Virtualizer",
|
||||
"PresetReverb",
|
||||
"EnvironmentalReverb",
|
||||
"LoudnessEnhancer",
|
||||
"DynamicsProcessing",
|
||||
]
|
||||
Reference in new issue
Block a user