-
Notifications
You must be signed in to change notification settings - Fork 565
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
add input capture support to OpenSL wrapper #26
Conversation
Put Engine and OutputMixer into Singleton classes. Create separate input and output classes.
Also fix some bugs in OpenSL ES implementation and replace asserts with error returns.
Use mutex. Better singleton behavior. Separate files for each class.
src/opensles/AudioStreamOpenSLES.h
Outdated
@@ -64,8 +61,23 @@ class AudioStreamOpenSLES : public AudioStreamBuffered { | |||
|
|||
int32_t getFramesPerBurst() override; | |||
|
|||
static SLuint32 getDefaultByteOrder(); | |||
|
|||
virtual int chanCountToChanMask(int chanCount) = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this method needs to be declared as part of the interface? It doesn't seem to be used in any common code, only in particular implementations. Also, it can be made static.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made it protected. It was already static. It is used by input and output streams to open a stream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry if I didn't explain my point clear enough. What I was trying to say is that virtual methods in the base class usually exist because there is either an external client or common code in the base class that uses them. For chanCountToChanMask, the usages only seem to be in the derived classes (in and out streams). So why not just define these methods in the derived classes?
Putting chanCountToChanMask doesn't help with code reuse, it only pollutes the interface definition.
|
||
case 2: | ||
channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't this defined as SL_ANDROID_SPEAKER_STEREO? Then the masks above can use it as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
#define SL_ANDROID_SPEAKER_QUAD (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT \ | ||
| SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT) | ||
|
||
#define SL_ANDROID_SPEAKER_5DOT1 (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be defined as an extension to QUAD.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
||
result = AudioStreamOpenSLES::registerBufferQueueCallback(); | ||
if (SL_RESULT_SUCCESS != result) { | ||
LOGE("get bufferqueue interface:%p result:%s", mSimpleBufferQueueInterface, getSLErrStr(result)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't this error message being printed by registerBufferQueueCallback? You seem to have the same code in the output stream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is printed in registerBufferQueueCallback() so I removed it from the input and output streams.
src/opensles/EngineOpenSLES.cpp
Outdated
|
||
EngineOpenSLES *EngineOpenSLES::getInstance() { | ||
static EngineOpenSLES sInstance; | ||
return &sInstance; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is preferred to return a reference (EngineOpenSLES&) rather than pointer for preventing clients from attempting to calling 'delete' on it or putting it into a smart pointer.
Also, references can't be null which makes caller's life easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/opensles/OpenSLESUtilities.cpp
Outdated
return SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT; | ||
case AudioFormat::Float: | ||
return SL_ANDROID_PCM_REPRESENTATION_FLOAT; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default: ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/opensles/OutputMixerOpenSLES.cpp
Outdated
|
||
OutputMixerOpenSL *OutputMixerOpenSL::getInstance() { | ||
static OutputMixerOpenSL sInstance; | ||
return &sInstance; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same note about returning the reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/opensles/OutputMixerOpenSLES.h
Outdated
|
||
private: | ||
std::mutex mLock; | ||
std::atomic<int32_t> mOpenCount{0}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same note about atomicity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
SLDataSource *audioSource, | ||
SLDataSink *audioSink); | ||
|
||
private: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The constructor and the destructor need to be made private, and copy and assignment constructors deleted. Otherwise, someone could make another instance of this singleton.
See example code here: http://www.modernescpp.com/index.php/thread-safe-initialization-of-a-singleton
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
SLresult createAudioPlayer(SLObjectItf *objectItf, | ||
SLDataSource *audioSource); | ||
|
||
private: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same note about the need to hide and delete constructors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -0,0 +1,219 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file must be added to CMakeLists.txt so that clients can build it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the relevant part of the CMakeLists.txt updated so this version builds and links correctly:
set (oboe_sources
src/aaudio/AAudioLoader.cpp
src/aaudio/AudioStreamAAudio.cpp
src/common/LatencyTuner.cpp
src/common/AudioStream.cpp
src/common/AudioStreamBuilder.cpp
src/common/Utilities.cpp
src/fifo/FifoBuffer.cpp
src/fifo/FifoController.cpp
src/fifo/FifoControllerBase.cpp
src/fifo/FifoControllerIndirect.cpp
src/opensles/AudioInputStreamOpenSLES.cpp
src/opensles/AudioOutputStreamOpenSLES.cpp
src/opensles/AudioStreamBuffered.cpp
src/opensles/AudioStreamOpenSLES.cpp
src/opensles/EngineOpenSLES.cpp
src/opensles/OpenSLESUtilities.cpp
src/opensles/OutputMixerOpenSLES.cpp
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
} | ||
|
||
// These will wind up in <SLES/OpenSLES_Android.h> | ||
#define SL_ANDROID_SPEAKER_QUAD (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better practice to use constexpr
here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
return Result::ErrorInternal; | ||
} | ||
|
||
SLuint32 bitsPerSample = getBytesPerSample() * OBOE_BITS_PER_BYTE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use constexpr
for this oboe constant and add it to the oboe namespace. The usual convention is to prefix constants with k so this would end up as oboe::kBitsPerByte
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/opensles/AudioStreamOpenSLES.h
Outdated
|
||
namespace oboe { | ||
|
||
#define OBOE_BITS_PER_BYTE 8 // common value TODO modernize |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See previous comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Use constexpr. Add new files to CMakeLists.txt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please resolve the note about chanCountToChanMask before submitting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!! Really excited to see this major feature implemented.
Refactored the OpenSL ES code.
Moved static functions into classes.
Split into an Input and Output stream.
Added RECORD support.
Added some thread safety to EngineOpenSLES.
Fixed some bugs and removed asserts.