Skip to content
Snippets Groups Projects
Commit e0627a18 authored by Adrien Béraud's avatar Adrien Béraud
Browse files

OpenSL: fix occasional crash

Change-Id: I8fcee2c5d722ca56db65f1ccc1051a3a4ee63664
parent 90eae94d
No related branches found
No related tags found
No related merge requests found
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "audio_common.h" #include "audio_common.h"
#include "buf_manager.h" #include "buf_manager.h"
#include "noncopyable.h"
#include <sys/types.h> #include <sys/types.h>
#include <SLES/OpenSLES_Android.h> #include <SLES/OpenSLES_Android.h>
...@@ -45,6 +46,8 @@ class AudioPlayer { ...@@ -45,6 +46,8 @@ class AudioPlayer {
public: public:
explicit AudioPlayer(ring::AudioFormat sampleFormat, SLEngineItf engine, SLint32 streamType); explicit AudioPlayer(ring::AudioFormat sampleFormat, SLEngineItf engine, SLint32 streamType);
~AudioPlayer(); ~AudioPlayer();
NON_COPYABLE(AudioPlayer);
bool start(); bool start();
void stop(); void stop();
bool started() const; bool started() const;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "audio_common.h" #include "audio_common.h"
#include "buf_manager.h" #include "buf_manager.h"
#include "noncopyable.h"
namespace ring { namespace ring {
namespace opensl { namespace opensl {
...@@ -43,6 +44,8 @@ class AudioRecorder { ...@@ -43,6 +44,8 @@ class AudioRecorder {
public: public:
explicit AudioRecorder(ring::AudioFormat, SLEngineItf engineEngine); explicit AudioRecorder(ring::AudioFormat, SLEngineItf engineEngine);
~AudioRecorder(); ~AudioRecorder();
NON_COPYABLE(AudioRecorder);
bool start(); bool start();
bool stop(); bool stop();
void setBufQueues(AudioQueue *freeQ, AudioQueue *recQ); void setBufQueues(AudioQueue *freeQ, AudioQueue *recQ);
......
...@@ -149,13 +149,8 @@ public: ...@@ -149,13 +149,8 @@ public:
private: private:
NON_COPYABLE(ProducerConsumerQueue); NON_COPYABLE(ProducerConsumerQueue);
std::vector<T> buffer_; std::vector<T> buffer_;
std::atomic<int> read_ { 0 };
// forcing cache line alignment to eliminate false sharing of the std::atomic<int> write_ { 0 };
// frequently-updated read and write pointers. The object is to never
// let these get into the "shared" state where they'd cause a cache miss
// for every write.
alignas(CACHE_ALIGN) std::atomic<int> read_ { 0 };
alignas(CACHE_ALIGN) std::atomic<int> write_ { 0 };
}; };
struct sample_buf { struct sample_buf {
...@@ -169,6 +164,15 @@ struct sample_buf { ...@@ -169,6 +164,15 @@ struct sample_buf {
o.cap_ = 0; o.cap_ = 0;
o.size_ = 0; o.size_ = 0;
} }
sample_buf& operator=(sample_buf&& o) {
buf_ = o.buf_;
cap_ = o.cap_;
size_ = o.size_;
o.buf_ = nullptr;
o.cap_ = 0;
o.size_ = 0;
return *this;
}
~sample_buf() { ~sample_buf() {
if (buf_) delete[] buf_; if (buf_) delete[] buf_;
...@@ -177,16 +181,3 @@ struct sample_buf { ...@@ -177,16 +181,3 @@ struct sample_buf {
}; };
using AudioQueue = ProducerConsumerQueue<sample_buf*>; using AudioQueue = ProducerConsumerQueue<sample_buf*>;
__inline__ std::vector<sample_buf>
allocateSampleBufs(unsigned count, size_t sizeInByte)
{
std::vector<sample_buf> bufs;
if (!count || !sizeInByte)
return bufs;
bufs.reserve(count);
size_t allocSize = (sizeInByte + 3) & ~3; // padding to 4 bytes aligned
for(unsigned i =0; i < count; i++)
bufs.emplace_back(allocSize, sizeInByte);
return bufs;
}
...@@ -136,6 +136,19 @@ OpenSLLayer::stopStream() ...@@ -136,6 +136,19 @@ OpenSLLayer::stopStream()
bufs_.clear(); bufs_.clear();
} }
std::vector<sample_buf>
allocateSampleBufs(unsigned count, size_t sizeInByte)
{
std::vector<sample_buf> bufs;
if (!count || !sizeInByte)
return bufs;
bufs.reserve(count);
size_t allocSize = (sizeInByte + 3) & ~3; // padding to 4 bytes aligned
for(unsigned i =0; i < count; i++)
bufs.emplace_back(allocSize, sizeInByte);
return bufs;
}
void void
OpenSLLayer::initAudioEngine() OpenSLLayer::initAudioEngine()
{ {
......
...@@ -175,18 +175,18 @@ class OpenSLLayer : public AudioLayer { ...@@ -175,18 +175,18 @@ class OpenSLLayer : public AudioLayer {
AudioQueue freeRingBufQueue_ {BUF_COUNT}; AudioQueue freeRingBufQueue_ {BUF_COUNT};
AudioQueue ringBufQueue_ {BUF_COUNT}; AudioQueue ringBufQueue_ {BUF_COUNT};
std::thread playThread; std::mutex playMtx {};
std::mutex playMtx; std::condition_variable playCv {};
std::condition_variable playCv; std::thread playThread {};
AudioQueue freeRecBufQueue_ {BUF_COUNT}; //Owner of the queue AudioQueue freeRecBufQueue_ {BUF_COUNT}; //Owner of the queue
AudioQueue recBufQueue_ {BUF_COUNT}; //Owner of the queue AudioQueue recBufQueue_ {BUF_COUNT}; //Owner of the queue
std::thread recThread; std::mutex recMtx {};
std::mutex recMtx; std::condition_variable recCv {};
std::condition_variable recCv; std::thread recThread {};
std::vector<sample_buf> bufs_; std::vector<sample_buf> bufs_ {};
AudioFormat hardwareFormat_ {AudioFormat::MONO()}; AudioFormat hardwareFormat_ {AudioFormat::MONO()};
size_t hardwareBuffSize_ {BUFFER_SIZE}; size_t hardwareBuffSize_ {BUFFER_SIZE};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment