تولید نوشتار به گفتار (TTS) بااستفاده از Gemini API


می‌توانید از مدل نوشتار به گفتار Gemini بخواهید از پیام‌واره نوشتاری، خروجی گفتار (صدا) تولید کند. وقتی از Firebase AI Logic استفاده می‌کنید، می‌توانید این درخواست را مستقیماً از برنامه‌تان انجام دهید.

تولید نوشتار به گفتار (TTS) قابل‌کنترل است، یعنی شما نوشتار دقیق را برای ترکیب شدن به گفتار ارائه می‌دهید. همچنین می‌توانید از زبان طبیعی در پیام‌واره‌هایتان استفاده کنید تا سبک، لهجه، سرعت، و لحن برونداد صوتی را هدایت کنید. می‌توانید TTS را برعکس ترانویسی (گفتار به نوشتار) درنظر بگیرید.

این ویژگی بااستفاده از هریک از مدل‌های Gemini -tts دردسترس است که برای تولید گفتار با کیفیت بالا و تأخیر کم بهینه‌سازی شده‌اند.

با این قابلیت می‌توانید کارهایی ازاین‌قبیل انجام دهید:

  • داستان‌سرایی تعاملی: کتاب‌های صوتی یا بازی‌های نقش‌آفرینی فراگیر ایجاد کنید که در آن‌ها مدل صدا را برای شخصیت‌های مختلف تغییر می‌دهد یا لحن خود را (مانند پچ‌پچ کردن در حالت تعلیق یا خندیدن به یک جوک) برای مطابقت با روایت تطبیق می‌دهد.

  • یادگیری زبان: راهنماهای تلفظی بسازید که بتوانند نوشتار را با لهجه‌های منطقه‌ای خاص یا با سرعت‌های آهسته‌تر بخوانند تا به زبان‌آموزان در تمرین تلفظ‌های دشوار کمک کنند.

  • خوانندگان محتوای حساس به بافت: مقاله‌های خبری، دستورالعمل‌های آشپزی، یا پست‌های وبلاگ را با صدای بلند و بااستفاده از شخصیت صوتی و لحن احساسی متناسب با محتوا می‌خوانند (مثلاً لحن جدی برای اخبار فوری یا لحن گرم و صبورانه برای دستورالعمل‌های گام‌به‌گام آشپزی).

این راهنما نشان می‌دهد که چگونه می‌توان از ورودی نوشتاری با یک یا چند گوینده گفتار تولید کرد و چگونه می‌توان پاسخ صوتی را جاری‌سازی کرد.

پرش به کد برای تک‌گوینده پرش به کد برای چندگوینده پرش به کد برای پاسخ‌های جاری‌سازی‌شده

مقایسه بین TTS و Live API

هر دو مدل نوشتار به گفتار (TTS) و مدل‌های Live API مدل‌های تولید گفتار با تأخیر کم هستند که می‌توانند برای زبان‌ها و صداهای پاسخ مختلف پیکربندی شوند. بااین‌حال، این دو برای موارد استفاده بسیار متفاوتی به‌کار می‌روند.

  • تولید نوشتار به گفتار (TTS) یک تعامل یک‌سویه درخواست-پاسخ (ورودی نوشتار، خروجی صدا) است. این مدل برای سناریوهایی که نیاز به بازخوانی دقیق نوشتار ارائه‌شده با کنترل دقیق بر سبک و صدا دارند، مانند روایت پادکست، کتاب‌های صوتی، یا خواندن مقالات با صدای بلند، طراحی شده است.

  • نسل Live API از جاری‌سازی دوجهتی برای مکالمه‌های گفتاری هم‌زمان (ورودی گفتاری، خروجی گفتاری) پشتیبانی می‌کند. این مدل در بافت‌های مکالمه‌ای پویا که مدل تصمیم می‌گیرد چه گفتاری را برگرداند، عالی عمل می‌کند. توجه داشته باشید که جدیدترین مدل‌های Live API از ورودی ویدیو و تصویر نیز پشتیبانی می‌کنند.

قبل از شروع

روی ارائه‌دهنده Gemini API کلیک کنید تا محتوا و کد مختص ارائه‌دهنده را در این صفحه ببینید.

اگر قبلاً این کار را نکرده‌اید، راهنمای شروع به کار را تکمیل کنید که نحوه راه‌اندازی پروژه Firebase، اتصال برنامه به Firebase، افزودن کیت توسعه نرم‌افزار، مقداردهی اولیه سرویس پس‌بست برای ارائه‌دهنده Gemini API انتخابی، و ایجاد نمونه GenerativeModel را شرح می‌دهد.

برای آزمایش و تکرار کردن پیام‌واره‌هایتان، توصیه می‌کنیم از Google AI Studio استفاده کنید.

مدل‌هایی که از این قابلیت پشتیبانی می‌کنند

  • gemini-3.1-flash-tts-preview

تولید کردن گفتار از نوشتار

می‌توانید بااستفاده از مدل نوشتار به گفتار Gemini، از نوشتار ارائه‌شده گفتار تولید کنید.

تولید گفتار با یک گوینده

قبل‌از امتحان کردن این نمونه، بخش قبل‌از شروع این راهنما را تکمیل کنید تا پروژه و برنامه‌تان را راه‌اندازی کنید.
در آن بخش، روی دکمه‌ای برای ارائه‌دهنده انتخابی‌تان Gemini API نیز کلیک خواهید کرد تا محتوای مختص ارائه‌دهنده را در این صفحه ببینید.

می‌توانید مدل را پیکربندی کنید تا صدا را بااستفاده از یک صدا برونداد کند.

در GenerationConfig، موارد زیر را اضافه کنید:

با پیام‌واره نوشتاری‌تان با generateContent تماس بگیرید. مدل داده‌های صوتی PCM خام را در بخش‌های پاسخ برمی‌گرداند.

Swift


import FirebaseAILogic

// Initialize the Gemini Developer API backend service.
let ai = FirebaseAI.firebaseAI(backend: .googleAI())

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
let config = GenerationConfig(
  responseModalities: [.audio],
  speechConfig: SpeechConfig(voiceName: "Kore", languageCode: "en-US")
)

// Create a `GenerativeModel` instance with a model that supports speech generation.
let model = ai.generativeModel(
  modelName: "gemini-3.1-flash-tts-preview",
  generationConfig: config
)

// Provide a text prompt.
let prompt = "Say cheerfully: Have a wonderful day!"

// Call `generateContent` to generate the speech output based on your text prompt.
let response = try await model.generateContent(prompt)

// Extract the audio data and handle it for downstream use. For example:
for part in response.inlineDataParts {
  let data = part.data          // Raw PCM audio bytes (24kHz, 1 channel, 16-bit)
  let mimeType = part.mimeType  // for example: "audio/pcm"
  print("Received audio data with MIME type: \(mimeType)")

  // To play back raw PCM audio bytes, you'll need to write your own `playRawPcm` function.
  playRawPcm(data: data)
}

Kotlin

برای Kotlin، روش‌های موجود در این کیت توسعه نرم‌افزار توابع تعلیق هستند و باید از دامنه Coroutine فراخوانی شوند.

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
val config = generationConfig {
    responseModalities = listOf(ResponseModality.AUDIO)
    speechConfig = SpeechConfig(
        voice = Voice("Kore"),
        languageCode = "en-US"
    )
}

// Initialize the Gemini Developer API backend service.
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-3.1-flash-tts-preview",
        generationConfig = config
    )

// Provide a text prompt.
val prompt = "Say cheerfully: Have a wonderful day!"

// Call `generateContent` to generate the speech output based on your text prompt.
val response = model.generateContent(prompt)

// Extract the audio data and handle it for downstream use. For example:
val part = response.candidates.firstOrNull()?.content?.parts?.firstOrNull()
if (part is InlineDataPart) {
    val pcmData = part.inlineData  // Raw PCM bytes (24kHz, 1 channel, 16-bit)
    val mimeType = part.mimeType   // for example: "audio/pcm"

    // To play back PCM audio data, you'll need to write your own `playAudio` function.
    playAudio(pcmData)
}

Java

برای Java، روش‌های جاری‌سازی در این کیت توسعه نرم‌افزار نوع Publisher را از کتابخانه Reactive Streams برمی‌گرداند.

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
GenerationConfig config = new GenerationConfig.Builder()
    .setResponseModalities(Collections.singletonList(ResponseModality.AUDIO))
    .setSpeechConfig(new SpeechConfig(new Voice("Kore"), "en-US"))
    .build();

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
GenerativeModel ai = FirebaseAI.getInstance(GenerativeBackend.googleAI())
        .generativeModel("gemini-3.1-flash-tts-preview", config);

// Use the GenerativeModelFutures Java compatibility layer.
GenerativeModelFutures model = GenerativeModelFutures.from(ai);

// Provide a text prompt.
String prompt = "Say cheerfully: Have a wonderful day!";
Content content = new Content.Builder().addText(prompt).build();
Executor executor = Executors.newSingleThreadExecutor();

// Call `generateContent` to generate the speech output based on your text prompt.
// Extract the audio data and handle it for downstream use.
ListenableFuture<GenerateContentResponse> response = model.generateContent(content);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
    @Override
    public void onSuccess(GenerateContentResponse result) {
        Part part = result.getCandidates().get(0).getContent().getParts().get(0);
        if (part instanceof InlineDataPart) {
            byte[] pcmData = ((InlineDataPart) part).getInlineData();
            String mimeType = ((InlineDataPart) part).getMimeType();

            // To play back PCM audio data, you'll need to write your own `playAudio` function.
            playAudio(pcmData);
        }
    }

    @Override
    public void onFailure(Throwable t) {
        t.printStackTrace();
    }
}, executor);

Web


import { initializeApp } from "firebase/app";
import { getAI, getGenerativeModel, GoogleAIBackend, ResponseModality } from "firebase/ai";

// TODO(developer): Replace with your app's Firebase configuration
const firebaseConfig = { /* ... */ };
const firebaseApp = initializeApp(firebaseConfig);

// Initialize the Gemini Developer API backend service.
const ai = getAI(firebaseApp, { backend: new GoogleAIBackend() });

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
const generationConfig = {
  responseModalities: [ResponseModality.AUDIO],
  speechConfig: {
    voiceConfig: { prebuiltVoiceConfig: { voiceName: "Kore" } },
    languageCode: "en-US"
  }
};

// Create a `GenerativeModel` instance with a model that supports speech generation.
const model = getGenerativeModel(ai, {
  model: "gemini-3.1-flash-tts-preview",
  generationConfig
});

// Provide a text prompt.
const prompt = "Say cheerfully: Have a wonderful day!";

// Call `generateContent` to generate the speech output based on your text prompt.
const result = await model.generateContent(prompt);
const inlineDataParts = result.response.inlineDataParts();

// Extract the audio data and handle it for downstream use. For example:
if (inlineDataParts?.[0]) {
  const pcmBase64 = inlineDataParts[0].inlineData.data;
  // Decode base64 to ArrayBuffer
  const pcmBuffer = Uint8Array.from(atob(pcmBase64), c => c.charCodeAt(0)).buffer;

  // To play back a PCM buffer, you'll need to write your own `playAudio` function.
  playAudio(pcmBuffer);
}

Dart


import 'package:firebase_ai/firebase_ai.dart';

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
final config = GenerationConfig(
  responseModalities: [ResponseModalities.audio],
  speechConfig: SpeechConfig(voiceName: 'Kore', languageCode: 'en-US'),
);

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
final model = FirebaseAI.googleAI().generativeModel(
  model: 'gemini-3.1-flash-tts-preview',
  generationConfig: config,
);

// Provide a text prompt.
final prompt = 'Say cheerfully: Have a wonderful day!';

// Call `generateContent` to generate the speech output based on your text prompt.
final response = await model.generateContent([Content.text(prompt)]);

// Extract the audio data and handle it for downstream use. For example:
final part = response.candidates.first.content.parts.first;
if (part is InlineDataPart && part.mimeType.startsWith('audio/')) {
  final Uint8List pcmData = part.bytes;  // Raw PCM bytes (24kHz, 1 channel, 16-bit)

  // To play back PCM audio data, you'll need to write your own `playAudio` function.
  await playAudio(pcmData);
}

Unity


using Firebase.AI;

// Set `responseModalities` to include `Audio`.
// Configure a `SpeechConfig` with your chosen voice name and language code.
var config = new GenerationConfig(
  responseModalities: new System.Collections.Generic.List<ResponseModality> { ResponseModality.Audio },
  speechConfig: SpeechConfig.UsePrebuiltVoice("Kore", "en-US")
);

// Initialize the Gemini Developer API backend service.
var ai = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI());

// Create a `GenerativeModel` instance with a model that supports speech generation.
var model = ai.GetGenerativeModel(
  modelName: "gemini-3.1-flash-tts-preview",
  generationConfig: config
);

// Provide a text prompt.
var prompt = "Say cheerfully: Have a wonderful day!";

// Call `GenerateContentAsync` to generate the speech output based on your text prompt.
var response = await model.GenerateContentAsync(prompt);

// Extract the audio data and handle it for downstream use. For example:
if (response.Candidates.Count > 0) {
  foreach (var part in response.Candidates[0].Content.Parts) {
    if (part is ModelContent.InlineDataPart inlineData) {
      byte[] pcmData = inlineData.Data;  // Raw PCM bytes (24kHz, 1 channel, 16-bit)

      // To play back PCM audio data, you'll need to write your own `playAudio` function.
      playAudio(pcmData);
    }
  }
}

تولید گفتار با چند گوینده

قبل‌از امتحان کردن این نمونه، بخش قبل‌از شروع این راهنما را تکمیل کنید تا پروژه و برنامه‌تان را راه‌اندازی کنید.
در آن بخش، روی دکمه‌ای برای ارائه‌دهنده انتخابی‌تان Gemini API نیز کلیک خواهید کرد تا محتوای مختص ارائه‌دهنده را در این صفحه ببینید.

می‌توانید مدل را پیکربندی کنید تا از صداهای مختلف برای گویندگان مختلف در نوشتار استفاده کند. این ویژگی برای تولید صدا برای دیالوگ‌ها یا مکالمه‌ها مفید است.

  1. یک MultiSpeakerVoiceConfig ایجاد کنید که نام‌های گوینده (که در پیام‌واره‌تان استفاده خواهید کرد) را به نام‌های صدای پاسخ خاص (مثلاً Kore) نگاشت کند.

    پیکربندی چندگوینده دقیقاً از ۲ گوینده پشتیبانی می‌کند.

  2. در GenerationConfig، موارد زیر را اضافه کنید:

  3. در پیام‌واره، بااستفاده از نام گویندگان به‌عنوان پیشوند (برای مثال، Joe: Hello. Jane: Hi.)، مشخص کنید چه کسی صحبت می‌کند.

با پیام‌واره نوشتاری‌تان با generateContent تماس بگیرید. مدل داده‌های صوتی PCM خام را در بخش‌های پاسخ برمی‌گرداند.

Swift


import FirebaseAILogic

// Initialize the Gemini Developer API backend service.
let ai = FirebaseAI.firebaseAI(backend: .googleAI())

// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
let multiSpeechConfig = SpeechConfig(
  multiSpeakerVoiceConfig: MultiSpeakerVoiceConfig(
    speakerVoiceConfigs: [
      SpeakerVoiceConfig(speaker: "Joe", voiceName: "Puck"),
      SpeakerVoiceConfig(speaker: "Jane", voiceName: "Kore")
    ]
  ),
  languageCode: "en-US"
)

// Set `responseModalities` to include `audio`.
let config = GenerationConfig(
  responseModalities: [.audio],
  speechConfig: multiSpeechConfig
)

// Create a `GenerativeModel` instance with a model that supports speech generation.
let model = ai.generativeModel(
  modelName: "gemini-3.1-flash-tts-preview",
  generationConfig: config
)

// Provide a text prompt that includes the names of the speakers.
let prompt = """
Joe: How's it going today Jane?
Jane: Not too bad, how about you?
"""

// Call `generateContent` to generate the speech output based on your text prompt.
let response = try await model.generateContent(prompt)

// Extract the audio data and handle it for downstream use. For example:
for part in response.inlineDataParts {
  let data = part.data          // Raw PCM audio bytes (24kHz, 1 channel, 16-bit)
  let mimeType = part.mimeType  // for example: "audio/pcm"
  print("Received audio data with MIME type: \(mimeType)")

  // To play back raw PCM audio bytes, you'll need to write your own `playRawPcm` function.
  playRawPcm(data: data)
}

Kotlin

برای Kotlin، روش‌های موجود در این کیت توسعه نرم‌افزار توابع تعلیق هستند و باید از دامنه Coroutine فراخوانی شوند.

// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
val multiSpeechConfig = SpeechConfig(
    multiSpeakerVoiceConfig = MultiSpeakerVoiceConfig(
        speakerVoiceConfigs = listOf(
            SpeakerVoiceConfig(speaker = "Joe", voice = Voice("Puck")),
            SpeakerVoiceConfig(speaker = "Jane", voice = Voice("Kore"))
        )
    ),
    languageCode = "en-US"
)

// Set `responseModalities` to include `AUDIO`.
val config = generationConfig {
    responseModalities = listOf(ResponseModality.AUDIO)
    speechConfig = multiSpeechConfig
}

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-3.1-flash-tts-preview",
        generationConfig = config
    )

// Provide a text prompt that includes the names of the speakers.
val prompt = """
Joe: How's it going today Jane?
Jane: Not too bad, how about you?
"""

// Call `generateContent` to generate the speech output based on your text prompt.
val response = model.generateContent(prompt)

// Extract the audio data and handle it for downstream use. For example:
val part = response.candidates.firstOrNull()?.content?.parts?.firstOrNull()
if (part is InlineDataPart) {
    val pcmData = part.inlineData  // Raw PCM bytes (24kHz, 1 channel, 16-bit)
    val mimeType = part.mimeType   // for example: "audio/pcm"

    // To play back PCM audio data, you'll need to write your own `playAudio` function.
    playAudio(pcmData)
}

Java

برای Java، روش‌های جاری‌سازی در این کیت توسعه نرم‌افزار نوع Publisher را از کتابخانه Reactive Streams برمی‌گرداند.

// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
MultiSpeakerVoiceConfig multiSpeakerVoiceConfig = new MultiSpeakerVoiceConfig(
    Arrays.asList(
        new SpeakerVoiceConfig("Joe", new Voice("Puck")),
        new SpeakerVoiceConfig("Jane", new Voice("Kore"))
    )
);

SpeechConfig multiSpeechConfig = new SpeechConfig(multiSpeakerVoiceConfig);

// Set `responseModalities` to include `AUDIO`.
GenerationConfig config = new GenerationConfig.Builder()
    .setResponseModalities(Collections.singletonList(ResponseModality.AUDIO))
    .setSpeechConfig(multiSpeechConfig)
    .build();

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
GenerativeModel ai = FirebaseAI.getInstance(GenerativeBackend.googleAI())
         .generativeModel("gemini-3.1-flash-tts-preview", config);

GenerativeModelFutures model = GenerativeModelFutures.from(ai);

// Provide a text prompt that includes the names of the speakers.
String prompt = "Joe: How's it going today Jane?\nJane: Not too bad, how about you?";
Content content = new Content.Builder().addText(prompt).build();
Executor executor = Executors.newSingleThreadExecutor();

// Call `generateContent` to generate the speech output based on your text prompt.
// Extract the audio data and handle it for downstream use.
ListenableFuture<GenerateContentResponse> response = model.generateContent(content);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
    @Override
    public void onSuccess(GenerateContentResponse result) {
        Part part = result.getCandidates().get(0).getContent().getParts().get(0);
        if (part instanceof InlineDataPart) {
            byte[] pcmData = ((InlineDataPart) part).getInlineData();  // Raw PCM bytes (24kHz, 1 channel, 16-bit)
            String mimeType = ((InlineDataPart) part).getMimeType();   // for example: "audio/pcm"

            // To play back PCM audio data, you'll need to write your own `playAudio` function.
            playAudio(pcmData);
        }
    }

    @Override
    public void onFailure(Throwable t) {
        t.printStackTrace();
    }
}, executor);

Web


import { initializeApp } from "firebase/app";
import { getAI, getGenerativeModel, GoogleAIBackend, ResponseModality } from "firebase/ai";

// TODO(developer): Replace with your app's Firebase configuration
const firebaseConfig = { /* ... */ };
const firebaseApp = initializeApp(firebaseConfig);

// Initialize the Gemini Developer API backend service.
const ai = getAI(firebaseApp, { backend: new GoogleAIBackend() });

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
const generationConfig = {
  responseModalities: [ResponseModality.AUDIO],
  speechConfig: {
    multiSpeakerVoiceConfig: {
      speakerVoiceConfigs: [
        { speaker: "Joe", voiceConfig: { prebuiltVoiceConfig: { voiceName: "Puck" } } },
        { speaker: "Jane", voiceConfig: { prebuiltVoiceConfig: { voiceName: "Kore" } } }
      ]
    },
    languageCode: "en-US"
  }
};

// Create a `GenerativeModel` instance with a model that supports speech generation.
const model = getGenerativeModel(ai, {
  model: "gemini-3.1-flash-tts-preview",
  generationConfig
});

// Provide a text prompt that includes the names of the speakers.
const prompt = `
Joe: How's it going today Jane?
Jane: Not too bad, how about you?
`;

// Call `generateContent` to generate the speech output based on your text prompt.
const result = await model.generateContent(prompt);
const inlineDataParts = result.response.inlineDataParts();

// Extract the audio data and handle it for downstream use. For example:
if (inlineDataParts?.[0]) {
  const pcmBase64 = inlineDataParts[0].inlineData.data;  // Raw PCM bytes (24kHz, 1 channel, 16-bit)
  const pcmBuffer = Uint8Array.from(atob(pcmBase64), c => c.charCodeAt(0)).buffer;

  // To play back a PCM buffer, you'll need to write your own `playAudio` function.
  playAudio(pcmBuffer);
}

Dart


import 'package:firebase_ai/firebase_ai.dart';

// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
final multiSpeechConfig = SpeechConfig.multiSpeaker(
  multiSpeakerVoiceConfig: MultiSpeakerVoiceConfig(
    speakerVoiceConfigs: [
      SpeakerVoiceConfig(speaker: 'Joe', voiceName: 'Puck'),
      SpeakerVoiceConfig(speaker: 'Jane', voiceName: 'Kore'),
    ],
  ),
  languageCode: 'en-US',
);

// Set `responseModalities` to include `audio`.
final config = GenerationConfig(
  responseModalities: [ResponseModalities.audio],
  speechConfig: multiSpeechConfig,
);

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
final model = FirebaseAI.googleAI().generativeModel(
  model: 'gemini-3.1-flash-tts-preview',
  generationConfig: config,
);

// Provide a text prompt that includes the names of the speakers.
final prompt = '''
Joe: How's it going today Jane?
Jane: Not too bad, how about you?
''';

// Call `generateContent` to generate the speech output based on your text prompt.
final response = await model.generateContent([Content.text(prompt)]);

// Extract the audio data and handle it for downstream use. For example:
final part = response.candidates.first.content.parts.first;
if (part is InlineDataPart && part.mimeType.startsWith('audio/')) {
  final Uint8List pcmData = part.bytes;  // Raw PCM bytes (24kHz, 1 channel, 16-bit)

  // To play back PCM audio data, you'll need to write your own `playAudio` function.
  await playAudio(pcmData);
}

Unity


using Firebase.AI;

