Qualcomm 远程信息处理 SDK - 用户指南(2)

281 篇文章 30 订阅
150 篇文章 17 订阅

Qualcomm 远程信息处理 SDK - 用户指南(2)


4 示例应用程序

TelSDK 提供的示例应用程序快速演示了如何使用 TelSDK API 来实现最终功能。所有示例应用程序的完整源代码位于 /telux/public/apps/samples 目录中。

注意:某些应用程序包含的参数默认值可能因产品而异。可以使用这些应用程序使用的配置文件来覆盖这些值。配置以键值对的形式指定。例如,make_call_app 使用的拨号号码可以由 DIAL_NUMBER 项指定,然后可以运行应用程序,将此文件作为命令行参数传递给应用程序。

# Contents of /data/make_call_app.conf
DIAL_NUMBER = +1234512345
# Run the application
$ make_call_app /data/make_call_app.conf
  • Audio
  • CV2X
  • Telephony
  • Data
  • Location
  • Modem configuration
  • Power
  • Thermal
  • Sensor
  • Platform
  • Crypto
  • Crypto accelerator
  • WLAN

4.1 音频

TelSDK 音频 API 提供对设备和流管理、转码、录制/播放音频、语音通话和 DTMF 音调生成/检测等的支持。

4.1.1 音频管理器和流

音频管理器提供 API 来创建音频流和转码器。它还有助于了解支持的音频设备和音频校准状态。

  1. 获取AudioFactory实例
#include <telux/audio/AudioFactory.hpp>
#include <telux/audio/AudioManager.hpp>
using namespace telux::common;
using namespace telux::audio;
static std::shared_ptr<IAudioManager> audioManager;
static std::shared_ptr<IAudioVoiceStream> audioVoiceStream;
Status status;
auto &audioFactory = AudioFactory::getInstance();
  1. 获取AudioManager实例
std::promise<ServiceStatus> prom{};
//  Get AudioManager instance.
audioManager = audioFactory.getAudioManager([&prom](ServiceStatus serviceStatus) {
    prom.set_value(serviceStatus);
});
if (!audioManager) {
    std::cout << "Failed to get AudioManager instance" << std::endl;
    return;
}
  1. 让音频子系统准备就绪
// Check if audio subsystem is ready
// If audio subsystem is not ready, wait for it to be ready
ServiceStatus managerStatus = audioManager->getServiceStatus();
if (managerStatus != ServiceStatus::SERVICE_AVAILABLE) {
    std::cout << "\nAudio subsystem is not ready, Please wait ..." << std::endl;
    managerStatus = prom.get_future().get();
}
// Check the service status again
if (managerStatus == ServiceStatus::SERVICE_AVAILABLE) {
    std::cout << "Audio Subsytem is Ready << std::endl;
} else {
    std::cout << "ERROR - Unable to initialize audio subsystem" << std::endl;
    return;
}

4.查询支持的音频设备

// Callback to get supported device type details
void getDevicesCallback(std::vector<std::shared_ptr<IAudioDevice>> devices, ErrorCode error)
{
    if (error != ErrorCode::SUCCESS) {
        std::cout << "getDevices() returned with error " << static_cast<unsigned int>(error)
            << std::endl;
        return;
    }
    int i = 0;
    for (auto device_type : devices) {
        std::cout << "Device [" << i << "] type: "
            << static_cast<unsigned int>(device_type->getType()) << ", direction: "
            << static_cast<unsigned int>(device_type->getDirection()) << std::endl;
        i++;
    }
}
// Query Supported Device type details
status = audioManager->getDevices(getDevicesCallback);

5.查询支持的音频流类型

// Callback to get supported stream type details
void getStreamTypesCallback(std::vector<StreamType> streams, ErrorCode error)
{
    if (error != ErrorCode::SUCCESS) {
        std::cout << "getStreamTypes() returned with error " << static_cast<unsigned int>(error)
            << std::endl;
        return;
    }
    int i = 0;
    for (auto stream_type : streams) {
        std::cout << "Stream [" << i << "] type: " << static_cast<unsigned int>(stream_type)
            << std::endl;
        i++;
    }
}
// Query Supported stream type details
status = audioManager->getStreamTypes(getStreamTypesCallback);
  1. 创建音频流(语音通话会话)
// Callback which provides response to createStream, with pointer to base interface IAudioStream
void createStreamCallback(std::shared_ptr<IAudioStream> &stream, ErrorCode error)
{
    if (error != ErrorCode::SUCCESS) {
        std::cout << "createStream() returned with error " << static_cast<unsigned int>(error)
            << std::endl;
        return;
    }
    std::cout << "createStream() succeeded." << std::endl;
    audioVoiceStream = std::dynamic_pointer_cast<IAudioVoiceStream>(stream);
}
// Create an Audio Stream (Voice Call Session)
StreamConfig config;
config.type = StreamType::VOICE_CALL;
config.slotId = DEFAULT_SLOT_ID;
config.sampleRate = 16000;
config.format = AudioFormat::PCM_16BIT_SIGNED;
config.channelTypeMask = ChannelType::LEFT;
/*For StreamType::VOICE_CALL, sink and source device are required to be passed.
  First device should be sink (speaker) and then source (mic) should be passed
  for stream creation.*/
