Audio Manager APIs Sample Reference for compressed audio format playback on voice paths
This Section demonstrates how to use the Audio Manager API for compressed audio format playback on voice paths.
1. Get the AudioFactory instance
auto &audioFactory = audioFactory::getInstance();
2. Get the AudioManager object and check for audio subsystem Readiness
std::promise<ServiceStatus> prom{};
audioManager = audioFactory.getAudioManager([&prom](ServiceStatus serviceStatus) {
prom.set_value(serviceStatus);
});
if (!audioManager) {
std::cout << "Failed to get AudioManager object" << std::endl;
return;
}
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();
}
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;
}
3. Create an Audio Stream (Audio Playback Session) with Voice Paths direction
StreamConfig config;
config.type = StreamType::PLAY;
config.slotId = DEFAULT_SLOT_ID;
config.sampleRate = SAMPLE_RATE;
config.format = AudioFormat::AMRWB_PLUS;
config.channelTypeMask = (ChannelType::LEFT | ChannelType::RIGHT);
config.voicePaths.emplace_back(Direction::TX);
AmrwbpParams amrParams{};
if (config.format == AudioFormat::AMRWB_PLUS) {
amrParams.bitWidth = 16;
amrParams.frameFormat = AmrwbpFrameFormat::FILE_STORAGE_FORMAT;
config.formatParams = &amrParams;
} else {
config.formatParams = nullptr;
}
std::promise<bool> p;
auto status = audioManager->createStream(config,
[&p,this](std::shared_ptr<IAudioStream> &audioStream, ErrorCode error) {
if (error == ErrorCode::SUCCESS) {
audioPlayStream_ = std::dynamic_pointer_cast<IAudioPlayStream>(audioStream);
p.set_value(true);
} else {
p.set_value(false);
std::cout << "failed to Create a stream" <<std::endl;
}
});
if (status == Status::SUCCESS) {
std::cout << "Request to create stream sent" << std::endl;
} else {
std::cout << "Request to create stream failed" << std::endl;
}
if (p.get_future().get()) {
std::cout<< "Audio Play Stream is Created" << std::endl;
}
4. Allocate Stream buffers for Playback operation
auto streamBuffer = audioPlayStream->getStreamBuffer();
if (streamBuffer != nullptr) {
size = streamBuffer->getMinSize();
if (size == 0) {
size = streamBuffer->getMaxSize();
}
streamBuffer->setDataSize(size);
} else {
std::cout << "Failed to get Stream Buffer " << std::endl;
}
5. Start write operation for playback to start
void writeCallback(std::shared_ptr<IStreamBuffer> buffer, uint32_t bytes, ErrorCode error)
{
if (error != ErrorCode::SUCCESS) {
std::cout << "write() returned with error " << static_cast<int>(error) << std::endl;
pipeLineEmpty_ = false;
}
buffer->reset();
return;
}
void onReadyForWrite() {
pipeLineEmpty_ = true;
}
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;
}
6.1 Stop playback operation(STOP_AFTER_PLAY : Stops after playing pending buffers in pipeline)
std::promise<bool> p;
auto status = audioPlayStream_->stopAudio(StopType::STOP_AFTER_PLAY, [&p](ErrorCode error) {
if (error == ErrorCode::SUCCESS) {
p.set_value(true);
} else {
p.set_value(false);
std::cout << "Failed to stop after playing buffers" << std::endl;
}
});
if (status == Status::SUCCESS) {
std::cout << "Request to stop playback after pending buffers Sent" << std::endl;
} else {
std::cout << "Request to stop playback after pending buffers failed" << std::endl;
}
if (p.get_future().get()) {
std::cout << "Pending buffers played successful !!" << std::endl;
}
6.2 Stop playback operation(FORCE_STOP : Stops immediately, all buffers in pipeline are flushed)
std::promise<bool> p;
auto status = audioPlayStream_->stopAudio(
StopType::FORCE_STOP, [&p](telux::common::ErrorCode error) {
if (error == telux::common::ErrorCode::SUCCESS) {
p.set_value(true);
} else {
p.set_value(false);
std::cout << "Failed to force stop" << std::endl;
}
});
if(status == telux::common::Status::SUCCESS){
std::cout << "Request to force stop Sent" << std::endl;
} else {
std::cout << "Request to force stop failed" << std::endl;
}
if (p.get_future().get()) {
std::cout << "Force Stop successful !!" << std::endl;
}
7. Delete an Audio Stream (Audio Playback Session), once reached end of operation
std::promise<bool> p;
Status status = audioManager-> deleteStream(
audioPlayStream_, [&p,this](ErrorCode error) {
if (error == ErrorCode::SUCCESS) {
p.set_value(true);
} else {
p.set_value(false);
std::cout << "Failed to delete a stream" << std::endl;
}
});
if (status == Status::SUCCESS) {
std::cout << "Request to delete stream sent" << std::endl;
} else {
std::cout << "Request to delete stream failed" << std::endl;
}
if (p.get_future().get()) {
audioPlayStream_= nullptr;
std::cout << "Audio Play Stream is Deleted" << std::endl;
}