summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2012-07-20 10:44:12 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2012-07-20 12:16:20 +0800
commit8667b6bcdfabe2108ab74591d9090951fe63010f (patch)
tree54c845c4eac3456e540d2b13f6b7cf5a1831b046
parent3f52d14271f8a650a1f63512e6f2114ce26d8d25 (diff)
Localized the mixer output stream mutex
Reduce contention on the device lock a lot.
-rw-r--r--src/device_mixer.cpp68
-rw-r--r--src/device_mixer.h2
2 files changed, 42 insertions, 28 deletions
diff --git a/src/device_mixer.cpp b/src/device_mixer.cpp
index 3f2d61e..09a640a 100644
--- a/src/device_mixer.cpp
+++ b/src/device_mixer.cpp
@@ -37,17 +37,26 @@ namespace audiere {
MixerDevice::read(const int sample_count, void* samples) {
// ADR_GUARD("MixerDevice::read");
- SYNCHRONIZED(this);
+ bool any_playing = false;
+
+ typedef RefPtr<MixerStream> MixerStreamPtr;
+ std::list<MixerStreamPtr> streams; {
+ SYNCHRONIZED(this);
// ADR_LOG("done locking mixer device");
- // are any sources playing?
- bool any_playing = false;
- for (std::list<MixerStream*>::iterator i = m_streams.begin();
- i != m_streams.end();
- ++i)
- {
- any_playing |= (*i)->m_is_playing;
+ // are any sources playing?
+ for (std::list<MixerStream*>::iterator i = m_streams.begin();
+ i != m_streams.end();
+ ++i)
+ {
+ if ((*i)->m_is_playing) {
+ MixerStream* stream = *i;
+
+ streams.push_back(stream);
+ any_playing = true;
+ }
+ }
}
// if not, return zeroed samples
@@ -69,9 +78,9 @@ namespace audiere {
s32 mix_buffer[BUFFER_SIZE * 2];
memset(mix_buffer, 0, sizeof(mix_buffer));
-
- for (std::list<MixerStream*>::iterator s = m_streams.begin();
- s != m_streams.end();
+
+ for (std::list<MixerStreamPtr>::iterator s = streams.begin();
+ s != streams.end();
++s)
{
if ((*s)->m_is_playing) {
@@ -107,8 +116,6 @@ namespace audiere {
int rate)
: m_device(device)
{
- SYNCHRONIZED(m_device.get());
-
m_source = new Resampler(source, rate);
m_last_l = 0;
m_last_r = 0;
@@ -116,6 +123,7 @@ namespace audiere {
m_volume = 255;
m_pan = 0;
+ SYNCHRONIZED(m_device.get());
m_device->m_streams.push_back(this);
}
@@ -128,16 +136,20 @@ namespace audiere {
void
MixerStream::play() {
- SYNCHRONIZED(m_device.get());
+ SYNCHRONIZED(this);
+
m_is_playing = true;
}
void
MixerStream::stop() {
- SYNCHRONIZED(m_device.get());
+ SYNCHRONIZED(this);
+
if (m_is_playing) {
m_is_playing = false;
+
+ SYNCHRONIZED(m_device.get());
m_device->fireStopEvent(this, StopEvent::STOP_CALLED);
} else {
m_is_playing = false;
@@ -147,70 +159,67 @@ namespace audiere {
bool
MixerStream::isPlaying() {
- SYNCHRONIZED(m_device.get());
return m_is_playing;
}
void
MixerStream::reset() {
- SYNCHRONIZED(m_device.get());
+ SYNCHRONIZED(this);
m_source->reset();
}
void
MixerStream::setRepeat(bool repeat) {
- SYNCHRONIZED(m_device.get());
+ SYNCHRONIZED(this);
m_source->setRepeat(repeat);
}
bool
MixerStream::getRepeat() {
- SYNCHRONIZED(m_device.get());
+ SYNCHRONIZED(this);
return m_source->getRepeat();
}
void
MixerStream::setVolume(float volume) {
- SYNCHRONIZED(m_device.get());
+ SYNCHRONIZED(this);
m_volume = int(volume * 255.0f + 0.5f);
}
float
MixerStream::getVolume() {
- SYNCHRONIZED(m_device.get());
return (m_volume / 255.0f);
}
void
MixerStream::setPan(float pan) {
- SYNCHRONIZED(m_device.get());
+ SYNCHRONIZED(this);
m_pan = int(pan * 255.0f);
}
float
MixerStream::getPan() {
- SYNCHRONIZED(m_device.get());
return m_pan / 255.0f;
}
void
MixerStream::setPitchShift(float shift) {
- SYNCHRONIZED(m_device.get());
+ SYNCHRONIZED(this);
m_source->setPitchShift(shift);
}
float
MixerStream::getPitchShift() {
- SYNCHRONIZED(m_device.get());
+ SYNCHRONIZED(this);
return m_source->getPitchShift();
}
@@ -229,20 +238,22 @@ namespace audiere {
void
MixerStream::setPosition(int position) {
- SYNCHRONIZED(m_device.get());
+ SYNCHRONIZED(this);
m_source->setPosition(position);
}
int
MixerStream::getPosition() {
- SYNCHRONIZED(m_device.get());
+ SYNCHRONIZED(this);
return m_source->getPosition();
}
void
MixerStream::read(int frame_count, s16* buffer) {
+ SYNCHRONIZED(this);
+
unsigned read = m_source->read(frame_count, buffer);
s16* out = buffer;
@@ -251,7 +262,10 @@ namespace audiere {
m_source->reset();
if (m_is_playing) {
m_is_playing = false;
+
// let subscribers know that the sound was stopped
+ SYNCHRONIZED(m_device.get());
+
m_device->fireStopEvent(this, StopEvent::STREAM_ENDED);
} else {
m_is_playing = false;
diff --git a/src/device_mixer.h b/src/device_mixer.h
index 87817da..8ddd674 100644
--- a/src/device_mixer.h
+++ b/src/device_mixer.h
@@ -49,7 +49,7 @@ namespace audiere {
};
- class MixerStream : public RefImplementation<OutputStream> {
+ class MixerStream : public RefImplementation<OutputStream>, public Mutex {
public:
MixerStream(MixerDevice* device, SampleSource* source, int rate);
~MixerStream();