config.deviceTypes.emplace_back(DeviceType::DEVICE_TYPE_SPEAKER);
config.deviceTypes.emplace_back(DeviceType::DEVICE_TYPE_MIC);
status = audioManager->createStream(config, createStreamCallback);
  1. 删除音频流
// Callback which provides response to deleteStream
void deleteStreamCallback(ErrorCode error) {
    if (error != ErrorCode::SUCCESS) {
        std::cout << "deleteStream() returned with error " << static_cast<unsigned int>(error)
            << std::endl;
        return;
    }
    std::cout << "deleteStream() succeeded." << std::endl;
    audioVoiceStream.reset();
}
// Delete the stream (voice call session), which was created earlier
status = audioManager->deleteStream(std::dynamic_pointer_cast<IAudioStream>(audioVoiceStream),
                                    deleteStreamCallback);

4.1.2 回放会话

此示例应用程序演示了如何使用音频 API 进行播放会话。

1.获取AudioFactory实例

auto &audioFactory = AudioFactory::getInstance();
  1. 获取 AudioManager 实例并检查音频子系统准备情况
std::promise<ServiceStatus> prom{};
// Get the AudioManager instance
audioManager = audioFactory.getAudioManager([&prom](ServiceStatus serviceStatus) {
    prom.set_value(serviceStatus);
});
if (!audioManager) {
    std::cout << "Failed to get AudioManager instance" << std::endl;
    return;
}
// Check if audio subsystem is ready
// If audio subsystem is not ready, wait for it to be ready
ServiceStatus managerStatus = audioManager->getServiceStatus();
if (managerStatus != ServiceStatus::SERVICE_AVAILABLE) {
    std::cout << "\nAudio subsystem is not ready, Please wait ..." << std::endl;
    managerStatus = prom.get_future().get();
}
// Check the audio service status again
if (managerStatus == ServiceStatus::SERVICE_AVAILABLE) {
    std::cout << "Audio Subsytem is Ready << std::endl;
} else {
    std::cout << "ERROR - Unable to initialize audio subsystem" << std::endl;
    return;
}
  1. 创建音频播放会话
// Callback which provides response to createStream, with pointer to base interface IAudioStream
 void createStreamCallback(std::shared_ptr<IAudioStream> &stream, ErrorCode error)
 {
     if (error != ErrorCode::SUCCESS) {
         std::cout << "createStream() returned with error " << static_cast<int>(error)
             << std::endl;
         return;
     }
     std::cout << "createStream() succeeded." << std::endl;
     audioPlayStream = std::dynamic_pointer_cast<IAudioPlayStream>(stream);
 }
 // Create an audio stream
 StreamConfig config;
 config.type = StreamType::PLAY;
 config.sampleRate = 48000;
 config.format = AudioFormat::PCM_16BIT_SIGNED;
 config.channelTypeMask = ChannelType::LEFT;
 config.deviceTypes.emplace_back(DeviceType::DEVICE_TYPE_SPEAKER);
 status = audioManager->createStream(config, createStreamCallback);
  1. 为播放操作分配流缓冲区
// Get an audio buffer (we can get more than one)
auto streamBuffer = audioPlayStream->getStreamBuffer();
if (streamBuffer != nullptr) {
    // Setting the size that is to be written to stream as the minimum size
    // required by stream. In any case if size returned is 0, using the Maximum
    // Buffer Size, any buffer size between min and max can be used
    size = streamBuffer->getMinSize();
    if (size == 0) {
        size =  streamBuffer->getMaxSize();
    }
    streamBuffer->setDataSize(size);
} else {
    std::cout << "Failed to get Stream Buffer " << std::endl;
}
  1. 开始写入操作以开始播放
// Callback which provides response to write operation
void writeCallback(std::shared_ptr<IStreamBuffer> buffer, uint32_t size, ErrorCode error)
{
    if (error != ErrorCode::SUCCESS) {
        std::cout << "write() returned with error " << static_cast<int>(error) << std::endl;
    } else {
        std::cout << "Successfully written " << size << " bytes" << std::endl;
    }
    buffer->reset();
    return;
}
// Write desired data into the buffer
// Very first write starts the playback session
memset(streamBuffer->getRawBuffer(),0x1,size);
auto status = audioPlayStream->write(streamBuffer, writeCallback);
if(status != telux::common::Status::SUCCESS) {
    std::cout << "write() failed with error" << static_cast<int>(status) << std::endl;
} else {
    std::cout << "Request to write to stream sent" << std::endl;
}
  1. 处理音频流
// Callback which provides response to deleteStream
void deleteStreamCallback(ErrorCode error) {
    if (error != ErrorCode::SUCCESS) {
        std::cout << "deleteStream() returned with error " << static_cast<int>(error)
            << std::endl;
        return;
    }
    std::cout << "deleteStream() succeeded." << std::endl;
    audioPlayStream.reset();
}
// Delete the audio stream
Status  status = audioManager->deleteStream(
           std::dynamic_pointer_cast<IAudioStream>(audioPlayStream), deleteStreamCallback);
if (status != Status::SUCCESS) {
    std::cout << "deleteStream failed with error" << static_cast<int>(status) << std::endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值