Telematics SDK 介绍(5)
5.6.3 音频捕捉会话
音频捕获会话的音频管理器API示例参考
本节演示如何使用音频管理器API进行音频捕获会话。
- 获取AudioFactory实例
auto &audioFactory = audioFactory::getInstance();
- 获取audimanager对象并检查音频子系统是否就绪
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 object" << 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 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;
}
- 创建音频流(音频捕获会话)
//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;
audioCaptureStream = std::dynamic_pointer_cast<IAudioCaptureStream>(stream);
}
//Create an Audio Stream (Audio Capture Session)
StreamConfig config;
config.type = StreamType::CAPTURE;
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);
- 为捕获操作分配流缓冲区
// Get an audio buffer (can get more than one)
auto streamBuffer = audioCaptureStream->getStreamBuffer();
if(streamBuffer != nullptr) {
// Setting the bytesToRead (bytes to be read from stream) as 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
bytesToRead = streamBuffer->getMinSize();
if(bytesToRead == 0) {
bytesToRead = streamBuffer->getMaxSize();
}
} else {
std::cout << "Failed to get Stream Buffer " << std::endl;
return EXIT_FAILURE;
}
- 开始读取操作为捕获开始
//Callback which provides response to read operation
void readCallback(std::shared_ptr<IStreamBuffer> buffer, ErrorCode error)
{
uint32_t bytesWrittenToFile = 0;
if (error != ErrorCode::SUCCESS) {
std::cout << "read() returned with error " << static_cast<int>(error) << std::endl;
} else {
uint32_t size = buffer->getDataSize();
std::cout << "Successfully read " << size << " bytes" << std::endl;
}
buffer->reset();
return;
}
//Read from Capture
//First read starts Capture Session.
auto status = audioCaptureStream->read(streamBuffer, bytesToRead, readCallback);
if(status != telux::common::Status::SUCCESS) {
std::cout << "read() failed with error" << static_cast<int>(status) << std::endl;
} else {
std::cout << "Request to read stream sent" << std::endl;
}
- 删除音频流(音频捕获会话),一旦捕获所需的字节
//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;
audioCaptureStream.reset();
}
//Delete an Audio Stream (Audio Capture Session), once reached end of operation.
Status status = audioManager->deleteStream(
std::dynamic_pointer_cast<IAudioStream>(audioCaptureStream), deleteStreamCallback);
if (status != Status::SUCCESS) {
std::cout << "deleteStream failed with error" << static_cast<int>(status) << std::endl;
}
5.6.4 音频回环会话
音频管理器API示例参考音频回环会话
请按照以下步骤在回环会话中启动/停止回环。
- 获取AudioFactory实例
auto &audioFactory = audioFactory::getInstance();
- 获取audimanager对象并检查音频子系统就绪
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 object" << 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 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;
}
- 创建一个音频流(与回环相关联)
// Implement a response function to get the request status
void createStreamCallback(std::shared_ptr<IAudioStream> &stream, ErrorCode error) {
if (error != ErrorCode::SUCCESS) {
std::cout << "createStream() failed with error" << static_cast<int>(error) << std::endl;
return;
}
std::cout << "createStream() succeeded." << std::endl;
audioLoopbackStream = std::dynamic_pointer_cast<IAudioLoopbackStream>(stream);
}
// Create a loopback stream with required configuration
config.type = telux::audio::StreamType::LOOPBACK;
config.sampleRate = 48000;
config.format = AudioFormat::PCM_16BIT_SIGNED;
config.channelTypeMask = ChannelType::LEFT;
config.deviceTypes.emplace_back(DeviceType::DEVICE_TYPE_SPEAKER);
config.deviceTypes.emplace_back(DeviceType::DEVICE_TYPE_MIC);
status = audioManager->createStream(config, createStreamCallback);
- 在指定的源和接收设备之间开始回环
// Implement a response function to get the request status
void startLoopbackCallback(ErrorCode error)
{
if (error != ErrorCode::SUCCESS) {
std::cout << "startLoopback() failed with error" << static_cast<int>(error) << std::endl;
return;
}
std::cout << "startLoopback() succeeded." << std::endl;
}
// start loopback
status = audioLoopbackStream->startLoopback(startLoopbackCallback);
- 停止指定源设备和接收设备之间的回环
// Implement a response function to get the request status
void stopLoopbackCallback(ErrorCode error)
{
if (error != ErrorCode::SUCCESS) {
std::cout << "stopLoopback() failed with error " << static_cast<int>(error) << std::endl;
return;
}
std::cout << "stopLoopback() succeeded." << std::endl;
}
// Stop the loopback, which was started earlier
status = audioLoopbackStream->stopLoopback(stopLoopbackCallback);
- 删除与回环会话关联的音频流
// Implement a response function to get the request status
void deleteStreamCallback(ErrorCode error) {
if (error != ErrorCode::SUCCESS) {
std::cout << "deleteStream() failed with error" << static_cast<int>(error) << std::endl;
return;
}
std::cout << "deleteStream() succeeded." << std::endl;
audioLoopbackStream.reset();
}
// Delete the Audio Stream
status = audioManager->deleteStream(std::dynamic_pointer_cast<IAudioStream>(audioLoopbackStream),
deleteStreamCallback);