00001 #ifdef _MSC_VER
00002 #pragma warning(disable : 4786)
00003 #endif
00004
00005
00006 #include <algorithm>
00007 #include "device_mixer.h"
00008 #include "resampler.h"
00009 #include "utility.h"
00010
00011
00012 namespace audiere {
00013
00014 MixerDevice::MixerDevice(int rate) {
00015 m_rate = rate;
00016 }
00017
00018
00019 OutputStream*
00020 MixerDevice::openStream(SampleSource* source) {
00021 return (source ? new MixerStream(this, source, m_rate) : 0);
00022 }
00023
00024
00025 OutputStream*
00026 MixerDevice::openBuffer(
00027 void* samples, int frame_count,
00028 int channel_count, int sample_rate, SampleFormat sample_format)
00029 {
00030 return openStream(OpenBufferStream(
00031 samples, frame_count,
00032 channel_count, sample_rate, sample_format));
00033 }
00034
00035
00036 int
00037 MixerDevice::read(const int sample_count, void* samples) {
00038 ADR_GUARD("MixerDevice::read");
00039
00040 SYNCHRONIZED(this);
00041
00042 ADR_LOG("done locking mixer device");
00043
00044
00045 bool any_playing = false;
00046 for (std::list<MixerStream*>::iterator i = m_streams.begin();
00047 i != m_streams.end();
00048 ++i)
00049 {
00050 any_playing |= (*i)->m_is_playing;
00051 }
00052
00053
00054 if (!any_playing) {
00055 memset(samples, 0, 4 * sample_count);
00056 return sample_count;
00057 }
00058
00059 ADR_LOG("at least one stream is playing");
00060
00061
00062 static const int BUFFER_SIZE = 4096;
00063
00064
00065 s16* out = (s16*)samples;
00066 int left = sample_count;
00067 while (left > 0) {
00068 int to_mix = std::min(BUFFER_SIZE, left);
00069
00070 s32 mix_buffer[BUFFER_SIZE];
00071 memset(mix_buffer, 0, sizeof(mix_buffer));
00072
00073 for (std::list<MixerStream*>::iterator s = m_streams.begin();
00074 s != m_streams.end();
00075 ++s)
00076 {
00077 if ((*s)->m_is_playing) {
00078 s16 stream_buffer[BUFFER_SIZE * 2];
00079 (*s)->read(to_mix, stream_buffer);
00080 for (int i = 0; i < to_mix * 2; ++i) {
00081 mix_buffer[i] += stream_buffer[i];
00082 }
00083 }
00084 }
00085
00086
00087 for (int i = 0; i < to_mix * 2; ++i) {
00088 s32 mixed = mix_buffer[i];
00089 s16 o;
00090 if (mixed < -32768) {
00091 o = -32768;
00092 } else if (mixed > 32767) {
00093 o = 32767;
00094 } else {
00095 o = mixed;
00096 }
00097 *out++ = o;
00098 }
00099
00100 left -= to_mix;
00101 }
00102
00103 return sample_count;
00104 }
00105
00106
00107 MixerStream::MixerStream(
00108 MixerDevice* device,
00109 SampleSource* source,
00110 int rate)
00111 {
00112 m_device = device;
00113 m_resampler = new Resampler(source, rate);
00114 m_source = new RepeatableStream(m_resampler.get());
00115 m_last_l = 0;
00116 m_last_r = 0;
00117 m_is_playing = false;
00118 m_volume = 255;
00119 m_pan = 0;
00120
00121 SYNCHRONIZED(m_device.get());
00122 m_device->m_streams.push_back(this);
00123 }
00124
00125
00126 MixerStream::~MixerStream() {
00127 SYNCHRONIZED(m_device.get());
00128 m_device->m_streams.remove(this);
00129 }
00130
00131
00132 void
00133 MixerStream::play() {
00134 SYNCHRONIZED(m_device.get());
00135 m_is_playing = true;
00136 }
00137
00138
00139 void
00140 MixerStream::stop() {
00141 SYNCHRONIZED(m_device.get());
00142 m_is_playing = false;
00143 }
00144
00145
00146 bool
00147 MixerStream::isPlaying() {
00148 SYNCHRONIZED(m_device.get());
00149 return m_is_playing;
00150 }
00151
00152
00153 void
00154 MixerStream::reset() {
00155 SYNCHRONIZED(m_device.get());
00156 m_source->reset();
00157 }
00158
00159
00160 void
00161 MixerStream::setRepeat(bool repeat) {
00162 SYNCHRONIZED(m_device.get());
00163 m_source->setRepeat(repeat);
00164 }
00165
00166
00167 bool
00168 MixerStream::getRepeat() {
00169 SYNCHRONIZED(m_device.get());
00170 return m_source->getRepeat();
00171 }
00172
00173
00174 void
00175 MixerStream::setVolume(float volume) {
00176 SYNCHRONIZED(m_device.get());
00177 m_volume = int(volume * 255.0f + 0.5f);
00178 }
00179
00180
00181 float
00182 MixerStream::getVolume() {
00183 SYNCHRONIZED(m_device.get());
00184 return (m_volume / 255.0f);
00185 }
00186
00187
00188 void
00189 MixerStream::setPan(float pan) {
00190 SYNCHRONIZED(m_device.get());
00191 m_pan = int(pan * 255.0f);
00192 }
00193
00194
00195 float
00196 MixerStream::getPan() {
00197 SYNCHRONIZED(m_device.get());
00198 return m_pan / 255.0f;
00199 }
00200
00201
00202 void
00203 MixerStream::setPitchShift(float shift) {
00204 SYNCHRONIZED(m_device.get());
00205 m_resampler->setPitchShift(shift);
00206 }
00207
00208
00209 float
00210 MixerStream::getPitchShift() {
00211 SYNCHRONIZED(m_device.get());
00212 return m_resampler->getPitchShift();
00213 }
00214
00215
00216 bool
00217 MixerStream::isSeekable() {
00218 return m_source->isSeekable();
00219 }
00220
00221
00222 int
00223 MixerStream::getLength() {
00224 return m_source->getLength();
00225 }
00226
00227
00228 void
00229 MixerStream::setPosition(int position) {
00230 SYNCHRONIZED(m_device.get());
00231 m_source->setPosition(position);
00232 }
00233
00234
00235 int
00236 MixerStream::getPosition() {
00237 SYNCHRONIZED(m_device.get());
00238 return m_source->getPosition();
00239 }
00240
00241
00242 void
00243 MixerStream::read(int frame_count, s16* buffer) {
00244 unsigned read = m_source->read(frame_count, buffer);
00245
00246
00247 if (read == 0) {
00248 m_is_playing = false;
00249 m_source->reset();
00250 }
00251
00252 int l_volume, r_volume;
00253 if (m_pan < 0) {
00254 l_volume = 255;
00255 r_volume = 255 + m_pan;
00256 } else {
00257 l_volume = 255 - m_pan;
00258 r_volume = 255;
00259 }
00260
00261 l_volume *= m_volume;
00262 r_volume *= m_volume;
00263
00264 s16* out = buffer;
00265 for (int i = 0; i < read; ++i) {
00266 *out = *out * l_volume / 255 / 255;
00267 ++out;
00268 *out = *out * r_volume / 255 / 255;
00269 ++out;
00270 }
00271
00272 int l = m_last_l;
00273 int r = m_last_r;
00274
00275 if (read > 0) {
00276 l = out[-2];
00277 r = out[-1];
00278 }
00279
00280 for (int i = read; i < frame_count; ++i) {
00281 *out++ = m_last_l;
00282 *out++ = m_last_r;
00283 }
00284
00285 m_last_l = l;
00286 m_last_r = r;
00287 }
00288
00289 }