// Configure a `SpeechConfig` for multiple speakers, assigning a voice to each speaker.
var multiSpeakerVoiceConfig = new MultiSpeakerVoiceConfig(
  new System.Collections.Generic.List<SpeakerVoiceConfig> {
    SpeakerVoiceConfig.UsePrebuiltVoice("Joe", "Puck"),
    SpeakerVoiceConfig.UsePrebuiltVoice("Jane", "Kore")
  }
);

var multiSpeechConfig = SpeechConfig.UseMultiSpeakerVoice(multiSpeakerVoiceConfig);

// Set `responseModalities` to include `Audio`.
var config = new GenerationConfig(
  responseModalities: new System.Collections.Generic.List<ResponseModality> { ResponseModality.Audio },
  speechConfig: multiSpeechConfig
);

// Initialize the Gemini Developer API backend service.
var ai = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI());

// Create a `GenerativeModel` instance with a model that supports speech generation.
var model = ai.GetGenerativeModel(
  modelName: "gemini-3.1-flash-tts-preview",
  generationConfig: config
);

// Provide a text prompt that includes the names of the speakers.
var prompt = "Joe: How's it going today Jane?\nJane: Not too bad, how about you?";

// Call `GenerateContentAsync` to generate the speech output based on your text prompt.
var response = await model.GenerateContentAsync(prompt);

// Extract the audio data and handle it for downstream use. For example:
if (response.Candidates.Count > 0) {
  foreach (var part in response.Candidates[0].Content.Parts) {
    if (part is ModelContent.InlineDataPart inlineData) {
      byte[] pcmData = inlineData.Data;  // Raw PCM bytes (24kHz, 1 channel, 16-bit)

      // To play back PCM audio data, you'll need to write your own `playAudio` function.
      playAudio(pcmData);
    }
  }
}

جاری‌سازی پاسخ

قبل‌از امتحان کردن این نمونه، بخش قبل‌از شروع این راهنما را تکمیل کنید تا پروژه و برنامه‌تان را راه‌اندازی کنید.
در آن بخش، روی دکمه‌ای برای ارائه‌دهنده انتخابی‌تان Gemini API نیز کلیک خواهید کرد تا محتوای مختص ارائه‌دهنده را در این صفحه ببینید.

با جاری‌سازی پاسخ صوتی به‌محض تولید شدن، به‌جای منتظر ماندن برای تکمیل کل فایل صوتی، می‌توانید تعاملات سریع‌تر و تأخیر کمتری داشته باشید.

جاری‌سازی گفتار تولیدشده هم برای پیکربندی‌های تک‌گوینده و هم چندگوینده پشتیبانی می‌شود. این ویژگی فقط هنگام استفاده از مدل‌های Gemini 3.x TTS پشتیبانی می‌شود.

برای جاری‌سازی پاسخ گفتاری، به‌جای generateContent، با generateContentStream تماس بگیرید و تکه‌ها را به‌محض رسیدن مدیریت کنید. مثال‌های زیر نحوه جاری‌سازی پاسخ یک گوینده را نشان می‌دهد:

Swift


import FirebaseAILogic

// Initialize the Gemini Developer API backend service.
let ai = FirebaseAI.firebaseAI(backend: .googleAI())

// Set `responseModalities` to include `audio`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
let config = GenerationConfig(
  responseModalities: [.audio],
  speechConfig: SpeechConfig(voiceName: "Kore")
)

// Create a `GenerativeModel` instance with a model that supports speech generation.
let model = ai.generativeModel(
  modelName: "gemini-3.1-flash-tts-preview",
  generationConfig: config
)

// Provide a text prompt.
let prompt = "Tell me a story about a brave knight."

// Call `generateContentStream` to generate the speech output stream based on your text prompt.
let responseStream = try model.generateContentStream(prompt)

// Extract the audio data and handle it for downstream use. For example:
for try await chunk in responseStream {
  for part in chunk.inlineDataParts {
    let data = part.data          // Raw PCM audio bytes (24kHz, 1 channel, 16-bit)
    let mimeType = part.mimeType  // for example: "audio/pcm"

    // Append the audio chunk to your audio queue/buffer for playback.
    appendAudioChunk(data)
  }
}

Kotlin

برای Kotlin، روش‌های موجود در این کیت توسعه نرم‌افزار توابع تعلیق هستند و باید از دامنه Coroutine فراخوانی شوند.

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
val config = generationConfig {
    responseModalities = listOf(ResponseModality.AUDIO)
    speechConfig = SpeechConfig(voice = Voice("Kore"))
}

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-3.1-flash-tts-preview",
        generationConfig = config
    )

// Provide a text prompt.
val prompt = "Tell me a story about a brave knight."

// Call `generateContentStream` to generate the speech output stream based on your text prompt.
// Extract the audio data and handle it for downstream use.
model.generateContentStream(prompt).collect { chunk ->
    val part = chunk.candidates.firstOrNull()?.content?.parts?.firstOrNull()
    if (part is InlineDataPart) {
        val pcmChunk = part.inlineData  // Raw PCM bytes (24kHz, 1 channel, 16-bit)
        val mimeType = part.mimeType    // for example: "audio/pcm"

        // Append the audio chunk to your audio queue/buffer for playback.
        appendAudioChunk(pcmChunk)
    }
}

Java

برای Java، روش‌های جاری‌سازی در این کیت توسعه نرم‌افزار نوع Publisher را از کتابخانه Reactive Streams برمی‌گرداند.

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
GenerationConfig config = new GenerationConfig.Builder()
    .setResponseModalities(Collections.singletonList(ResponseModality.AUDIO))
    .setSpeechConfig(new SpeechConfig(new Voice("Kore")))
    .build();

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
GenerativeModel ai = FirebaseAI.getInstance(GenerativeBackend.googleAI())
        .generativeModel("gemini-3.1-flash-tts-preview", config);

GenerativeModelFutures model = GenerativeModelFutures.from(ai);

// Provide a text prompt.
String prompt = "Tell me a story about a brave knight.";
Content content = new Content.Builder().addText(prompt).build();

// Call `generateContentStream` to generate the speech output stream based on your text prompt.
Publisher<GenerateContentResponse> streamingResponse =
    model.generateContentStream(content);

// Extract the audio data and handle it for downstream use.
streamingResponse.subscribe(new Subscriber<GenerateContentResponse>() {
  @Override
  public void onSubscribe(Subscription s) {
      s.request(Long.MAX_VALUE);
  }

  @Override
  public void onNext(GenerateContentResponse chunk) {
      Part part = chunk.getCandidates().get(0).getContent().getParts().get(0);
      if (part instanceof InlineDataPart) {
          byte[] pcmChunk = ((InlineDataPart) part).getInlineData();  // Raw PCM bytes (24kHz, 1 channel, 16-bit)
          String mimeType = ((InlineDataPart) part).getMimeType();    // for example: "audio/pcm"

          // Append the audio chunk to your audio queue/buffer for playback.
          appendAudioChunk(pcmChunk);
      }
  }

  @Override
  public void onComplete() {
      // Audio stream complete.
  }

  @Override
  public void onError(Throwable t) {
      t.printStackTrace();
  }
});

Web


import { initializeApp } from "firebase/app";
import { getAI, getGenerativeModel, GoogleAIBackend, ResponseModality } from "firebase/ai";

// TODO(developer): Replace with your app's Firebase configuration
const firebaseConfig = { /* ... */ };
const firebaseApp = initializeApp(firebaseConfig);

// Initialize the Gemini Developer API backend service.
const ai = getAI(firebaseApp, { backend: new GoogleAIBackend() });

// Set `responseModalities` to include `AUDIO`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
const generationConfig = {
  responseModalities: [ResponseModality.AUDIO],
  speechConfig: {
    voiceConfig: { prebuiltVoiceConfig: { voiceName: "Kore" } }
  }
};

// Create a `GenerativeModel` instance with a model that supports speech generation.
const model = getGenerativeModel(ai, {
  model: "gemini-3.1-flash-tts-preview",
  generationConfig
});

// Provide a text prompt.
const prompt = "Tell me a story about a brave knight.";

// Call `generateContentStream` to generate the speech output stream based on your text prompt.
const result = await model.generateContentStream(prompt);

// Extract the audio data and handle it for downstream use. For example:
const playbackQueue = [];
for await (const chunk of result.stream) {
  const inlineDataParts = chunk.inlineDataParts();
  if (inlineDataParts?.[0]) {
    const pcmBase64 = inlineDataParts[0].inlineData.data;  // Raw PCM bytes (24kHz, 1 channel, 16-bit)
    const pcmBuffer = Uint8Array.from(atob(pcmBase64), c => c.charCodeAt(0)).buffer;

    // Append the audio chunk to your audio queue/buffer for playback.
    playbackQueue.push(pcmBuffer);
  }
}

// To play back an array of PCM buffers in sequence, you'll need to write your own `processPlaybackQueue` function.
processPlaybackQueue(playbackQueue);

Dart


import 'package:firebase_ai/firebase_ai.dart';

// Set `responseModalities` to include `audio`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
final config = GenerationConfig(
  responseModalities: [ResponseModalities.audio],
  speechConfig: SpeechConfig(voiceName: 'Kore'),
);

// Initialize the Gemini Developer API backend service.
// Create a `GenerativeModel` instance with a model that supports speech generation.
final model = FirebaseAI.googleAI().generativeModel(
  model: 'gemini-3.1-flash-tts-preview',
  generationConfig: config,
);

// Provide a text prompt.
final prompt = 'Tell me a story about a brave knight.';

// Call `generateContentStream` to generate the speech output stream based on your text prompt.
final responseStream = model.generateContentStream([Content.text(prompt)]);

// Extract the audio data and handle it for downstream use. For example:
await for (final chunk in responseStream) {
  final part = chunk.candidates.first.content.parts.first;
  if (part is InlineDataPart && part.mimeType.startsWith('audio/')) {
    final Uint8List pcmChunk = part.bytes;  // Raw PCM bytes (24kHz, 1 channel, 16-bit)

    // Append the audio chunk to your audio queue/buffer for playback.
    appendAudioChunk(pcmChunk);
  }
}

Unity


using System.Collections.Generic;
using System.Linq;
using Firebase.AI;

// Initialize the Gemini Developer API backend service.
var ai = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI());

// Set `ResponseModalities` to include `Audio`.
// Configure a `SpeechConfig` with your chosen voice name (and optionally a language code).
var config = new GenerationConfig(
    responseModalities: new List<ResponseModality> { ResponseModality.Audio },
    speechConfig: SpeechConfig.UsePrebuiltVoice("Kore")
);

// Create a `GenerativeModel` instance with a model that supports speech generation.
var model = ai.GetGenerativeModel(
    modelName: "gemini-3.1-flash-tts-preview",
    generationConfig: config
);

// Provide a text prompt.
var prompt = "Tell me a story about a brave knight.";

// Call `GenerateContentStreamAsync` to generate the speech output stream based on your text prompt.
var responseStream = model.GenerateContentStreamAsync(prompt);

// Extract the audio data and handle it for downstream use. For example:
await foreach (var response in responseStream)
{
    var audioParts = response.Candidates.FirstOrDefault().Content.Parts
                            .OfType<ModelContent.InlineDataPart>();

    foreach (var part in audioParts)
    {
        byte[] pcmChunk = part.Data; // Raw PCM bytes (24kHz, 1 channel, 16-bit)

        // Append the audio chunk to your audio queue/buffer for playback.
        appendAudioChunk(pcmChunk);
    }
}



کنترل کردن برونداد گفتاری با پیام‌واره‌ها

بااستفاده از تکنیک‌های خاص پیام‌واره‌نویسی می‌توانید بر لحن، سرعت، و سبک گفتار تولیدشده تأثیر بگذارید.

زیربخش‌های زیر درباره ساختار پیام‌واره و برچسب‌های صوتی راهنمایی‌های سطح بالا را شرح می‌دهند. برای راهنمایی دقیق، به این راهنمای پیام‌واره‌ها مراجعه کنید.

ساختار پیام‌واره

برای کسب بهترین نتایج، پیام‌واره‌تان را با مؤلفه‌های زیر ساختاربندی کنید:

  • Audio Profile: شخصیت، هویت اصلی، و کهن‌الگوی گوینده را شرح دهید (برای مثال، A warm, professional narrator).

  • Scene: محیط و حس‌وحال احساسی را توصیف کنید (برای مثال، In a quiet library یا Amidst a noisy crowd).

  • Director's Notes: احساس، سرعت، سبک، و لهجه را شرح دهید (برای مثال، Speak slowly and with mystery).

  • Sample Context: نقطه شروعی به مدل بدهید (برای مثال، The speaker is greeting a close friend).

  • ترانویسی: نوشتار واقعی که باید گفته شود. برای بهترین عملکرد، مطمئن شوید که لحن نوشتاری و بافت نوشتار با نمایه صدا و یادداشت‌های کارگردانی مطابقت داشته باشد.

پیام‌واره نمونه:

[Audio Profile: A young, energetic voice]
[Scene: A lively sports broadcast]
[Director's Notes: Speak fast, with high energy and excitement]
[Sample Context: The game just ended with a last-second touchdown]
Welcome back fans! What an incredible game we're witnessing today!

برچسب‌های صوتی

می‌توانید برچسب‌های قالب‌بندی را مستقیماً در پیام‌واره نوشتاری خود درج کنید تا عملکرد مدل را هدایت کنید.

برچسب‌های صوتی فقط هنگام استفاده از مدل‌های Gemini 3.x TTS پشتیبانی می‌شوند.

برچسب‌های پرکاربرد عبارت‌اند از:

  • [whispers]: صحبت کردن با صدای آهسته
  • ‫[laughs]: برای افزودن خنده
  • [giggles]: برای افزودن خنده
  • [sighs]: برای افزودن آه
  • [gasp]: برای افزودن نفس‌نفس زدن
  • [shouting]: فریاد زدن
  • [excited]: با هیجان صحبت کردن
  • ‫[serious]: صحبت کردن به‌طور جدی
  • [sighs whispers]: احساسات ترکیبی (می‌توانید برچسب‌ها را ترکیب کنید)

هنگام استفاده از برچسب‌های صوتی به موارد زیر توجه کنید:

  • فهرست جامع نیست: فهرست ثابتی از برچسب‌های پشتیبانی‌شده وجود ندارد. می‌توانید احساسات و حالت‌های مختلف (مثل [bored]، [sarcastically]، یا حتی [like dracula]) را امتحان کنید تا ببینید خروجی چگونه تغییر می‌کند.

  • پیام‌واره نوشتاری غیرانگلیسی: اگر پیام‌واره نوشتاری شما به زبان انگلیسی نیست، برای بهترین نتایج همچنان باید از برچسب‌های صوتی انگلیسی استفاده کنید.

پیام‌واره نمونه:

I have a secret to tell you. [whispers] I found the hidden treasure. [laughs] I can't believe it!



محدودیت‌ها و الزامات

هنگام استفاده از تولید گفتار، از محدودیت‌ها و الزامات زیر آگاه باشید:

  • پیکربندی چندگوینده دقیقاً از ۲ گوینده پشتیبانی می‌کند.

  • ویژگی‌های زیر فقط هنگام استفاده از مدل‌های Gemini 3.x TTS پشتیبانی می‌شوند: جاری‌سازی، برچسب‌های صوتی، و زبان‌های تشخیص‌داده‌شده خودکار اضافی.

محدودیت‌های gemini-3.1-flash-tts-preview

  • ناسازگاری صدا: اگر لحن و بافت پیام‌واره شما با نمایه گوینده مطابقت نداشته باشد (برای مثال، صدای بم مردانه که تلاش می‌کند مانند دختر جوانی صحبت کند)، ممکن است خروجی مدل همیشه دقیقاً با گوینده انتخاب‌شده مطابقت نداشته باشد. مطمئن شوید بافت پیام‌واره با صدا مطابقت داشته باشد.
  • خروجی‌های طولانی‌تر: کیفیت و ثبات گفتار ممکن است برای صداهای طولانی‌تر از چند دقیقه تغییر کند. توصیه می‌کنیم پیام‌واره‌های نوشتاری طولانی را به بخش‌های کوچک‌تر تقسیم کنید.
  • برگرداندن گاه‌به‌گاه داده‌واحد نوشتاری: مدل گاهی به‌جای داده‌واحد صوتی، داده‌واحد نوشتاری برمی‌گرداند که باعث می‌شود درخواست با خطای 500 ناموفق شود. چون این خطا به‌طور تصادفی در درصد کمی از درخواست‌ها رخ می‌دهد، باید منطق تکرار مجدد را در برنامه‌تان پیاده‌سازی کنید.
  • رد کردن‌های اشتباه طبقه‌بندی‌کننده: پیام‌واره‌های مبهم ممکن است در طبقه‌بندی‌کننده ترکیب گفتار رد شوند و درنتیجه درخواست رد شود (PROHIBITED_CONTENT) یا باعث شود مدل دستورالعمل‌های سبک شما را با صدای بلند بخواند. برای جلوگیری از این اتفاق، از پیام‌واره ساختاریافته با مقدمه واضح (مثل Audio Profile و Director's Notes) در ابتدای پیام‌واره استفاده کنید.



زبان‌ها و صداهای پشتیبانی‌شده

مدل‌های Gemini TTS ورودی نوشتاری را دریافت می‌کنند و خروجی صوتی تولید می‌کنند، بنابراین پاسخ همان گفتار ترکیبی است. در بخش‌های فرعی زیر، فهرست صداها و زبان‌های پشتیبانی‌شده‌ای که مدل‌های تبدیل نوشتار به گفتار Gemini می‌توانند به آن‌ها «صحبت کنند» (یا پاسخ دهند) ارائه شده است.

صداها چندزبانه هستند، یعنی می‌توانید از یک صدا برای تولید گفتار به هریک از زبان‌های پشتیبانی‌شده استفاده کنید. برای مثال، می‌توانید صدا را روی Kore تنظیم کنید و مجموعه‌ای از پیام‌واره‌های نوشتاری را به زبان‌های اسپانیایی، هندی، و ویتنامی ارسال کنید. همه پاسخ‌ها با صدای Kore اما به هریک از آن زبان‌های مختلف خواهد بود.

نام صداها

مدل‌های تبدیل نوشتار به گفتار Gemini از ۳۰ صدای HD ترکیبی مختلف پشتیبانی می‌کنند که هرکدام ویژگی‌های متمایزی دارند. با ازهم باز کردن بخش زیر می‌توانید فهرست گزینه‌های صدای پاسخ را مشاهده کنید و نمونه‌های هر صدا را بشنوید.

زبان‌ها

مدل‌های «تبدیل نوشتار به گفتار» Gemini می‌توانند زبان‌های زیر را در پیام‌واره نوشتاری شما به‌طور خودکار تشخیص دهند. گفتار تولیدشده به آن زبان خواهد بود.

توجه داشته باشید که می‌توانید به‌طور اختیاری کد زبان را به‌طور صریح در پیکربندی گفتار تنظیم کنید.

زبان‌های پشتیبانی‌شده توسط همه مدل‌های تولیدکننده صدا
زبان کد BCP-47 زبان کد BCP-47
عربی (مصری) ar-EG آلمانی (آلمان) de-DE
انگلیسی (امریکا) en-US اسپانیایی (ایالات متحده) es-US
فرانسوی (فرانسه) fr-FR هندی (هندوستان) hi-IN
اندونزیایی (اندونزیایی) id-ID ایتالیایی (ایتالیا) it-IT
ژاپنی (ژاپن) ja-JP کره‌ای (کره) ko-KR
پرتغالی (برزیل) pt-BR روسی (روسیه) ru-RU
هلندی (هلند) nl-NL لهستانی (لهستان) لهستانی (لهستان)
تایلندی (تایلند) تایلندی (تایلند) ترکی (ترکیه) tr
ویتنامی (ویتنامی) vi-VN رومانیایی (رومانی) ro-RO
اوکراینی (اوکراین) uk-UA بنگالی (بنگلادش) bn-BD
انگلیسی (هند) بسته انگلیسی هندی و هندی مراتی (هند) mr-IN
تامیلی (هند) ta-IN تلوگو (هند) te-IN
زبان‌های دیگری که مدل‌های 3.x تولیدکننده صدا از آن‌ها پشتیبانی می‌کنند
زبان کد BCP-47 زبان کد BCP-47
آفریکانس af فیلیپینی fil
آلبانیایی sq فنلاندی fi
آمهاریک am گالیسی gl
ارمنی hy گرجستانی ka
آذربایجانی az یونانی el
باسک eu گجراتی gu
بلاروسی be کرئول هائیتی نیمه
بلغاری bg عبری او
برمه‌ای my مجاری hu
Catalan ca ایسلندی is
سبوانو سبوانو جاوه‌ای jv
چینی، ماندارین cmn کنادا kn
کرواتی hr کونکانی kok
چک cs لائوسی lo
دانمارکی da لاتین la
استونیایی et لتونیایی lv
Lithuanian lt لوگزامبورگی پوند
مقدونی mk مایتیلی مای
مالاگاسی میلی‌گرم مالایایی ms
Malayalam ml مغولی mn
Nepali ne نروژی، بوکمال nb
نروژی، نی‌نورسک nn اودیا یا
پشتو ps فارسی fa
پنجابی pa صربی sr
سیندهی sd سینهالی si
Slovak sk Slovenian sl
سواحیلی sw Swedish sv
اردو ur

(اختیاری) کد زبان را به‌طور صریح تنظیم کنید

اگر کد زبان را در پیکربندی گفتار مشخص نکنید، مدل به‌طور خودکار زبان را در پیام‌واره نوشتاری شما تشخیص می‌دهد.

بااین‌حال، می‌توانید به‌طور اختیاری زبان را به‌طور صریح تنظیم کنید (بااستفاده از پارامتر languageCode در پیکربندی گفتار). برای انجام این کار، باید از یکی از کدهای منطقه زبانی BCP-47 پشتیبانی‌شده زیر استفاده کنید:

  • عربی: ar-XA
  • بنگالی: bn-IN
  • چینی (ماندارین): cmn-CN
  • هلندی: nl-NL
  • انگلیسی: en-US، en-GB، en-AU، en-IN
  • فرانسوی: fr-FR، fr-CA
  • آلمانی: de-DE
  • گجراتی: gu-IN
  • هندی: hi-IN
  • اندونزیایی: id-ID
  • ایتالیایی: it-IT
  • ژاپنی: ja-JP
  • کنادا: kn-IN
  • کره‌ای: ko-KR
  • مالایالام: ml-IN
  • مراتی: mr-IN
  • لهستانی: pl-PL
  • پرتغالی: pt-BR
  • روسی: ru-RU
  • اسپانیایی: es-US، es-ES
  • تامیل: ta-IN
  • تلوگو: te-IN
  • تایلندی: th-TH
  • ترکی: tr-TR
  • ویتنامی: vi-VN



چه کارهای دیگری می‌توانید انجام دهید؟

امتحان کردن قابلیت‌های دیگر

با نحوه کنترل تولید محتوا آشنا شوید

همچنین می‌توانید بااستفاده از Google AI Studio پیکربندی‌های مدل و پیام‌واره‌ها را آزمایش کنید و حتی تکه‌کد تولیدشده دریافت کنید.

درباره مدل‌های پشتیبانی‌شده بیشتر بدانید

با مدل‌های دردسترس برای موارد استفاده مختلف و سهمیه‌ها و قیمت‌گذاری آن‌ها آشنا شوید.


درباره تجربه‌تان با Firebase AI Logic بازخورد ارائه دهید