Skip to content

Commit 3e4a874

Browse files
xgfd3tamworthHeZhengQingxuchunzhen
authored
Dev/4.4.0 (#390)
* [Android]Adapt to 4.4.0 sdk * [Android][Audio]Adapt to 4.4.0 sdk. * [Android][Compose]Adapt to 4.4.0 sdk. * [Android]1.add voiceAITuner config;2.add TransparentRendering case. * [Android]update sdk version in gradle config. * [Android][Audio]add voice AI Tuner config to VoiceEffects case. * [Windows]Adapt to 4.4.0. * [windows] add ai tuner config. * feat: upgrade sdk to 4.4.0 * feat: enable setup voice ai tuner * feat: add new case(transparent render) * fix: clean rtc when leave room * feat: add voice ai tuner to mac * ·fix: keycenter minor changes * [Android]Renew token service url. * feat: upgrade sdk to 4.4.0 * feat: enable setup voice ai tuner * feat: add new case(transparent render) * fix: clean rtc when leave room * feat: add voice ai tuner to mac * ·fix: keycenter minor changes * [FEAT] conditional import third party player in audio route * [iOS/Mac]Renew token service url. * fix: revert cert default value * fix: revert cert * fix: minor changes * fix: revert * fix: remove -ld_classic * [Android]fix tansparent rendering video bug. * [Android]update cpp include files. * [Android]TansparentRendering add encodeAlpha config and etc * [Android][Compose]perfect audio route. * [iOS][OC]fix metadata receive crash(NMS-21946). * [iOS]fix audio router player bug(NMS-21940). * [iOS]fix fusion CDN bug(NMS-21901). * [Mac]fix take multi snapshot bug(NMS-21934). * [iOS]update ci build. * [Mac]fix CustomVideoSourcePushMulti render bug(NMS-21932). * fix: pip dosent on iOS 15 * [Windows]remove adative render mode choice. * fix: custom video source crash fixed * fix: fix for main thread hang during exit in funstion cdn * [Android]fix sensetime beauty bug. * fix: download file completion crash fixed * [Android]update ci build script. * fix: compile fail * [Android]Add media player info display. * [Android]perfect extension sample and update head include files. * fix: custom video render fix ui freeze * fix: custom render fix freeze * fix: play samples fixed * [Android][Compose]rename audio basic case file name. * fix: rename class --------- Co-authored-by: wushengtao <[email protected]> Co-authored-by: HeZhengQing <[email protected]> Co-authored-by: xuchunzhen <[email protected]>
1 parent 3bb8292 commit 3e4a874

File tree

202 files changed

+11916
-2457
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

202 files changed

+11916
-2457
lines changed

Android/APIExample-Audio/app/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
apply plugin: 'com.android.application'
22

33
def localSdkPath= "${rootProject.projectDir.absolutePath}/../../sdk"
4-
def agoraSdkVersion = '4.3.2'
4+
def agoraSdkVersion = '4.4.0'
55

66
android {
77
compileSdkVersion 32

Android/APIExample-Audio/app/src/main/java/io/agora/api/example/examples/advanced/VoiceEffects.java

+37-26
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@
8989
import io.agora.rtc2.RtcEngineConfig;
9090
import io.agora.rtc2.proxy.LocalAccessPointConfiguration;
9191

92+
/**
93+
* The type Voice effects.
94+
*/
9295
@Example(
9396
index = 4,
9497
group = ADVANCED,
@@ -106,7 +109,7 @@ public class VoiceEffects extends BaseFragment implements View.OnClickListener,
106109
private EditText et_channel;
107110
private Button join;
108111
private Spinner audioProfile, audioScenario,
109-
chatBeautifier, timbreTransformation, voiceChanger, styleTransformation, roomAcoustics, pitchCorrection, _pitchModeOption, _pitchValueOption, voiceConversion, ainsMode,
112+
chatBeautifier, timbreTransformation, voiceChanger, styleTransformation, roomAcoustics, pitchCorrection, _pitchModeOption, _pitchValueOption, voiceConversion, ainsMode, voiceAITuner,
110113
customBandFreq, customReverbKey;
111114
private ViewGroup _voice3DLayout, _pitchModeLayout, _pitchValueLayout;
112115
private SeekBar _voice3DCircle, customPitch, customBandGain, customReverbValue, customVoiceFormant;
@@ -154,6 +157,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
154157
_pitchValueOption = view.findViewById(R.id.audio_pitch_value_option);
155158
voiceConversion = view.findViewById(R.id.audio_voice_conversion);
156159
ainsMode = view.findViewById(R.id.audio_ains_mode);
160+
voiceAITuner = view.findViewById(R.id.voice_ai_tuner);
157161

158162
chatBeautifier.setOnItemSelectedListener(this);
159163
timbreTransformation.setOnItemSelectedListener(this);
@@ -166,6 +170,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
166170
_pitchModeOption.setOnItemSelectedListener(this);
167171
_pitchValueOption.setOnItemSelectedListener(this);
168172
ainsMode.setOnItemSelectedListener(this);
173+
voiceAITuner.setOnItemSelectedListener(this);
169174

170175
// Customize Voice Effects Layout
171176
customPitch = view.findViewById(R.id.audio_custom_pitch); // engine.setLocalVoicePitch()
@@ -205,6 +210,7 @@ private void resetControlLayoutByJoined() {
205210
_pitchValueLayout.setVisibility(View.GONE);
206211
voiceConversion.setEnabled(joined);
207212
ainsMode.setEnabled(joined);
213+
voiceAITuner.setEnabled(joined);
208214

209215
customPitch.setEnabled(joined);
210216
customBandFreq.setEnabled(joined);
@@ -238,30 +244,30 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
238244
}
239245
try {
240246
RtcEngineConfig config = new RtcEngineConfig();
241-
/**
247+
/*
242248
* The context of Android Activity
243249
*/
244250
config.mContext = context.getApplicationContext();
245-
/**
251+
/*
246252
* The App ID issued to you by Agora. See <a href="https://docs.agora.io/en/Agora%20Platform/token#get-an-app-id"> How to get the App ID</a>
247253
*/
248254
config.mAppId = getString(R.string.agora_app_id);
249-
/** Sets the channel profile of the Agora RtcEngine.
255+
/* Sets the channel profile of the Agora RtcEngine.
250256
CHANNEL_PROFILE_COMMUNICATION(0): (Default) The Communication profile.
251257
Use this profile in one-on-one calls or group calls, where all users can talk freely.
252258
CHANNEL_PROFILE_LIVE_BROADCASTING(1): The Live-Broadcast profile. Users in a live-broadcast
253259
channel have a role as either broadcaster or audience. A broadcaster can both send and receive streams;
254260
an audience can only receive streams.*/
255261
config.mChannelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
256-
/**
262+
/*
257263
* IRtcEngineEventHandler is an abstract class providing default implementation.
258264
* The SDK uses this class to report to the app on SDK runtime events.
259265
*/
260266
config.mEventHandler = iRtcEngineEventHandler;
261267
config.mAudioScenario = Constants.AudioScenario.getValue(Constants.AudioScenario.DEFAULT);
262-
config.mAreaCode = ((MainApplication)getActivity().getApplication()).getGlobalSettings().getAreaCode();
268+
config.mAreaCode = ((MainApplication) getActivity().getApplication()).getGlobalSettings().getAreaCode();
263269
engine = RtcEngine.create(config);
264-
/**
270+
/*
265271
* This parameter is for reporting the usages of APIExample to agora background.
266272
* Generally, it is not necessary for you to set this parameter.
267273
*/
@@ -288,7 +294,7 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
288294
@Override
289295
public void onDestroy() {
290296
super.onDestroy();
291-
/**leaveChannel and Destroy the RtcEngine instance*/
297+
/*leaveChannel and Destroy the RtcEngine instance*/
292298
if (engine != null) {
293299
engine.leaveChannel();
294300
}
@@ -312,15 +318,14 @@ public void onClick(View v) {
312318
AndPermission.with(this).runtime().permission(
313319
Permission.Group.STORAGE,
314320
Permission.Group.MICROPHONE
315-
).onGranted(permissions ->
316-
{
321+
).onGranted(permissions -> {
317322
// Permissions Granted
318323
joinChannel(channelId);
319324
}).start();
320325
} else {
321326
joined = false;
322327
resetControlLayoutByJoined();
323-
/**After joining a channel, the user must call the leaveChannel method to end the
328+
/*After joining a channel, the user must call the leaveChannel method to end the
324329
* call before joining another channel. This method returns 0 if the user leaves the
325330
* channel and releases all resources related to the call. This method call is
326331
* asynchronous, and the user has not exited the channel when the method call returns.
@@ -389,21 +394,21 @@ private int getPitch2Value(String str) {
389394
* Users that input the same channel name join the same channel.
390395
*/
391396
private void joinChannel(String channelId) {
392-
/**In the demo, the default is to enter as the anchor.*/
397+
/*In the demo, the default is to enter as the anchor.*/
393398
engine.setClientRole(Constants.CLIENT_ROLE_BROADCASTER);
394399
// audio config
395400
engine.setAudioProfile(
396401
Constants.AudioProfile.getValue(Constants.AudioProfile.valueOf(audioProfile.getSelectedItem().toString())),
397402
Constants.AudioScenario.getValue(Constants.AudioScenario.valueOf(audioScenario.getSelectedItem().toString()))
398403
);
399404

400-
/**Please configure accessToken in the string_config file.
405+
/*Please configure accessToken in the string_config file.
401406
* A temporary token generated in Console. A temporary token is valid for 24 hours. For details, see
402407
* https://docs.agora.io/en/Agora%20Platform/token?platform=All%20Platforms#get-a-temporary-token
403408
* A token generated at the server. This applies to scenarios with high-security requirements. For details, see
404409
* https://docs.agora.io/en/cloud-recording/token_server_java?platform=Java*/
405410
TokenUtils.gen(requireContext(), channelId, 0, accessToken -> {
406-
/** Allows a user to join a channel.
411+
/* Allows a user to join a channel.
407412
if you do not specify the uid, we will generate the uid for you*/
408413

409414
ChannelMediaOptions option = new ChannelMediaOptions();
@@ -588,7 +593,7 @@ public void onItemSelected(AdapterView<?> parent, View view, int position, long
588593

589594
for (Spinner spinner : voiceBeautifierSpinner) {
590595
if (spinner != parent) {
591-
if(spinner.getSelectedItemPosition() != 0){
596+
if (spinner.getSelectedItemPosition() != 0) {
592597
spinner.setTag("reset");
593598
spinner.setSelection(0);
594599
}
@@ -605,33 +610,33 @@ public void onItemSelected(AdapterView<?> parent, View view, int position, long
605610

606611
for (Spinner spinner : audioEffectSpinner) {
607612
if (spinner != parent) {
608-
if(spinner.getSelectedItemPosition() != 0){
613+
if (spinner.getSelectedItemPosition() != 0) {
609614
spinner.setTag("reset");
610615
spinner.setSelection(0);
611616
}
612617
}
613618
}
614619

615-
_voice3DLayout.setVisibility(audioEffectPreset == ROOM_ACOUSTICS_3D_VOICE ? View.VISIBLE: View.GONE);
620+
_voice3DLayout.setVisibility(audioEffectPreset == ROOM_ACOUSTICS_3D_VOICE ? View.VISIBLE : View.GONE);
616621
_pitchModeLayout.setVisibility(audioEffectPreset == PITCH_CORRECTION ? View.VISIBLE : View.GONE);
617622
_pitchValueLayout.setVisibility(audioEffectPreset == PITCH_CORRECTION ? View.VISIBLE : View.GONE);
618623
return;
619624
}
620625

621-
if(parent == voiceConversion){
626+
if (parent == voiceConversion) {
622627
String item = parent.getSelectedItem().toString();
623628
engine.setVoiceConversionPreset(getVoiceConversionValue(item));
624629
return;
625630
}
626631

627632

628-
if(parent == _pitchModeOption || parent == _pitchValueOption){
633+
if (parent == _pitchModeOption || parent == _pitchValueOption) {
629634
int effectOption1 = getPitch1Value(_pitchModeOption.getSelectedItem().toString());
630635
int effectOption2 = getPitch2Value(_pitchValueOption.getSelectedItem().toString());
631636
engine.setAudioEffectParameters(PITCH_CORRECTION, effectOption1, effectOption2);
632637
}
633638

634-
if(parent == ainsMode){
639+
if (parent == ainsMode) {
635640
boolean enable = position > 0;
636641
/*
637642
The AI noise suppression modes:
@@ -644,6 +649,12 @@ public void onItemSelected(AdapterView<?> parent, View view, int position, long
644649
*/
645650
engine.setAINSMode(enable, position - 1);
646651
}
652+
653+
if (parent == voiceAITuner) {
654+
boolean enable = position > 0;
655+
String item = parent.getSelectedItem().toString();
656+
engine.enableVoiceAITuner(enable, enable ? Constants.VOICE_AI_TUNER_TYPE.valueOf(item) : Constants.VOICE_AI_TUNER_TYPE.VOICE_AI_TUNER_MATURE_MALE);
657+
}
647658
}
648659

649660
private int getVoiceConversionValue(String label) {
@@ -672,7 +683,7 @@ private int getVoiceConversionValue(String label) {
672683
return VOICE_CHANGER_DARTH_VADER;
673684
case "VOICE_CHANGER_IRON_LADY":
674685
return VOICE_CHANGER_IRON_LADY;
675-
case "VOICE_CHANGER_SHIN_CHAN":
686+
case "VOICE_CHANGER_SHIN_CHAN":
676687
return VOICE_CHANGER_SHIN_CHAN;
677688
case "VOICE_CHANGER_GIRLISH_MAN":
678689
return VOICE_CHANGER_GIRLISH_MAN;
@@ -807,11 +818,11 @@ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
807818
if (!fromUser) {
808819
return;
809820
}
810-
if(seekBar == _voice3DCircle){
821+
if (seekBar == _voice3DCircle) {
811822
int cicle = (int) (1 + 59 * progress * 1.0f / seekBar.getMax());
812823
// [1,60], 10 default
813824
engine.setAudioEffectParameters(ROOM_ACOUSTICS_3D_VOICE, cicle, 0);
814-
}else if(seekBar == customPitch){
825+
} else if (seekBar == customPitch) {
815826
double pitch = 0.5 + 1.5 * progress * 1.0f / seekBar.getMax();
816827
// pitch: [0.5,2.0], 1.0 default
817828
engine.setLocalVoicePitch(pitch);
@@ -827,11 +838,11 @@ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
827838
// AUDIO_REVERB_ROOM_SIZE(2):[0, 100] dB
828839
// AUDIO_REVERB_WET_DELAY(3):Wet signal, [0, 200] ms
829840
// AUDIO_REVERB_STRENGTH(4): [0, 100]
830-
if(reverbKey == Constants.AUDIO_REVERB_TYPE.AUDIO_REVERB_DRY_LEVEL || reverbKey == Constants.AUDIO_REVERB_TYPE.AUDIO_REVERB_WET_LEVEL){
841+
if (reverbKey == Constants.AUDIO_REVERB_TYPE.AUDIO_REVERB_DRY_LEVEL || reverbKey == Constants.AUDIO_REVERB_TYPE.AUDIO_REVERB_WET_LEVEL) {
831842
value = (int) (-20 + 30 * progress * 1.0f / seekBar.getMax());
832-
}else if(reverbKey == Constants.AUDIO_REVERB_TYPE.AUDIO_REVERB_WET_DELAY){
843+
} else if (reverbKey == Constants.AUDIO_REVERB_TYPE.AUDIO_REVERB_WET_DELAY) {
833844
value = (int) (200 * progress * 1.0f / seekBar.getMax());
834-
}else {
845+
} else {
835846
value = (int) (100 * progress * 1.0f / seekBar.getMax());
836847
}
837848
engine.setLocalVoiceReverb(reverbKey, value);

Android/APIExample-Audio/app/src/main/java/io/agora/api/example/utils/TokenUtils.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ private static void gen(String appId, String certificate, String channelName, in
8585
}
8686

8787
Request request = new Request.Builder()
88-
.url("https://test-toolbox.bj2.agoralab.co/v1/token/generate")
88+
.url("https://service.agora.io/toolbox-global/v1/token/generate")
8989
.addHeader("Content-Type", "application/json")
9090
.post(RequestBody.create(postBody.toString(), null))
9191
.build();

Android/APIExample-Audio/app/src/main/res/layout/fragment_voice_effects.xml

+23
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,29 @@
329329

330330
</LinearLayout>
331331

332+
<LinearLayout
333+
android:layout_width="match_parent"
334+
android:layout_height="wrap_content"
335+
android:layout_marginBottom="16dp"
336+
android:gravity="center_vertical">
337+
338+
<TextView
339+
android:layout_width="160dp"
340+
android:layout_height="wrap_content"
341+
android:layout_marginStart="16dp"
342+
android:text="Voice AI Tuner"
343+
android:textColor="@android:color/black" />
344+
345+
<androidx.appcompat.widget.AppCompatSpinner
346+
android:id="@+id/voice_ai_tuner"
347+
android:layout_width="match_parent"
348+
android:layout_height="wrap_content"
349+
android:layout_marginHorizontal="16dp"
350+
android:entries="@array/voice_ai_tuner"
351+
android:spinnerMode="dropdown" />
352+
353+
</LinearLayout>
354+
332355
<TextView
333356
android:layout_width="match_parent"
334357
android:layout_height="wrap_content"

Android/APIExample-Audio/app/src/main/res/values/arrays.xml

+14
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,18 @@
149149
<item>AINS_MODE_AGGRESSIVE</item>
150150
<item>AINS_MODE_ULTRALOWLATENCY</item>
151151
</string-array>
152+
153+
<string-array name="voice_ai_tuner">
154+
<item>OFF</item>
155+
<item>VOICE_AI_TUNER_MATURE_MALE</item>
156+
<item>VOICE_AI_TUNER_FRESH_MALE</item>
157+
<item>VOICE_AI_TUNER_ELEGANT_FEMALE</item>
158+
<item>VOICE_AI_TUNER_SWEET_FEMALE</item>
159+
<item>VOICE_AI_TUNER_WARM_MALE_SINGING</item>
160+
<item>VOICE_AI_TUNER_GENTLE_FEMALE_SINGING</item>
161+
<item>VOICE_AI_TUNER_HUSKY_MALE_SINGING</item>
162+
<item>VOICE_AI_TUNER_WARM_ELEGANT_FEMALE_SINGING</item>
163+
<item>VOICE_AI_TUNER_POWERFUL_MALE_SINGING</item>
164+
<item>VOICE_AI_TUNER_DREAMY_FEMALE_SINGING</item>
165+
</string-array>
152166
</resources>

Android/APIExample-Audio/cloud_build.sh

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
# cache gradle to /tmp/.gradle
44
ls ~/.gradle || (mkdir -p /tmp/.gradle && ln -s /tmp/.gradle ~/.gradle && touch ~/.gradle/ln_$(date "+%y%m%d%H") && ls ~/.gradle)
55

6+
#change android maven to china repos
7+
sed -ie "s#google()#maven { url \"https\://maven.aliyun.com/repository/public\" }\n google()#g" settings.gradle
8+
sed -ie "s#https://services.gradle.org/distributions#https://mirrors.cloud.tencent.com/gradle#g" gradle/wrapper/gradle-wrapper.properties
9+
610
## config appId
711
sed -i -e "s#YOUR APP ID#${APP_ID}#g" app/src/main/res/values/string_configs.xml
812
sed -i -e "s#YOUR APP CERTIFICATE##g" app/src/main/res/values/string_configs.xml

Android/APIExample-Compose/app/src/main/java/io/agora/api/example/compose/samples/CustomVideoRender.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,8 @@ class CustomVideoRenderRender(
285285
0,
286286
0,
287287
viewportWidth,
288-
viewportHeight
288+
viewportHeight,
289+
0
289290
)
290291
} catch (exception: NullPointerException) {
291292
Log.e(TAG, "skip empty buffer!")

0 commit comments

Comments
 (0)