00001 #ifdef _MSC_VER
00002 #pragma warning(disable : 4786)
00003 #endif
00004
00005
00006 #include <algorithm>
00007 #include <functional>
00008 #include "device_null.h"
00009 #include "timer.h"
00010 #include "threads.h"
00011 #include "utility.h"
00012
00013 namespace audiere {
00014
00015 NullAudioDevice*
00016 NullAudioDevice::create(const ParameterList& ) {
00017 return new NullAudioDevice;
00018 }
00019
00020
00021 NullAudioDevice::NullAudioDevice() {
00022 }
00023
00024
00025 NullAudioDevice::~NullAudioDevice() {
00026 ADR_GUARD("~NullAudioDevice");
00027
00028 ADR_ASSERT(m_streams.size() == 0,
00029 "Null output context should not die with open streams");
00030 }
00031
00032
00033 void
00034 NullAudioDevice::update() {
00035 ADR_GUARD("NullAudioDevice::update");
00036 SYNCHRONIZED(this);
00037
00038 StreamList::iterator i = m_streams.begin();
00039 for (; i != m_streams.end(); ++i) {
00040 (*i)->update();
00041 }
00042
00043 AI_Sleep(50);
00044 }
00045
00046
00047 OutputStream*
00048 NullAudioDevice::openStream(SampleSource* source) {
00049 ADR_GUARD("NullAudioDevice::openStream");
00050
00051 if (!source) {
00052 return 0;
00053 }
00054
00055 SYNCHRONIZED(this);
00056
00057 NullOutputStream* stream = new NullOutputStream(this, source);
00058 m_streams.push_back(stream);
00059 return stream;
00060 }
00061
00062
00063 OutputStream*
00064 NullAudioDevice::openBuffer(
00065 void* samples, int frame_count,
00066 int channel_count, int sample_rate, SampleFormat sample_format)
00067 {
00068 ADR_GUARD("NullAudioDevice::openBuffer");
00069
00070 RefPtr<SampleSource> source(OpenBufferStream(
00071 samples, frame_count,
00072 channel_count, sample_rate, sample_format));
00073 return openStream(source.get());
00074 }
00075
00076
00077 void
00078 NullAudioDevice::removeStream(NullOutputStream* stream) {
00079 SYNCHRONIZED(this);
00080 m_streams.remove(stream);
00081 }
00082
00083
00084 NullOutputStream::NullOutputStream(
00085 NullAudioDevice* device,
00086 SampleSource* source)
00087 : m_device(device)
00088 , m_source(new RepeatableStream(source))
00089 , m_is_playing(false)
00090 , m_volume(1)
00091 , m_pan(0)
00092 , m_shift(1)
00093 , m_last_update(0)
00094 {
00095 ADR_GUARD("NullOutputStream::NullOutputStream");
00096 m_source->getFormat(m_channel_count, m_sample_rate, m_sample_format);
00097 }
00098
00099
00100 NullOutputStream::~NullOutputStream() {
00101 m_device->removeStream(this);
00102 }
00103
00104
00105 void
00106 NullOutputStream::play() {
00107 ADR_GUARD("NullOutputStream::play");
00108 m_is_playing = true;
00109 resetTimer();
00110 }
00111
00112
00113 void
00114 NullOutputStream::stop() {
00115 m_is_playing = false;
00116 }
00117
00118
00119 void
00120 NullOutputStream::reset() {
00121 SYNCHRONIZED(m_device.get());
00122 resetTimer();
00123 m_source->reset();
00124 }
00125
00126
00127 bool
00128 NullOutputStream::isPlaying() {
00129 return m_is_playing;
00130 }
00131
00132
00133 void
00134 NullOutputStream::setRepeat(bool repeat) {
00135 SYNCHRONIZED(m_device.get());
00136 m_source->setRepeat(repeat);
00137 }
00138
00139
00140 bool
00141 NullOutputStream::getRepeat() {
00142 SYNCHRONIZED(m_device.get());
00143 return m_source->getRepeat();
00144 }
00145
00146
00147 void
00148 NullOutputStream::setVolume(float volume) {
00149 m_volume = volume;
00150 }
00151
00152
00153 float
00154 NullOutputStream::getVolume() {
00155 return m_volume;
00156 }
00157
00158
00159 void
00160 NullOutputStream::setPan(float pan) {
00161 m_pan = pan;
00162 }
00163
00164
00165 float
00166 NullOutputStream::getPan() {
00167 return m_pan;
00168 }
00169
00170
00171 void
00172 NullOutputStream::setPitchShift(float shift) {
00173 m_shift = shift;
00174 }
00175
00176
00177 float
00178 NullOutputStream::getPitchShift() {
00179 return m_shift;
00180 }
00181
00182
00183 bool
00184 NullOutputStream::isSeekable() {
00185 return m_source->isSeekable();
00186 }
00187
00188
00189 int
00190 NullOutputStream::getLength() {
00191 return m_source->getLength();
00192 }
00193
00194
00195 void
00196 NullOutputStream::setPosition(int position) {
00197 SYNCHRONIZED(m_device.get());
00198 m_source->setPosition(position);
00199 reset();
00200 }
00201
00202
00203 int
00204 NullOutputStream::getPosition() {
00205 return m_source->getPosition();
00206 }
00207
00208
00209 void
00210 NullOutputStream::resetTimer() {
00211 m_last_update = GetNow();
00212 }
00213
00214
00215 void
00216 NullOutputStream::update() {
00217 ADR_GUARD("NullOutputStream::update");
00218
00219 if (m_is_playing) {
00220 ADR_LOG("Null output stream is playing");
00221
00222
00223
00224 u64 now = GetNow();
00225 u64 elapsed = now - m_last_update;
00226
00227 double shifted_time = m_shift * s64(elapsed) / 1000000.0;
00228 int samples_to_read = int(m_sample_rate * shifted_time);
00229
00230 ADR_IF_DEBUG {
00231 char str[100];
00232 sprintf(str, "Samples to read: %d", samples_to_read);
00233 ADR_LOG(str);
00234 }
00235
00236 int samples_read = dummyRead(samples_to_read);
00237
00238 if (samples_read != samples_to_read) {
00239 ADR_LOG("Stopping null output stream");
00240 m_source->reset();
00241 stop();
00242 }
00243
00244 m_last_update = now;
00245 }
00246 }
00247
00248
00249 int
00250 NullOutputStream::dummyRead(int samples_to_read) {
00251 int total = 0;
00252
00253 const int bytes_per_sample = GetSampleSize(m_sample_format);
00254
00255
00256 u8* dummy = new u8[1024 * m_channel_count * bytes_per_sample];
00257 while (samples_to_read > 0) {
00258 int read = std::min(1024, samples_to_read);
00259 int actual_read = m_source->read(read, dummy);
00260 total += actual_read;
00261 samples_to_read -= actual_read;
00262 if (actual_read < read) {
00263 break;
00264 }
00265 }
00266
00267 delete[] dummy;
00268 return total;
00269 }
00270
00271 }