Audio Manager APIs Sample Reference for audio transcoding operation
This Section demonstrates how to use the Audio Manager and Audio Transcoder APIs for transcoding operation.
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 Transcoder
FormatInfo inputConfig_;
FormatInfo outputConfig_;
AmrwbpParams inputParams{};
inputConfig_.sampleRate = SAMPLE_RATE;
inputConfig_.mask = CHANNEL_MASK;
inputConfig_.format = AudioFormat::AMRWB_PLUS;
inputParams.bitWidth = 16;
inputParams.frameFormat = AmrwbpFrameFormat::FILE_STORAGE_FORMAT;
inputConfig_.params = &inputParams;
inputConfig_.sampleRate = SAMPLE_RATE;
outputConfig_.mask = CHANNEL_MASK;
outputConfig_.format = AudioFormat::PCM_16BIT_SIGNED;
outputConfig_.params = nullptr;
audioManager->createTranscoder(inputConfig_, outputConfig_,
[&p,this](std::shared_ptr<telux::audio::ITranscoder> &transcoder,
telux::common::ErrorCode error) {
if (error == telux::common::ErrorCode::SUCCESS) {
transcoder_ = transcoder;
registerListener();
p.set_value(true);
} else {
p.set_value(false);
std::cout << "failed to create transcoder" <<std::endl;
}
});
if (p.get_future().get()) {
std::cout<< "Transcoder Created" << std::endl;
}
4.1 Allocate Audio buffers for write operation
auto audioBuffer = transcoder_->getWriteBuffer();
if (audioBuffer != nullptr) {
size = audioBuffer->getMinSize();
if (size == 0) {
size = audioBuffer->getMaxSize();
}
audioBuffer->setDataSize(size);
} else {
std::cout << "Failed to get Audio Buffer for write operation " << std::endl;
}
4.2 Allocate Audio buffers for read operation
auto audioBuffer = transcoder_->getReadBuffer();
if (audioBuffer != nullptr) {
size = audioBuffer->getMinSize();
if (size == 0) {
size = audioBuffer->getMaxSize();
}
audioBuffer->setDataSize(size);
} else {
std::cout << "Failed to get Audio Buffer for read operation " << std::endl;
}
5. Start write operation in one thread for transcoding
void writeCallback(std::shared_ptr<IAudioBuffer> buffer,
uint32_t bytes, ErrorCode error) {
std::cout << "Bytes Written : " << bytes << std::endl;
if (error != ErrorCode::SUCCESS || buffer->getDataSize() != bytes) {
pipeLineEmpty_ = false;
}
buffer->reset();
writeBuffers_.push(buffer);
cv_.notify_all();
return;
}
void onReadyForWrite() {
pipeLineEmpty_ = true;
}
auto writeCb = std::bind(&TranscoderApp::writeCallback, this, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
telux::common::Status status = telux::common::Status::FAILED;
if (EOF_REACHED) {
status = transcoder_->write(audioBuffer, EOF_REACHED, writeCb);
} else {
status = transcoder_->write(audioBuffer, EOF_NOT_REACHED, writeCb);
}
if (status != telux::common::Status::SUCCESS) {
std::cout << "write() failed with error" << static_cast<unsigned int>(status) << std::endl;
} else {
std::cout << "Request to transcode buffers sent " << std::endl;
}
6. Start read operation in another thread for transcoding
void readCallback(std::shared_ptr<telux::audio::IAudioBuffer> buffer,
uint32_t isLastBuffer, telux::common::ErrorCode error) {
if (isLastBuffer) {
}
if (error != telux::common::ErrorCode::SUCCESS) {
std::cout << "read() returned with error " << static_cast<unsigned int>(error)
<< std::endl;
} else {
}
buffer->reset();
readBuffers_.push(buffer);
cv_.notify_all();
return;
}
auto readCb = std::bind(&TranscoderApp::readCallback, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
telux::common::Status status = transcoder_->read(audioBuffer, bytesToRead, readCb);
if (status != telux::common::Status::SUCCESS) {
std::cout << "read() failed with error" << static_cast<unsigned int>(status) << std::endl;
}
7. Tear down the audio transcoder instance
std::promise<bool> p;
auto status = transcoder_->tearDown([&p](telux::common::ErrorCode error) {
if (error == telux::common::ErrorCode::SUCCESS) {
p.set_value(true);
} else {
p.set_value(false);
std::cout << "Failed to tear down" << std::endl;
}
});
if (status == telux::common::Status::SUCCESS) {
std::cout << "Request to Teardown transcoder sent" << std::endl;
} else {
std::cout << "Request to Teardown transcoder failed" << std::endl;
}
if (p.get_future().get()) {
transcoder_ = nullptr;
std::cout << "Tear Down successful !!" << std::endl;
}