Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't initialize new AudioTrack instance #1

Open
MasterEx opened this issue Mar 17, 2013 · 4 comments
Open

Can't initialize new AudioTrack instance #1

MasterEx opened this issue Mar 17, 2013 · 4 comments
Labels

Comments

@MasterEx
Copy link
Owner

How to reproduce:

Click the Start/Stop button many times. App crashes.

The exception is thrown on AudioGenerator createPlayer().

The exception is about that:
AudioFlinger could not create track, status: -12
[android.media.AudioTrack ] Error code -20 when initializing AudioTrack.

Not sure why this is happening. My guess is that the AudioTrack binds some resources that later aren't properly released.

@ghost
Copy link

ghost commented May 9, 2018

Having the same issue!

Not... to worry! Boober Bunz is on the case!

I'm putting up a stackoverflow question on it right now.

@ghost
Copy link

ghost commented May 9, 2018

Oh wait I didn't realize you are the author of this app. Thanks for making this!!! Did you ever find out why this happens? I'm working on it... I'll definitely let you know if I can figure it out.

@MasterEx
Copy link
Owner Author

Hey! No, I haven't figured this out (at least I don't remember doing so 😄 ).

If you fix it, feel free to submit a pull request!

@mgood7123
Copy link

How to reproduce:

Click the Start/Stop button many times. App crashes.

The exception is thrown on AudioGenerator createPlayer().

The exception is about that:
AudioFlinger could not create track, status: -12
[android.media.AudioTrack ] Error code -20 when initializing AudioTrack.

Not sure why this is happening. My guess is that the AudioTrack binds some resources that later aren't properly released.

I have had this problem in Oboe

when calling AAudioStream_requestStart(); and AAudioStream_requestStop(); many times rapidly

the cause is a race condition internally

specifically

/*
 * IMPORTANT: avoid starting and stopping the `oboe::AudioStream *stream` rapidly
 * exact reason appears to due to a bug in the AAudio Legacy path for Android P (9),
 *
 * W/AudioStreamLegacy: processCallbackCommon() stopping because callback disabled
 * E/AudioTrack: EVENT_MORE_DATA requested 256 bytes but callback returned -1 bytes
 *
 * see https://github.com/google/oboe/issues/396 :
 *
 * When I returned oboe::DataCallbackResult::Stop in the input stream callback, the callback stopped
 * being called as expected, but the stream state remained in Stopping and never changed to Stopped.
 *
 * In this case, the callback stopped, but the stream state remained in Started with Errors
 * W/AudioStreamLegacy: processCallbackCommon() callback requested stop, fake an error and
 * E/AudioRecord: EVENT_MORE_DATA requested 384 bytes but callback returned -1 bytes
 *
 * And when I tried to restart the stream by calling requestStart(), it didn't work.
 *
 * That is due to a bug in the AAudio Legacy path for Android P (9).
 *
 * This and other bugs related to DataCallbackResult::Stop have been fixed for a future Android
 * release.
*/

the solution to this was

bool STREAM_STARTED = false; // we only use a single stream for now

bool Oboe_Stream_Start() {
    LOGW("Oboe_Init: requesting Start");
    AudioEngine.StartStream();
    LOGW("Oboe_Init: requested Start");
    STREAM_STARTED = true;
    return true;
}

bool Oboe_Stream_Stop() {
    LOGW("Oboe_Init: requesting Stop");
    AudioEngine.StopStream();
    LOGW("Oboe_Init: requested Stop");
    STREAM_STARTED = false;
    return true;
}

NATIVE(void, Oboe, Play)(JNIEnv *env, jobject type) {
    if (currentAudioTrack != NULL) {
        if (!STREAM_STARTED) Oboe_Stream_Start();
        currentAudioTrack->setPlaying(true);
    }
}

NATIVE(void, Oboe, Pause)(JNIEnv *env, jobject type) {
    if (currentAudioTrack != NULL) {
        currentAudioTrack->setPlaying(false);
    }
}

NATIVE(void, Oboe, Stop)(JNIEnv *env, jobject type) {
    if (currentAudioTrack != NULL) {
        if (STREAM_STARTED) Oboe_Stream_Stop();
        currentAudioTrack->setPlaying(false);
        currentAudioTrack->resetPlayHead();
    }
}

in that

when playback is requested, we start our stream ONLY if it has not been started

after that, we simply render our audio

void SoundRecording::renderAudio(int16_t *targetData, uint64_t totalFrames, SoundRecording *Audio){
    SoundRecordingAudioData * AudioData = Audio->AudioData;
    if (mIsPlaying) {

        // Check whether we're about to reach the end of the recording
        if (!mIsLooping && mReadFrameIndex + totalFrames >= mTotalFrames) {
            totalFrames = mTotalFrames - mReadFrameIndex;
            mIsPlaying = false;
        }

        if (mReadFrameIndex == 0) {
            GlobalTime.StartOfFile = true;
            GlobalTime.update(mReadFrameIndex, AudioData);
        }
        for (int i = 0; i < totalFrames; ++i) {
            for (int j = 0; j < AudioData->channelCount; ++j) {
                targetData[(i * AudioData->channelCount) + j] = Audio->Audio[(mReadFrameIndex * AudioData->channelCount) + j];
            }

            // Increment and handle wraparound
            if (++mReadFrameIndex >= mTotalFrames) {
                GlobalTime.EndOfFile = true;
                GlobalTime.update(mReadFrameIndex, AudioData);
                mReadFrameIndex = 0;
            } else {
                GlobalTime.update(mReadFrameIndex, AudioData);
            }
        }
    } else {
        // fill with zeros to output silence
        for (int i = 0; i < totalFrames * AudioData->channelCount; ++i) {
            targetData[i] = 0;
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants