Skip to content

Commit 1d357b7

Browse files
committed
webrtc test
1 parent 098fd85 commit 1d357b7

3 files changed

Lines changed: 294 additions & 2 deletions

File tree

.github/workflows/webrtc-test.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Build WebRTC Audio DSP for FFM
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
build:
8+
runs-on: windows-2022
9+
10+
steps:
11+
- name: Checkout repository
12+
uses: actions/checkout@v4
13+
14+
- name: Setup Python
15+
uses: actions/setup-python@v5
16+
with:
17+
python-version: '3.11'
18+
19+
- name: Install depot_tools
20+
shell: powershell
21+
run: |
22+
Invoke-WebRequest -Uri "https://storage.googleapis.com/chrome-infra/depot_tools.zip" -OutFile depot_tools.zip
23+
Expand-Archive -Path depot_tools.zip -DestinationPath depot_tools
24+
echo "$pwd\depot_tools" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
25+
echo "DEPOT_TOOLS_WIN_TOOLCHAIN=0" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
26+
27+
- name: Fetch WebRTC Source
28+
shell: cmd
29+
run: |
30+
mkdir webrtc_build
31+
cd webrtc_build
32+
fetch --nohooks webrtc
33+
cd src
34+
gclient sync
35+
36+
- name: Inject C Wrapper and GN Targets
37+
run: |
38+
# 假设你的 ipynb 脚本保存在仓库根目录下的 scripts 文件夹中
39+
# 如果你更倾向于直接将 ipynb 转换为 py 运行,可以在此处使用 jupyter-nbconvert
40+
pip install nbconvert
41+
jupyter nbconvert --to script scripts/generate_webrtc_wrapper.ipynb
42+
python scripts/generate_webrtc_wrapper.py
43+
working-directory: ${{ github.workspace }}
44+
45+
- name: Compile WebRTC DLL
46+
shell: cmd
47+
run: |
48+
cd webrtc_build\src
49+
50+
set GN_ARGS=target_os="win" is_debug=false is_component_build=false rtc_include_tests=false rtc_build_examples=false rtc_build_tools=false rtc_enable_video=false rtc_enable_protobuf=false rtc_use_x11=false rtc_include_ilbc=false rtc_include_opus=false rtc_include_internal_audio_device=false
51+
52+
call gn gen out/Release "--args=%GN_ARGS%"
53+
call ninja -C out/Release webrtc_ffm
54+
55+
- name: Upload Output Artifacts
56+
uses: actions/upload-artifact@v4
57+
with:
58+
name: webrtc-ffm-windows
59+
path: |
60+
webrtc_build/src/out/Release/webrtc_ffm.dll
61+
webrtc_build/src/ffm_wrapper/webrtc_ffm.h
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
{
2+
"cells": [
3+
{
4+
"metadata": {},
5+
"cell_type": "code",
6+
"outputs": [],
7+
"execution_count": null,
8+
"source": [
9+
"import os\n",
10+
"import textwrap\n",
11+
"\n",
12+
"webrtc_src_dir = os.path.join(os.getcwd(), \"webrtc_build\", \"src\")\n",
13+
"wrapper_dir = os.path.join(webrtc_src_dir, \"ffm_wrapper\")\n",
14+
"os.makedirs(wrapper_dir, exist_ok=True)"
15+
],
16+
"id": "a19f8ef83a0c06ac"
17+
},
18+
{
19+
"metadata": {},
20+
"cell_type": "code",
21+
"outputs": [],
22+
"execution_count": null,
23+
"source": [
24+
"header_content = textwrap.dedent(\"\"\"\\\n",
25+
" #pragma once\n",
26+
" #include <stdint.h>\n",
27+
" #include <stdbool.h>\n",
28+
"\n",
29+
" #if defined(_WIN32)\n",
30+
" #define FFM_EXPORT __declspec(dllexport)\n",
31+
" #else\n",
32+
" #define FFM_EXPORT\n",
33+
" #endif\n",
34+
"\n",
35+
" #ifdef __cplusplus\n",
36+
" extern \"C\" {\n",
37+
" #endif\n",
38+
"\n",
39+
" // --- Audio Processing ---\n",
40+
" typedef void* FFM_AudioProcessing;\n",
41+
" FFM_EXPORT FFM_AudioProcessing FFM_CreateAudioProcessing();\n",
42+
" FFM_EXPORT void FFM_FreeAudioProcessing(FFM_AudioProcessing apm);\n",
43+
" FFM_EXPORT void FFM_ApplyAudioProcessingConfig(FFM_AudioProcessing apm,\n",
44+
" bool ns_enabled, int ns_level,\n",
45+
" bool aec_enabled, bool aec_hp_filter,\n",
46+
" bool hp_enabled,\n",
47+
" bool gc_enabled, int gc_fixed_gain_db,\n",
48+
" bool agc_enabled, int agc_target_level, int agc_max_gain, int agc_max_noise, int agc_step);\n",
49+
" FFM_EXPORT void FFM_SetStreamDelayMs(FFM_AudioProcessing apm, int delay_ms);\n",
50+
" FFM_EXPORT int FFM_ProcessStream(FFM_AudioProcessing apm, const int16_t* src, int sample_rate_in, int channels, int16_t* dest);\n",
51+
"\n",
52+
" // --- VAD ---\n",
53+
" typedef void* FFM_Vad;\n",
54+
" FFM_EXPORT FFM_Vad FFM_CreateVad();\n",
55+
" FFM_EXPORT void FFM_FreeVad(FFM_Vad vad);\n",
56+
" FFM_EXPORT int FFM_InitVad(FFM_Vad vad);\n",
57+
" FFM_EXPORT int FFM_SetVadMode(FFM_Vad vad, int mode);\n",
58+
" FFM_EXPORT int FFM_ProcessVad(FFM_Vad vad, int sample_rate, const int16_t* audio_frame, size_t frame_length);\n",
59+
"\n",
60+
" // --- Resampler ---\n",
61+
" typedef void* FFM_Resampler;\n",
62+
" FFM_EXPORT FFM_Resampler FFM_CreateResampler();\n",
63+
" FFM_EXPORT void FFM_FreeResampler(FFM_Resampler resampler);\n",
64+
" FFM_EXPORT int FFM_Resample(FFM_Resampler resampler, const int16_t* src, size_t src_length, int src_rate, int16_t* dest, size_t dest_capacity, int dest_rate, int channels);\n",
65+
"\n",
66+
" #ifdef __cplusplus\n",
67+
" }\n",
68+
" #endif\n",
69+
" \"\"\")\n",
70+
"\n",
71+
"with open(os.path.join(wrapper_dir, \"webrtc_ffm.h\"), \"w\") as f:\n",
72+
" f.write(header_content)"
73+
],
74+
"id": "bbaaff7bf07c53c"
75+
},
76+
{
77+
"metadata": {},
78+
"cell_type": "code",
79+
"outputs": [],
80+
"execution_count": null,
81+
"source": [
82+
"cpp_content = textwrap.dedent(\"\"\"\\\n",
83+
" #include \"webrtc_ffm.h\"\n",
84+
" #include \"modules/audio_processing/include/audio_processing.h\"\n",
85+
" #include \"common_audio/vad/include/webrtc_vad.h\"\n",
86+
" #include \"common_audio/resampler/include/push_resampler.h\"\n",
87+
" #include \"api/audio/audio_frame.h\"\n",
88+
"\n",
89+
" using namespace webrtc;\n",
90+
"\n",
91+
" extern \"C\" {\n",
92+
"\n",
93+
" FFM_AudioProcessing FFM_CreateAudioProcessing() {\n",
94+
" rtc::scoped_refptr<AudioProcessing> apm = AudioProcessingBuilder().Create();\n",
95+
" apm->AddRef();\n",
96+
" return apm.get();\n",
97+
" }\n",
98+
"\n",
99+
" void FFM_FreeAudioProcessing(FFM_AudioProcessing apm) {\n",
100+
" if (apm) {\n",
101+
" static_cast<AudioProcessing*>(apm)->Release();\n",
102+
" }\n",
103+
" }\n",
104+
"\n",
105+
" void FFM_ApplyAudioProcessingConfig(FFM_AudioProcessing apm,\n",
106+
" bool ns_enabled, int ns_level,\n",
107+
" bool aec_enabled, bool aec_hp_filter,\n",
108+
" bool hp_enabled,\n",
109+
" bool gc_enabled, int gc_fixed_gain_db,\n",
110+
" bool agc_enabled, int agc_target_level, int agc_max_gain, int agc_max_noise, int agc_step) {\n",
111+
"\n",
112+
" AudioProcessing* ap = static_cast<AudioProcessing*>(apm);\n",
113+
" AudioProcessing::Config config = ap->GetConfig();\n",
114+
"\n",
115+
" config.noise_suppression.enabled = ns_enabled;\n",
116+
" config.noise_suppression.level = static_cast<AudioProcessing::Config::NoiseSuppression::Level>(ns_level);\n",
117+
"\n",
118+
" config.echo_canceller.enabled = aec_enabled;\n",
119+
" config.echo_canceller.enforce_high_pass_filtering = aec_hp_filter;\n",
120+
"\n",
121+
" config.high_pass_filter.enabled = hp_enabled;\n",
122+
"\n",
123+
" config.gain_controller1.enabled = gc_enabled || agc_enabled;\n",
124+
" if (gc_enabled && !agc_enabled) {\n",
125+
" config.gain_controller1.mode = AudioProcessing::Config::GainController1::kFixedDigital;\n",
126+
" } else if (agc_enabled) {\n",
127+
" config.gain_controller1.mode = AudioProcessing::Config::GainController1::kAdaptiveDigital;\n",
128+
" }\n",
129+
"\n",
130+
" ap->ApplyConfig(config);\n",
131+
" }\n",
132+
"\n",
133+
" void FFM_SetStreamDelayMs(FFM_AudioProcessing apm, int delay_ms) {\n",
134+
" static_cast<AudioProcessing*>(apm)->set_stream_delay_ms(delay_ms);\n",
135+
" }\n",
136+
"\n",
137+
" int FFM_ProcessStream(FFM_AudioProcessing apm, const int16_t* src, int sample_rate_in, int channels, int16_t* dest) {\n",
138+
" AudioProcessing* ap = static_cast<AudioProcessing*>(apm);\n",
139+
" StreamConfig config(sample_rate_in, channels);\n",
140+
" memcpy(dest, src, config.num_frames() * channels * sizeof(int16_t));\n",
141+
" return ap->ProcessStream(dest, config, config, dest);\n",
142+
" }\n",
143+
"\n",
144+
" FFM_Vad FFM_CreateVad() {\n",
145+
" VadInst* vad = WebRtcVad_Create();\n",
146+
" return vad;\n",
147+
" }\n",
148+
"\n",
149+
" void FFM_FreeVad(FFM_Vad vad) {\n",
150+
" if (vad) WebRtcVad_Free(static_cast<VadInst*>(vad));\n",
151+
" }\n",
152+
"\n",
153+
" int FFM_InitVad(FFM_Vad vad) {\n",
154+
" return WebRtcVad_Init(static_cast<VadInst*>(vad));\n",
155+
" }\n",
156+
"\n",
157+
" int FFM_SetVadMode(FFM_Vad vad, int mode) {\n",
158+
" return WebRtcVad_set_mode(static_cast<VadInst*>(vad), mode);\n",
159+
" }\n",
160+
"\n",
161+
" int FFM_ProcessVad(FFM_Vad vad, int sample_rate, const int16_t* audio_frame, size_t frame_length) {\n",
162+
" return WebRtcVad_Process(static_cast<VadInst*>(vad), sample_rate, audio_frame, frame_length);\n",
163+
" }\n",
164+
"\n",
165+
" FFM_Resampler FFM_CreateResampler() {\n",
166+
" return new PushResampler<int16_t>();\n",
167+
" }\n",
168+
"\n",
169+
" void FFM_FreeResampler(FFM_Resampler resampler) {\n",
170+
" if (resampler) delete static_cast<PushResampler<int16_t>*>(resampler);\n",
171+
" }\n",
172+
"\n",
173+
" int FFM_Resample(FFM_Resampler resampler, const int16_t* src, size_t src_length, int src_rate, int16_t* dest, size_t dest_capacity, int dest_rate, int channels) {\n",
174+
" PushResampler<int16_t>* r = static_cast<PushResampler<int16_t>*>(resampler);\n",
175+
" r->InitializeIfNeeded(src_rate, dest_rate, channels);\n",
176+
" return r->Resample(src, src_length, dest, dest_capacity);\n",
177+
" }\n",
178+
"\n",
179+
" }\n",
180+
" \"\"\")\n",
181+
"\n",
182+
"with open(os.path.join(wrapper_dir, \"webrtc_ffm.cc\"), \"w\") as f:\n",
183+
" f.write(cpp_content)"
184+
],
185+
"id": "783ae2bb67b1ce1b"
186+
},
187+
{
188+
"metadata": {},
189+
"cell_type": "code",
190+
"outputs": [],
191+
"execution_count": null,
192+
"source": [
193+
"build_gn_content = textwrap.dedent(\"\"\"\\\n",
194+
" import(\"//webrtc.gni\")\n",
195+
"\n",
196+
" shared_library(\"webrtc_ffm\") {\n",
197+
" sources = [\n",
198+
" \"webrtc_ffm.cc\",\n",
199+
" \"webrtc_ffm.h\",\n",
200+
" ]\n",
201+
" deps = [\n",
202+
" \"//modules/audio_processing:audio_processing\",\n",
203+
" \"//common_audio:common_audio\",\n",
204+
" \"//api/audio:audio_frame_api\",\n",
205+
" ]\n",
206+
" }\n",
207+
" \"\"\")\n",
208+
"\n",
209+
"with open(os.path.join(wrapper_dir, \"BUILD.gn\"), \"w\") as f:\n",
210+
" f.write(build_gn_content)"
211+
],
212+
"id": "677e50857d1919b2"
213+
},
214+
{
215+
"metadata": {},
216+
"cell_type": "code",
217+
"outputs": [],
218+
"execution_count": null,
219+
"source": [
220+
"root_build_gn = os.path.join(webrtc_src_dir, \"BUILD.gn\")\n",
221+
"with open(root_build_gn, \"a\") as f:\n",
222+
" f.write(\"\\n\")\n",
223+
" f.write(\"group(\\\"ffm_build\\\") {\\n\")\n",
224+
" f.write(\" deps = [ \\\"//ffm_wrapper:webrtc_ffm\\\" ]\\n\")\n",
225+
" f.write(\"}\\n\")"
226+
],
227+
"id": "b855f25b3af90d3e"
228+
}
229+
],
230+
"metadata": {},
231+
"nbformat": 4,
232+
"nbformat_minor": 5
233+
}

src/main/java/cn/ussshenzhou/channel/audio/client/send/WebRTCHelper.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
import cn.ussshenzhou.channel.audio.Trigger;
77
import cn.ussshenzhou.channel.util.ModConstant;
88
import dev.onvoid.webrtc.media.audio.*;
9-
import net.minecraft.SharedConstants;
109

1110
import javax.annotation.Nullable;
12-
import java.nio.file.Path;
1311
import java.util.Arrays;
1412

1513
/**

0 commit comments

Comments
 (0)