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

problem with calling oboe::AudioStream-functions #48

Closed
SchmadenSchmuki opened this issue Jan 12, 2018 · 9 comments
Closed

problem with calling oboe::AudioStream-functions #48

SchmadenSchmuki opened this issue Jan 12, 2018 · 9 comments

Comments

@SchmadenSchmuki
Copy link

SchmadenSchmuki commented Jan 12, 2018

Experienced the following problem and I think (hope) it's not a fault in my code:
I have "static oboe::AudioStream* pOboeAudioStream(nullptr);" after my #include-lines in the native-lib.cpp.
When I call "oboe::AudioStreamBuilder.open(&pOboeAudioStream);" directly in a native function, it works as expected, stream is opened and I can call the stream functions also outside this specific function.

But when I go one step further nested I'm getting troubles.
So when I try something like:
JNIEXPORT jint JNICALL
Java_schmaden_programme_android_test_MainActivity_makeOboeAudioStream()
{
callFunctionThatDoesAllTheBuilderSetUpAndOpensStream(pOboeAudioStream);
return 0;
}
I get a crash with the first call that uses pOboeAudioStream outside of callFunctionThatD... . So I can call requestStart() or any other function related to pOboeAudioStream only inside this function.
The only way to get some sound is to call requestStart() inside of callFunctionThatD... .

If I call requestStop() outside callFunctionThatD... in the following way:
if(pOboeAudioStream != nullptr) pOboeAudioStream->requestStop();
nothing happens, no stopping, no crash.

As said before it works with the first method, so it's not a problem when you know it, otherwise it's pretty unexpected.

I set up a callback in the builder (if that matter), the code was executed on Android emulator API 27.

@dturner
Copy link
Collaborator

dturner commented Jan 12, 2018

What is the crash? Presumably a null pointer dereference? Please could you post the stack trace.

@SchmadenSchmuki
Copy link
Author

SchmadenSchmuki commented Jan 12, 2018

The last line in android studio logcat is:
01-12 11:29:12.894 29799-29799/jogi.programme.android.testrequeststartproblem A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 29799 (eststartproblem), pid 29799 (eststartproblem)
Everything before is normal.
Looks like it could be what you said.
For a stack trace, can I get that easily, do I have to use systrace. If so, then that would take some time, I'm not into that yet (though I'm planning to get to know it at some point).

So, do you think that's from my code?

@dturner
Copy link
Collaborator

dturner commented Jan 12, 2018

Please post everything that comes after the SIGSEGV line, that should give more of a clue as to where the crash is coming from.

@SchmadenSchmuki
Copy link
Author

SchmadenSchmuki commented Jan 12, 2018

You're right, it is a null pointer dereference.
Wenn I log the pointer it prints 0x0. So the behaviour from that point is consistent.

What I don't understand is why I get this problem under the described circumstances (I still think it's not a fault in my code).
The difference between working and not working code is (exactly) like this:

working:
JNIEXPORT jint JNICALL
Java_schmaden_programme_android_test_MainActivity_makeOboeAudioStream(
JNIEnv env,
jobject /
this */)
{
OpenOboeStreamFunctions openOboeStreamFunctions;
oboe::AudioStreamBuilder localBuilder;

openOboeStreamFunctions.configureCallbackStreamBuilder(&localBuilder, &oboeClassWithCallback);
oboe::Result result(localBuilder.openStream(&pOboeAudioStream));

return 0;

}

problem:
JNIEXPORT jint JNICALL
Java_schmaden_programme_android_test_MainActivity_makeOboeAudioStream(
JNIEnv env,
jobject /
this */)
{
OpenOboeStreamFunctions openOboeStreamFunctions;
oboe::AudioStreamBuilder localBuilder;

openOboeStreamFunctions.configureCallbackStreamBuilder(&localBuilder, &oboeClassWithCallback);
openOboeStreamFunctions.openStreamRequestStart(pOboeAudioStream, &localBuilder); 

return 0;

}
with openStreamRequestStart being:
int16_t OpenOboeStreamFunctions::openStreamRequestStart(oboe::AudioStream* stream,
oboe::AudioStreamBuilder* builder)
{
oboe::Result result(builder->openStream(&stream));
if (result != oboe::Result::OK)
{
__android_log_print(ANDROID_LOG_ERROR, "AudioEngine", "Error opening stream %s",
oboe::convertToText(result));
return -108;
}
result= stream->requestStart(); // so sound output is started and heard
return 0;
} // from here stream is a nullpointer

