Voice cloning Java SDK reference

Updated at:

Use the DashScope Java SDK to clone and manage Qwen-Audio-TTS/Qwen-Audio-Realtime/CosyVoice voices.

Service endpoint

The SDK uses the China (Beijing) endpoint by default. To switch to a different region, modify Constants.baseHttpApiUrl before initialization.

Note

  • API keys differ by region. Use the API key for the target region.
  • The region setting is global and affects all DashScope SDK API calls.

China (Beijing)

https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1

Replace {WorkspaceId} with your actual workspace ID.

Singapore

https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1

Replace {WorkspaceId} with your actual workspace ID.

ImportantAlibaba Cloud Model Studio has released workspace-specific domains for the China (Beijing) and Singapore regions. The new dedicated domains deliver superior performance and higher stability for inference requests. We recommend migrating to the new domains:

  • China (Beijing): from dashscope.aliyuncs.com to {WorkspaceId}.cn-beijing.maas.aliyuncs.com
  • Singapore: from dashscope-intl.aliyuncs.com to {WorkspaceId}.ap-southeast-1.maas.aliyuncs.com

VoiceEnrollmentService class

Package: com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentService

Purpose: Manage the lifecycle of Qwen-Audio-TTS, Qwen-Audio-Realtime, and CosyVoice cloned voices (create, query, update, and delete).

Constructor

public VoiceEnrollmentService(String apiKey)

Parameters:

ParameterTypeDescription

apiKey

String

API key

createVoice() - Create a voice

Method signature:

public Voice createVoice(String targetModel, String prefix, String url, VoiceEnrollmentParam customParam) throws NoApiKeyException, InputRequiredException

Parameters:

ParameterTypeRequiredDescription

targetModel

String

Yes

The target model that uses the voice. It must match the model used in subsequent requests with this voice; otherwise, the requests fail.

prefix

String

Yes

A prefix for the voice name. Only alphanumeric characters are allowed, with a maximum length of 10 characters. The resulting voice name follows this format: {target_model}-{prefix}-{unique_id}.

url

String

Yes

Reference audio for voice cloning. Accepts a publicly accessible URL or a Base64 Data URI, such as data:audio/wav;base64,....

customParam

VoiceEnrollmentParam

No

Custom parameters such as languageHints and maxPromptAudioLength.

Return value: A Voice object. Call getVoiceId() to retrieve the voice ID.

listVoice() - List voices

Method signature:

public Voice[] listVoice(String prefix, int pageIndex, int pageSize) throws NoApiKeyException, InputRequiredException

Parameters:

ParameterTypeRequiredDescription

prefix

String

No

Filters voices by name prefix.

pageIndex

int

No

Page index, starting from 0.

pageSize

int

No

Number of records per page.

Return value: A Voice[] array.

queryVoice() - Retrieve voice details

Method signature:

public Voice queryVoice(String voiceId) throws NoApiKeyException, InputRequiredException

Parameters:

ParameterTypeRequiredDescription

voiceId

String

Yes

The ID of the voice to retrieve.

Return value: A Voice object containing the voice details.

updateVoice() - Update a voice

Method signatures:

public void updateVoice(String voiceId, String url) throws NoApiKeyException, InputRequiredException
public void updateVoice(String voiceId, String url, VoiceEnrollmentParam customParam) throws NoApiKeyException, InputRequiredException

Parameters:

ParameterTypeRequiredDescription

voiceId

String

Yes

The voice ID to update.

url

String

Yes

New reference audio. Accepts a publicly accessible URL or a Base64 Data URI, such as data:audio/wav;base64,....

customParam

VoiceEnrollmentParam

No

Custom parameters.

deleteVoice() - Delete a voice

Method signature:

public void deleteVoice(String voiceId) throws NoApiKeyException, InputRequiredException

Parameters:

ParameterTypeRequiredDescription

voiceId

String

Yes

The voice ID to delete.

VoiceEnrollmentParam class

Package: com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentParam

Build parameter objects using the builder pattern.

MethodTypeDescription

model(String)

String

The voice cloning model. The value must be "voice-enrollment".

languageHints(List<String>)

List<String>

Helps the model identify the language of the sample audio to extract voice features more accurately and improve cloning quality. If the specified language doesn't match the actual audio language (for example, setting en when the audio is in Chinese), the system ignores this value and detects the language automatically.

This parameter is an array and must contain exactly one element.

NoteApplies to qwen-audio-3.1-tts-plus, qwen-audio-3.1-tts-flash, qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, qwen-audio-3.1-realtime-plus, qwen-audio-3.0-realtime-plus, qwen-audio-3.0-realtime-flash, cosyvoice-v3.5-plus, cosyvoice-v3.5-flash, cosyvoice-v3-plus, cosyvoice-v3-flash.

Click to view supported languages by model

  • qwen-audio-3.1-tts-plus, qwen-audio-3.1-tts-flash, qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, qwen-audio-3.1-realtime-plus, qwen-audio-3.0-realtime-plus, qwen-audio-3.0-realtime-flash:

    • zh: Chinese
    • en: English
    • fr: French
    • de: German
    • ja: Japanese
    • ko: Korean
    • ru: Russian
    • pt: Portuguese
    • th: Thai
    • id: Indonesian
    • vi: Vietnamese
    • it: Italian
    • es: Spanish
    • ms: Malaysian
    • fil: Filipino
    • ar: Arabic
  • cosyvoice-v3-plus:

    • zh: Chinese
    • en: English
    • fr: French
    • de: German
    • ja: Japanese
    • ko: Korean
    • ru: Russian
  • cosyvoice-v3.5-plus, cosyvoice-v3.5-flash, cosyvoice-v3-flash:

    • zh: Chinese
    • en: English
    • fr: French
    • de: German
    • ja: Japanese
    • ko: Korean
    • ru: Russian
    • pt: Portuguese
    • th: Thai
    • id: Indonesian
    • vi: Vietnamese

Default: ["zh"].

maxPromptAudioLength(Float)

Float

The maximum duration (in seconds) of the reference audio after preprocessing. Valid values: [3.0, 30.0].

Default: 10.0.

NoteApplies to qwen-audio-3.1-tts-plus, qwen-audio-3.1-tts-flash, qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, qwen-audio-3.1-realtime-plus, qwen-audio-3.0-realtime-plus, qwen-audio-3.0-realtime-flash, cosyvoice-v3.5-plus, cosyvoice-v3.5-flash, cosyvoice-v3-flash.

parameter(String, Object)

Object

Sets custom parameters, such as parameter("language_hints", Arrays.asList("en")), parameter("max_prompt_audio_length", 10.0f), parameter("enable_preprocess", false), and parameter("enable_volume_normalization", "false").

Additional parameters

ParameterTypeRequiredDescription

enable_preprocess

boolean

No

Whether to enable audio preprocessing (noise reduction, audio enhancement, and volume normalization). Enable this for recordings with background noise. Disable it for recordings in quiet environments to preserve the original voice characteristics.

Default: false.

NoteApplies to qwen-audio-3.1-tts-plus, qwen-audio-3.1-tts-flash, qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, qwen-audio-3.1-realtime-plus, qwen-audio-3.0-realtime-plus, qwen-audio-3.0-realtime-flash, cosyvoice-v3.5-plus, cosyvoice-v3.5-flash, cosyvoice-v3-flash.

enable_volume_normalization

String

No

Whether to normalize the volume of the sample audio used for voice cloning. Valid values are "true" and "false". When enabled, audio synthesized with the created voice may have a different volume than audio synthesized with a voice created with this parameter disabled. Default: "false".

Sample code

Create a voice

import com.alibaba.dashscope.audio.ttsv2.enrollment.Voice;
import com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentParam;
import com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentService;
import com.alibaba.dashscope.utils.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

public class Main {
    private static final Logger logger = LoggerFactory.getLogger(Main.class);

    public static void main(String[] args) {
        // The following uses the Singapore region. Replace {WorkspaceId} with your actual workspace ID. For other regions, modify the URL accordingly.
        Constants.baseHttpApiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
        String apiKey = System.getenv("DASHSCOPE_API_KEY");
        String targetModel = "qwen-audio-3.0-tts-flash";
        String prefix = "myvoice";
        String fileUrl = "https://your-audio-file-url";
        String cloneModelName = "voice-enrollment";

        try {
            VoiceEnrollmentService service = new VoiceEnrollmentService(apiKey);
            Voice myVoice = service.createVoice(
                    targetModel,
                    prefix,
                    fileUrl,
                    VoiceEnrollmentParam.builder()
                            .model(cloneModelName)
                            .parameter("language_hints", Arrays.asList("en"))
                            // .parameter("max_prompt_audio_length", 10.0f)
                            // .parameter("enable_preprocess", false)
                            // .parameter("enable_volume_normalization", "false")
                            .build());

            logger.info("Voice creation submitted. Request ID: {}", service.getLastRequestId());
            logger.info("Generated Voice ID: {}", myVoice.getVoiceId());
        } catch (Exception e) {
            logger.error("Failed to create voice", e);
        }
    }
}

