Quickstart

Updated

Build a Voice Calling app for your selected platform, and switch platforms with the selector below.

This Windows quickstart shows you how to create a basic Voice Calling app using the Agora Voice SDK.

Understand the tech

To start a Voice Calling session, implement the following steps in your app:

  • Initialize the Agora Engine: Before calling other APIs, create and initialize an Agora Engine instance.

  • Join a channel: Call methods to create and join a channel.

  • Send and receive audio: All users can publish streams to the channel and subscribe to audio streams published by other users in the channel.

Prerequisites

Set up your project

This section shows you how to set up your Windows project and install the Agora Voice SDK.

The following steps outline the process to set up a new Visual Studio 2022 project on Windows 11 for implementing real-time audio and video interaction functions.

  1. In Visual Studio, select File > New > Project to create a new project. In the pop-up window, select MFC application as the project template, click Next, update the project name to AgoraQuickStart, set the project storage location, and then click Create.

  2. In the pop-up MFC application window, set the application type to Dialog-based , and set Use MFC to Use MFC in a shared DLL. Enter the generated class, set the generated class to Dlg, set the base class to CDialog, and click Finish.

To integrate real-time audio interaction into your project:

  1. Launch Visual Studio 2022 and open your existing project by selecting File > Open > Project/Solution.

  2. Navigate to your project directory and open the .sln file.

  1. Create a user-interface for your app based on your application use-case.

    A basic UI consists of the following controls:

    • Join channel button
    • Leave channel button
    • An Edit Control for entering a channel name

    Refer to Create a user interface to get a bare bones sample layout.

Install the SDK

Install the Agora Voice SDK:

  1. Download the latest Windows SDK.

  2. Unzip and open the downloaded SDK. Copy all subfolders in sdk/ to your solution folder. Make sure these subfolders are in the same directory as your .sln file.

Configure the project

In the Solution Explorer window, right-click the project name and click Properties to configure the following:

  1. Go to the C/C++ > General > Additional Include Directory menu, click Edit, and in the pop-up window enter $(SolutionDir)sdk\high_level_api\include.
  2. Go to the Linker > General > Additional Library Directory menu, click Edit, and in the pop-up window:
    • for 64 bit Windows, enter $(SolutionDir)sdk\x86_64.
    • for x86 Windows, enter $(SolutionDir)sdk\x86.
  3. Go to the Linker > Input > Additional Dependencies menu, click Edit, and in the pop-up window:
    • for 64 bit Windows, enter $(SolutionDir)sdk\x86_64\agora_rtc_sdk.dll.lib.
    • for x86 Windows, enter $(SolutionDir)sdk\x86\agora_rtc_sdk.dll.lib.
  4. Enter the Advanced menu, and in Advanced Properties, set Copy contents to OutDir and Copy C++ runtime to output directory to Yes.
  5. Go to the Build Events > Post-Build Events > Command Line menu and enter copy $(SolutionDir)sdk\x86_64\*.dll $(SolutionDir)$(Platform)\$(Configuration).
  6. Click Apply to save the configuration.

Implement Voice Calling

This section guides you through the implementation of basic real-time audio interaction in your app.

The following figure illustrates the essential steps:

This guide includes complete sample code that demonstrates implementing basic real-time interaction. To understand the core API calls in the sample code, review the following implementation steps.

Initialize the engine

For real-time communication, initialize an IRtcEngine instance and set up event handlers to manage user interactions within the channel. Use RtcEngineContext to specify the App ID, and custom event handler, then call initialize to initialize the engine, enabling further channel operations. Add the following code to your header and .cpp files:

// Declare the required variables
IRtcEngine* m_rtcEngine = nullptr; // RTC engine instance
CAgoraQuickStartRtcEngineEventHandler m_eventHandler; // IRtcEngineEventHandler
void CAgoraQuickStartDlg::initializeAgoraEngine() {
  // Create IRtcEngine object
  m_rtcEngine = createAgoraRtcEngine();
  // Create IRtcEngine context object
  RtcEngineContext context;
  // Input your App ID. You can obtain your project's App ID from the Agora Console
  context.appId = APP_ID;
  // Add event handler for callbacks and events
  context.eventHandler = &m_eventHandler;
  // Initialize
  int ret = m_rtcEngine->initialize(context);
  m_initialize = (ret == 0);

  if (!m_initialize) {
    AfxMessageBox(_T("Failed to initialize Agora RTC engine"));
  }
}

Join a channel

To join a channel, call joinChannel[2/2] with the following parameters:

  • Channel name: The name of the channel to join. Clients that pass the same channel name join the same channel. If a channel with the specified name does not exist, it is created when the first user joins.

  • Authentication token: A dynamic key that authenticates a user when the client joins a channel. In a production environment, you obtain a token from a token server in your security infrastructure. For the purpose of this guide Generate a temporary token.

  • User ID: A 32-bit signed integer that identifies a user in the channel. You can specify a unique user ID for each user yourself. If you set the user ID to 0 when joining a channel, the SDK generates a random number for the user ID and returns the value in the onJoinChannelSuccess callback.

  • Channel media options: Configure ChannelMediaOptions to define publishing and subscription settings, optimize performance for your specific use-case, and set optional parameters.

For Voice Calling, set the channelProfile to CHANNEL_PROFILE_COMMUNICATION and the user role to CLIENT_ROLE_BROADCASTER.

