How to read data from a stream using callback function. Oboe-Android

405 views Asked by At

I'm currently working on a project where I need low-latency audio, so I decided to use Oboe (google library) to work with it.

I've read the documentation but multiple questions arise from it.

First, once I create my stream using the builder pattern, open the stream and request the stream to start, how can I capture the data coming in from the mic?

I know there are two ways: using the read function or a callback.

QUESTIONS:

  1. But if I use the read function how can I make sure it is being call as long as the stream is started?

  2. How can I use the callback to obtain the data and process it?

I'll leave my code below

void HelloOboeEngine::start() {
    isRecording = true;

    oboe::Result result = createStream();
    if (result != oboe::Result::OK) {
        closeStream(mRecordingStream);
    }

    result = mRecordingStream->requestStart();
    if (result != oboe::Result::OK) {
        closeStream(mRecordingStream);
    }
    
}


oboe::Result HelloOboeEngine::createStream() {
    oboe::AudioStreamBuilder builder;
    return builder.setPerformanceMode(oboe::PerformanceMode::LowLatency)
            ->setDirection(oboe::Direction::Input)
            ->setFormat(mFormat)
            ->setFormatConversionAllowed(true)
            ->setChannelConversionAllowed(true)
            ->setSampleRateConversionQuality(oboe::SampleRateConversionQuality::Medium)
            ->openStream(mRecordingStream);
}

void HelloOboeEngine::closeStream(std::shared_ptr<oboe::AudioStream> &stream) {
    if (stream) {
        oboe::Result result = stream->stop();
        if (result != oboe::Result::OK) {
            LOGW("Error stopping stream: %s", oboe::convertToText(result));
        }
        result = stream->close();
        if (result != oboe::Result::OK) {
            LOGE("Error closing stream: %s", oboe::convertToText(result));
        } else {
            LOGW("Successfully closed stream");
        }
        stream.reset();
    }
}
1

There are 1 answers

0
Hpsaturn On

You need first extend your class to override and get the data from the callback in your header file, like this:

class AndroidAudioDeviceManager : public oboe::AudioStreamCallback {

Set the callback in the builder in your class like this:

oboe::AudioStreamBuilder *AndroidAudioDeviceManager::setupPlaybackStreamParameters(
        oboe::AudioStreamBuilder *builder) {
    builder->setDataCallback(this)
            ->setErrorCallback(this)
            ->setDeviceId(mPlaybackDeviceId)
            ->setDirection(oboe::Direction::Output)
            ->setChannelCount(mOutputChannelCount);

    return setupCommonStreamParameters(builder);
}

And write your implementation, overriding the method:

oboe::DataCallbackResult AndroidAudioDeviceManager::onAudioReady(
        oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames) {
    
    oboe::DataCallbackResult callbackResult = oboe::DataCallbackResult::Continue;
    int32_t actualFramesRead = 0;

    // Silence the output.
    int32_t numBytes = numFrames * outputStream->getBytesPerFrame();
    memset(audioData, 0 /* value */, numBytes);

    // YOUR CODE ...

    return callbackResult;
}