For a local WAV file, add the following assignment inside the try block above, before calling createVoice. To update a voice, also pass the Data URI through the url parameter of updateVoice. Replace sample.wav with your local audio path.

fileUrl = "data:audio/wav;base64," + java.util.Base64.getEncoder().encodeToString(
        java.nio.file.Files.readAllBytes(java.nio.file.Paths.get("sample.wav")));

List voices

This example requires the third-party library com.google.gson.Gson.

import com.alibaba.dashscope.audio.ttsv2.enrollment.Voice;
import com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentService;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    public static String apiKey = System.getenv("DASHSCOPE_API_KEY");  // Replace with your API key if not using an environment variable
    private static String prefix = "myvoice"; // Replace with your actual value
    private static final Logger logger = LoggerFactory.getLogger(Main.class);

    public static void main(String[] args)
            throws NoApiKeyException, InputRequiredException {
        // The following uses the Singapore region. Replace {WorkspaceId} with your actual workspace ID. For other regions, modify the URL accordingly.
        Constants.baseHttpApiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
        VoiceEnrollmentService service = new VoiceEnrollmentService(apiKey);
        // List voices
        Voice[] voices = service.listVoice(prefix, 0, 10);
        logger.info("List successful. Request ID: {}", service.getLastRequestId());
        logger.info("Voices Details: {}", new Gson().toJson(voices));
    }
}

Retrieve a specific voice

This example requires the third-party library com.google.gson.Gson.

import com.alibaba.dashscope.audio.ttsv2.enrollment.Voice;
import com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentService;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    public static String apiKey = System.getenv("DASHSCOPE_API_KEY");  // Replace with your API key if not using an environment variable
    private static String voiceId = "qwen-audio-3.0-tts-flash-myvoice-xxx"; // Replace with your actual value
    private static final Logger logger = LoggerFactory.getLogger(Main.class);

    public static void main(String[] args)
            throws NoApiKeyException, InputRequiredException {
        // The following uses the Singapore region. Replace {WorkspaceId} with your actual workspace ID. For other regions, modify the URL accordingly.
        Constants.baseHttpApiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
        VoiceEnrollmentService service = new VoiceEnrollmentService(apiKey);
        Voice voice = service.queryVoice(voiceId);

        logger.info("Query successful. Request ID: {}", service.getLastRequestId());
        logger.info("Voice Details: {}", new Gson().toJson(voice));
    }
}

Update a voice

import com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentService;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    public static String apiKey = System.getenv("DASHSCOPE_API_KEY");  // Replace with your API key if not using an environment variable
    private static String fileUrl = "https://your-audio-file-url";  // Replace with your actual value
    private static String voiceId = "qwen-audio-3.0-tts-flash-myvoice-xxx"; // Replace with your actual value
    private static final Logger logger = LoggerFactory.getLogger(Main.class);

    public static void main(String[] args)
            throws NoApiKeyException, InputRequiredException {
        // The following uses the Singapore region. Replace {WorkspaceId} with your actual workspace ID. For other regions, modify the URL accordingly.
        Constants.baseHttpApiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
        VoiceEnrollmentService service = new VoiceEnrollmentService(apiKey);
        // Update the voice
        service.updateVoice(voiceId, fileUrl);
        logger.info("Update submitted. Request ID: {}", service.getLastRequestId());
    }
}

Delete a voice

import com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentService;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    public static String apiKey = System.getenv("DASHSCOPE_API_KEY");  // Replace with your API key if not using an environment variable
    private static String voiceId = "qwen-audio-3.0-tts-flash-myvoice-xxx"; // Replace with your actual value
    private static final Logger logger = LoggerFactory.getLogger(Main.class);

    public static void main(String[] args)
            throws NoApiKeyException, InputRequiredException {
        // The following uses the Singapore region. Replace {WorkspaceId} with your actual workspace ID. For other regions, modify the URL accordingly.
        Constants.baseHttpApiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1";
        VoiceEnrollmentService service = new VoiceEnrollmentService(apiKey);
        // Delete the voice
        service.deleteVoice(voiceId);
        logger.info("Deletion submitted. Request ID: {}", service.getLastRequestId());
    }
}