google / google/oboe

When actively pushing data, the FLTP audio format played has noise and interference, and is discontinuous.

Open
#2,379 1 comment 0 reactions 1 assignee Claimed by @Mangomm View on GitHub
bug
Dominant language
C++
Stars
4.1k
Forks
639
Avg merge
2d 23h
Merged PRs (30d)
8

Description

Android version(s): Android 9 development board
Android device(s): Android 9 development board
Oboe version: 1.10.1
App name used for testing:


**Short description**
When actively pushing data, the FLTP audio format played has noise and interference, and is discontinuous.

When I used the following code to play the audio, I found that playing interleaved s16 pcm was normal, but when playing fltp32 pcm, there would be noise, distortion, intermittent and abnormal audio. I'm using the SDL library on Windows. The same code works fine. So, is it that Oboe doesn't handle flat audio very well? Or is it something else? Currently, I'm trying to resample ftlp -> s16 to see the effect.

Core code:

// open audio stream
`do {

try {

oboe::AudioStreamBuilder builder;
builder.setDirection(oboe::Direction::Output)
->setPerformanceMode(oboe::PerformanceMode::LowLatency)
->setSharingMode(oboe::SharingMode::Exclusive)
->setSampleRate(48000)
->setChannelCount(2)
->setFormat(AudioFormat::Float);

if (builder.openStream(_audio_stream) != oboe::Result::OK) {
LOGE("Failed to open android audio stream");
break;
}

if (_audio_stream->requestStart() != oboe::Result::OK) {
LOGE("Failed to request start android audio stream");
break;
}

_abart_thread_request = false;
_thread = std::thread(&OboeAudioRenderImp::audio_render_thread, this);

ret = 0;
}
catch (const std::exception& ex) {
LOGW("Oboe audio open catch exception:{}",ex.what());
}

}while(false);`

`void OboeAudioRenderImp::interleave_audio(
IAVFrame::shared frame)
{
auto audio_frame = std::dynamic_pointer_cast(frame);
if (!audio_frame || !audio_frame->is_audio() || !_audio_stream) {
return;
}

int channels = audio_frame->get_channels();
int nb_samples = audio_frame->get_nb_samples();
int bytes_per_sample = _audio_stream->getBytesPerSample();
int frame_size = channels * bytes_per_sample;

int required_size = nb_samples * frame_size;

if (_interleave_buffer.size() != required_size) {
_interleave_buffer.resize(required_size);
}

uint8_t* out = _interleave_buffer.data();

for (int c = 0; c < channels; ++c) {
const uint8_t* src = audio_frame->get_data(c);
uint8_t* dst = out + c * bytes_per_sample;

for (int n = 0; n < nb_samples; ++n) {
memcpy(dst,
src + n * bytes_per_sample,
bytes_per_sample);

dst += frame_size;
}
}

// write Oboe
_audio_stream->write(out, nb_samples, 0);
}`

`void OboeAudioRenderImp::audio_render_thread()
{
IAVFrame::shared frame;
int ret;
IAudioFrame::shared audio_frame;
int nb_samples;

while(true){
if(_abart_thread_request){
LOGI("Android audio thread exit");
break;
}

ret = _audio_frame_queue.pop(frame, -1);
if(ret < 0){
LOGW("Android audio queue abort");
break;
}
audio_frame = std::dynamic_pointer_cast(frame);
if (!audio_frame) {
break;
}

if (audio_frame->get_channels() > 1 && is_planar_audio_format(audio_frame->get_sample_format())) {
interleave_audio(frame);
}
else {
nb_samples = OBOE_AUDIO_MIN_BUFFER_SIZE != audio_frame->get_nb_samples() ?
audio_frame->get_nb_samples() :
audio_frame->get_nb_samples();
if (_audio_stream && audio_frame->get_data(0)) {
auto oboe_ret = _audio_stream->write(audio_frame->get_data(0), nb_samples, 1000000); // timeout
if(oboe_ret.error() != Result::OK){
LOGW("Failed to write pcm for android, ret: {}", oboe_ret.error());
}
}
}

}
}`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.