void CAgoraQuickStartDlg::joinChannel(const char* token, const char* channelName) {
  ChannelMediaOptions options;
  // Set channel profile to live broadcasting
  options.channelProfile = CHANNEL_PROFILE_COMMUNICATION;
  // Set user role to broadcaster; keep default value if setting user role to audience
  options.clientRoleType = CLIENT_ROLE_BROADCASTER;
  // Publish the audio stream captured by the microphone
  options.publishMicrophoneTrack = true;
  // Automatically subscribe to all audio streams
  options.autoSubscribeAudio = true;
  // Join the channel using the token and channel name (both are const char*)
  m_rtcEngine->joinChannel(token, channelName, 0, options);
}

Subscribe to Voice SDK events

The Voice SDK provides an interface for subscribing to channel events. To use it, create a custom event handler class by inheriting from IRtcEngineEventHandler and override its methods to handle real-time interaction events. Add callbacks to receive notification of users joining and leaving the channel.

To ensure that you receive all Voice SDK events, set the Agora Engine event handler before joining a channel.

// Define the CAgoraQuickStartRtcEngineEventHandler class to handle callback events such as users joining and leaving the channel
class CAgoraQuickStartRtcEngineEventHandler
  : public IRtcEngineEventHandler {
  public:
    CAgoraQuickStartRtcEngineEventHandler()
      : m_hMsgHandler(nullptr) {
    }

    // Set the handle of the message receiving window
    void SetMsgReceiver(HWND hWnd) {
      m_hMsgHandler = hWnd;
    }

    // Register onJoinChannelSuccess callback
    // This callback is triggered when a local user successfully joins a channel
    virtual void onJoinChannelSuccess(const char* channel, uid_t uid, int elapsed) {
      if (m_hMsgHandler) {
        ::PostMessage(m_hMsgHandler, WM_MSGID(EID_JOIN_CHANNEL_SUCCESS), uid, 0);
      }
    }

    // Register onUserJoined callback
    // This callback is triggered when the remote host successfully joins the channel
    virtual void onUserJoined(uid_t uid, int elapsed) {
      if (m_hMsgHandler) {
        ::PostMessage(m_hMsgHandler, WM_MSGID(EID_USER_JOINED), uid, 0);
      }
    }

    // Register onUserOffline callback
    // This callback is triggered when the remote host leaves the channel or is offline
    virtual void onUserOffline(uid_t uid, USER_OFFLINE_REASON_TYPE reason) {
      if (m_hMsgHandler) {
        ::PostMessage(m_hMsgHandler, WM_MSGID(EID_USER_OFFLINE), uid, 0);
      }
    }

  private:
    HWND m_hMsgHandler;
};

Implement the callback functions.

LRESULT CAgoraQuickStartDlg::OnEIDJoinChannelSuccess(WPARAM wParam, LPARAM lParam) {
  // Join channel success callback
  uid_t localUid = wParam;
  return 0;
}

LRESULT CAgoraQuickStartDlg::OnEIDUserJoined(WPARAM wParam, LPARAM lParam) {
  // Remote user joined callback
  return 0;
}

LRESULT CAgoraQuickStartDlg::OnEIDUserOffline(WPARAM wParam, LPARAM lParam) {
  // Remote user left callback
  return 0;
}

Leave the channel

When a user ends a call, or closes the app call leaveChannel to exit the current channel.

// Leave the channel
m_rtcEngine->leaveChannel();

Release resources

To destroy the engine instance, call release :

// Release resources when the object is destroyed
m_rtcEngine->release(true);
m_rtcEngine = NULL;

After you call Dispose, you can no longer use any SDK methods or callbacks. To use real-time Voice Calling again, you must create a new engine. For more information, see Initialize the Engine.

Complete sample code

A complete code sample that implements the basic process of real-time interaction is presented here for your reference. Copy the sample code into your project to quickly implement the basic functions of real-time interaction.

AgoraQuickStartDlg.h

Create a user interface

Follow these steps to create a bare-bones UI for your project.

Steps to create a minimalistic UI

  1. In the right menu bar, switch the project to resource view, then open the .Dialog file.

  2. Add an input box for the channel name:

    1. Go to View > Toolbox and select Add Static Text control.
    2. Change the description text to Channel name in the properties.
    3. Add an Edit Control as an input box.
    4. In Properties > Miscellaneous, set the control's ID to IDC_EDIT_CHANNEL.
  3. Add join and leave channel buttons:

    1. In View > Toolbox, add two Button controls.
    2. In Properties > Miscellaneous, set the IDs of the controls to ID_BTN_JOIN and ID_BTN_LEAVE.
    3. Set the description text to Join and Leave respectively.

    Your interface looks similar to the following:

Test the sample code

To test your app, follow these steps:

  1. In Visual Studio, select local Windows debugger to start compiling the application.

  2. Enter the name of the channel you want to join in the input box and click the Join button to join the channel.

  3. Use the Web demo to join the same channel and test the following use-cases:

    • If users on both devices join the channel as hosts, they can hear each other.
    • If one user joins as host and the other as audience, the audience can hear the host.

Reference

This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.

  • If a firewall is deployed in your network environment, refer to Connect with Cloud Proxy to use Agora services normally.

Next steps

After implementing the quickstart sample, read the following documents to learn more:

  • To ensure communication security in a test or production environment, best practice is to obtain and use a token from an authentication server. For details, see Secure authentication with tokens.

Sample project

Agora provides open source sample projects on GitHub for your reference.

API Reference

Frequently asked questions

See also