In both cases pOboeAudioStream and oboeClassWithCallback are like this (immediately written after the #include-lines):
static oboe::AudioStream* pOboeAudioStream(nullptr);
static CallbackForTest oboeClassWithCallback;

I think it's also possible that the bug was always there but in the way for example hello-aaudio is written, it hard to see. Because, if I got it right, in hello-audio the callback is always running and when the output should be silenced it works with memset 0, an this way something like requestStop is never called.

@philburk
Copy link
Collaborator

philburk commented Jan 13, 2018

I suspect the problem is in not passing a pointer to the stream pointer:

This code:

  int16_t OpenOboeStreamFunctions::openStreamRequestStart(oboe::AudioStream* stream,
  oboe::AudioStreamBuilder* builder) {
     oboe::Result result(builder->openStream(&stream));

should use "**stream" not "*stream":
(UPDATED 1/13/18 to restore double star removed by editor)

  int16_t OpenOboeStreamFunctions::openStreamRequestStart(oboe::AudioStream** stream,
  oboe::AudioStreamBuilder* builder) {
     oboe::Result result(builder->openStream(stream));         // <== NO & !!!!!

Then call with an &:
openOboeStreamFunctions.openStreamRequestStart(&pOboeAudioStream, &localBuilder);

Let me know if that helps.

@SchmadenSchmuki
Copy link
Author

Thanks for the help.
Tried
oboe::Result result(builder->openStream(stream)); // <== NO & !!!!!
but it doesn't compile, I get the following error:
Error:(57, 45) error: cannot initialize a parameter of type 'oboe::AudioStream **' with an lvalue of type 'oboe::AudioStream *'
Strange thing is, when press ctrl and hover over openStream, the preview I get says declared in "AudioStreamBuilder.h" and "oboe::AudioStream *" is needed.
When I follow the link, android studio shows me "AudioStreamBuilder.cpp" and "oboe::AudioStream **"
for calling the function.

@philburk
Copy link
Collaborator

philburk commented Jan 13, 2018

I just notice that GitHub removed the double star from my message! The code that I see now in my email is wrong! If I try to fix it then I see the proper code. I will try to edit it with the code tag.

openStreamRequestStart() must be declared with a double star, a pointer to a pointer. But I can't seem to type that without it getting removed.

The builder->openStream() call passes back a pointer to an AudioStream. So you must pass it a pointer to a pointer.

If Preview looks out of sync with the real code, try adding a comment to your CMakeLists.txt file and doing a gradle sync. That can sometime kick it back into sync.

@SchmadenSchmuki
Copy link
Author

@philburk
Thanks you, that worked, will make my life a lot easier.

Really have to learn the basics better, never would have thought of that.
(To be honest, I still don't get it, because in the working case I also used openStream(&pOboeAudioStream);.
The only difference I see is one time the function was called over the instance (the working version localBuilder.openStream(&pOboeAudioStream);), the other time with pointer dereference of builderpointer (the problemversion builder->openStream(&stream);), with pOboeAudioStream and stream both being an oboe::AudioStream*.
But I have to read about, think on and play with that tomorrow.)

Thanks a lot.

@philburk
Copy link
Collaborator

You were passing Oboe a pointer to a pointer. That's good.

But you were passing a pointer to the variable declared in your function.
It received the pointer to the new stream. But it was immediately discarded.

After the fix, you passed a pointer to the variable declared in your object.
That is the one that needed to be set.

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

No branches or pull requests

3 participants