Audio code structure

本文详细介绍了在用户空间和内核空间中音频相关代码的目录路径,包括HAL实现、TinyAlsa、QTI OMX组件、Stagefright、nuPlayer、AudioFlinger、ACDB驱动、蓝牙A2DP、USB音频等关键部分。

Audio code structure

 

1.User space audio code

 

The following is a list of directory paths in the user space where the code related to audio is located for the debugging and customization:

 

<APSS_BUILD>/hardware/qcom/audio/hal/msm8974 – Contains the audio Hardware Abstraction Layer (HAL)-related code

 

<APSS_BUILD>/external/tinyalsa/ – Contains the code related to tinymix, tinyplay, and tinycap

 

<APSS_BUILD>/hardware/qcom/audio/mm-audio – Contains the implementation of QTI OMX components for the audio encoder and decoders

 

<APSS_BUILD>/frameworks/av/media/libstagefright/ – Contains the source code for Google’s Stagefright implementation

 

<APSS_BUILD>/frameworks/av/media/libmediaplayerservice/nuplayer - Contains the source code for Google’s nuplayer implementation

 

<APSS_BUILD>/frameworks/av/services/audioflinger/ – Contains the source code for AudioFlinger that manages audio streams from the user space

 

<APSS_BUILD>/vendor/qcom/proprietary/mm-audio/ – Contains the code related to the Audio Calibration Database (ACDB) driver, parsers for DTS and AC3, surround sound, SVA, etc.

 

<APSS_BUILD>/external/bluetooth/bluedroid/ – Contains the code related to Bluetooth® (BT) A2DP used in a QTI platform

 

<APSS_BUILD>/external/bluetooth/bluedroid/audio_a2dp_hw/ – Contains the A2DP audio HAL implementation

 

<APSS_BUILD>/hardware/libhardware/modules/usbaudio/ – Contains the USB HAL implementation for a USB dock use case

 

<APSS_BUILD>/hardware/qcom/audio/hal/audio_extn/:

 

audio_extn.c – Implements the wrapper function for audio extension features, such as FM, Dolby, Compress capture, HFP, SVA (listen), speaker protection, SSR, USB audio over headset

 

usb.c – Contains the HAL implementation for USB playback and record over the headset

 

compress_capture.c – Contains the HAL implementation for Compress capture

 

dolby.c – Contains the HAL implementation for the Dolby postprocessing feature

 

fm.c – Contains the HAL implementation for the FM playback and recording feature

 

hfp.c – Contains the HAL implementation for the hands-free profile feature where the MSM™ chipset can be used as as a BT headset device

 

listen.c – Contains the HAL implementation for the Snapdragon™ Voice Activation (SVA) feature

 

spkr_protection.c – Contains the HAL implementation for the speaker protection feature

 

ssr.c – Contains the HAL implementation for the surround sound recording feature

 

<APSS_BUILD>/vendor/qcom/proprietary/wfd/mm/source/framework/src/ – Contains the Wi-Fi Display (WFD) frameworks-related code; WFDMMSourceAudioSource.cpp configures the RT Proxy port via ALSA APIs and gets the PCM data from the audio layer

 

<APSS_BUILD>/system/core/include/system/ – Contains audio.h and audio_policy.h that contain enum definitions and inline functions used all over the code for audio in the user space

 

<APSS_BUILD>/frameworks/base/media/java/android/media/ – Contains .java files for audio that expose APIs that can be called by Android™ applications written in Java

 

2.Kernel space audio code

 

The following is a list of directory paths in the kernel where the code related to audio is located for debugging and customization:

 

<APSS_BUILD>/kernel/sound/soc/msm/ – Contains the msm8994.c machine driver

 

<APSS_BUILD>/kernel/sound/soc/msm/qdsp6v2 – Contains the source code for the platform drivers, Frontend (FE), and Backend (BE) DAI driver, QDSP drivers for AFE, ADM, and ASM, voice driver, etc.

 

<APSS_BUILD>/kernel/sound/soc/soc-*.c – All the soc-*.c files provide information on the ALSA SOC framework

 

<APSS_BUILD>/kernel/drivers/slimbus/ – Contains the source for the SLIMbus driver

 

<APSS_BUILD>/kernel/arch/arm/mach-msm/qdsp6v2/ – Contains the drivers for DSP-based encoders and decoders, code for the ADSP loader, APR driver, Ion memory driver, and other utility files

 

<APSS_BUILD>//LINUX/android/kernel/arch/arm/boot/dts – Contains msm8994-*.dtsi files that contain MSM8994-specific information;board-specific information on the MSM8994;GPIO management ; audio-related customization is available in files such as msm8994.dtsi, msm8994-mtp.dtsi, and msm8994-cdp.dtsi

 

<APSS_BUILD>/LINUX/android//kernel/sound/soc/codecs/ – Contains the source code for the codec driver for WCD9330; codec driver-related source files are wcd9330.c, wcd9xxx-mbhc.c, wcd9xxx-resmgr.c, wcd9xxx-common.c, etc.

 

<APSS_BUILD>//LINUX/android/kernel/drivers/mfd/ – Contains the source code for the codec driver; wcd9xxx-core.c, wcd9xxx-slimslave.c, and wcd9xxx-irq.c are the codec driver-related files

function varargout = gui(varargin) % GUI MATLAB code for gui.fig % GUI, by itself, creates a new GUI or raises the existing % singleton*. % % H = GUI returns the handle to a new GUI or the handle to % the existing singleton*. % % GUI('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in GUI.M with the given input arguments. % % GUI('Property','Value',...) creates a new GUI or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before gui_OpeningFcn gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to gui_OpeningFcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES % Edit the above text to modify the response to help gui % Last Modified by GUIDE v2.5 11-May-2025 14:47:23 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @gui_OpeningFcn, ... 'gui_OutputFcn', @gui_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT end % --- Executes just before gui is made visible. function gui_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to gui (see VARARGIN) % Choose default command line output for gui handles.output = hObject; % Update handles structure guidata(hObject, handles); % UIWAIT makes gui wait for user response (see UIRESUME) % uiwait(handles.figure1); end % --- Outputs from this function are returned to the command line. function varargout = gui_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure varargout{1} = handles.output; end %选择音频文件 % --- Executes on button press in pushbutton1. function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) [filename, pathname] = uigetfile('*.wav','选择音频文件'); if isequal(filename,0) || isequal(pathname,0) return; end handles.fpath = fullfile(pathname, filename); [orig_voice, fs] = audioread(handles.fpath); % 统一采样率为16kHz target_fs = 16000; if fs ~= target_fs orig_voice = resample(orig_voice, target_fs, fs); fs = target_fs; end handles.audio_data = orig_voice(:,1); % 强制单声道 handles.fs = fs; % 显示原始信号 axes(handles.axes1); plot((0:length(handles.audio_data)-1)/fs, handles.audio_data); title('原始信号时域波形'); % 显示原始频谱 N = 4096; yf = abs(fft(handles.audio_data, N)); f = (0:N-1)*fs/N; axes(handles.axes2); plot(f(1:N/2), yf(1:N/2)); title('原始信号频谱'); xlabel('频率 (Hz)'); guidata(hObject, handles); end %男变女 % --- Executes on button press in pushbutton2. function pushbutton2_Callback(hObject, eventdata, handles) % hObject handle to pushbutton2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) if ~isfield(handles, 'audio_data') errordlg('请先选择音频文件','错误'); return; end synth_voice = pitch_shift(handles.audio_data, handles.fs, 5, 1.2, [200 2800]); update_plots(handles, synth_voice); sound(synth_voice, handles.fs); end %女变男 % --- Executes on button press in pushbutton3. function pushbutton3_Callback(hObject, eventdata, handles) % hObject handle to pushbutton3 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) if ~isfield(handles, 'audio_data') errordlg('请先选择音频文件','错误'); return; end synth_voice = pitch_shift(handles.audio_data, handles.fs, -5, 0.8, [80 2200]); update_plots(handles, synth_voice); sound(synth_voice, handles.fs); end %变童声 % --- Executes on button press in pushbutton4. function pushbutton4_Callback(hObject, eventdata, handles) % hObject handle to pushbutton4 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) if ~isfield(handles, 'audio_data') errordlg('请先选择音频文件','错误'); return; end synth_voice = pitch_shift(handles.audio_data, handles.fs, 7, 1.5, [300 3500]); update_plots(handles, synth_voice); sound(synth_voice, handles.fs); end % === 核心算法函数 === function synth_voice = pitch_shift(orig_voice, fs, semitones, formant_scale, formant_range) % 参数校验 orig_voice = orig_voice(:); % 强制列向量 orig_voice = orig_voice / max(abs(orig_voice)); % 归一化 % 第一阶段:音高调整 shift_ratio = 2^(semitones/12); synth_voice = phase_vocoder(orig_voice, fs, shift_ratio); % 第二阶段:共振峰调整 synth_voice = formant_shift(synth_voice, fs, formant_scale, formant_range); % 后处理 synth_voice = synth_voice(1:length(orig_voice)); synth_voice = synth_voice / max(abs(synth_voice)); end function y = phase_vocoder(x, fs, shift_ratio) % 参数设置 frame_len = 2048; % 增加帧长提高频率分辨率 overlap = 0.75; % 75%重叠减少伪影 win = hann(frame_len, 'periodic'); hop_in = round(frame_len*(1-overlap)); hop_out = round(hop_in * shift_ratio); % 初始化 x = x(:); len_x = length(x); num_frames = floor((len_x - frame_len)/hop_in) + 1; y = zeros(ceil(len_x*shift_ratio) + frame_len, 1); % 相位处理变量 phase_accum = 0; prev_phase = 0; for n = 1:num_frames % 取帧加窗 start_idx = (n-1)*hop_in + 1; end_idx = start_idx + frame_len - 1; frame = x(start_idx:min(end_idx,len_x)) .* win; % FFT变换 fft_frame = fft(frame); mag = abs(fft_frame); phase = angle(fft_frame); % 相位差处理 delta_phase = phase - prev_phase; prev_phase = phase; % 去除期望相位增量 delta_phase = delta_phase - hop_in * 2*pi*(0:frame_len-1)'/frame_len; delta_phase = mod(delta_phase + pi, 2*pi) - pi; % 相位展开 % 计算瞬时频率 inst_freq = (2*pi*(0:frame_len-1)'/frame_len) + (delta_phase/hop_in); % 更新相位累积 phase_accum = phase_accum + hop_out * inst_freq; % 重建信号 synth_fft = mag .* exp(1i*phase_accum); synth_frame = real(ifft(synth_fft)); % 重叠相加 start_y = (n-1)*hop_out + 1; end_y = start_y + frame_len - 1; y(start_y:end_y) = y(start_y:end_y) + synth_frame .* win; end % 裁剪输出 y = y(1:ceil(len_x*shift_ratio)); end function y = formant_shift(x, fs, scale, freq_range) % 设计共振峰滤波器 nyq = fs/2; center = mean(freq_range); bandwidth = diff(freq_range); % 计算新中心频率 new_center = center * scale; new_bandwidth = bandwidth * scale; % 设计带通滤波器 [b, a] = butter(4, [new_center - new_bandwidth/2, ... new_center + new_bandwidth/2]/nyq, 'bandpass'); % 应用滤波 y = filter(b, a, x); end % === 可视化更新函数 === function update_plots(handles, processed_voice) fs = handles.fs; % 时域波形 axes(handles.axes3); plot((0:length(processed_voice)-1)/fs, processed_voice); title('处理后时域波形'); % 频域频谱 N = 4096; yf = abs(fft(processed_voice, N)); f = (0:N-1)*fs/N; axes(handles.axes4); plot(f(1:N/2), yf(1:N/2)); title('处理后频谱'); xlabel('频率 (Hz)'); drawnow; end 目前该程序存在以下问题:1.原声在时域上被截断,后面一点点声音没有了;2.当选择的音频是男声时,无法使用女变男的按键,当原始音频是女声时,无法使用女变男的按键;3.变声效果还是很差。应该怎么修改代码
05-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值