device_null.cpp

Go to the documentation of this file.
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& /*parameters*/) {
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   const char*
00078   NullAudioDevice::getName() {
00079     return "null";
00080   }
00081 
00082 
00083   void
00084   NullAudioDevice::removeStream(NullOutputStream* stream) {
00085     SYNCHRONIZED(this);
00086     m_streams.remove(stream);
00087   }
00088 
00089 
00090   NullOutputStream::NullOutputStream(
00091     NullAudioDevice* device,
00092     SampleSource* source)
00093   : m_device(device)
00094   , m_source(source)
00095   , m_is_playing(false)
00096   , m_volume(1)
00097   , m_pan(0)
00098   , m_shift(1)
00099   , m_last_update(0)
00100   {
00101     ADR_GUARD("NullOutputStream::NullOutputStream");
00102     m_source->getFormat(m_channel_count, m_sample_rate, m_sample_format);
00103   }
00104 
00105 
00106   NullOutputStream::~NullOutputStream() {
00107     m_device->removeStream(this);
00108   }
00109 
00110 
00111   void
00112   NullOutputStream::play() {
00113     ADR_GUARD("NullOutputStream::play");
00114     m_is_playing = true;
00115     resetTimer();
00116   }
00117 
00118 
00119   void
00120   NullOutputStream::stop() {
00121     doStop(false);
00122   }
00123 
00124 
00125   void
00126   NullOutputStream::reset() {
00127     SYNCHRONIZED(m_device.get());
00128     resetTimer();
00129     m_source->reset();
00130   }
00131 
00132 
00133   bool
00134   NullOutputStream::isPlaying() {
00135     return m_is_playing;
00136   }
00137 
00138 
00139   void
00140   NullOutputStream::setRepeat(bool repeat) {
00141     SYNCHRONIZED(m_device.get());
00142     m_source->setRepeat(repeat);
00143   }
00144 
00145 
00146   bool
00147   NullOutputStream::getRepeat() {
00148     SYNCHRONIZED(m_device.get());
00149     return m_source->getRepeat();
00150   }
00151 
00152 
00153   void
00154   NullOutputStream::setVolume(float volume) {
00155     m_volume = volume;
00156   }
00157 
00158 
00159   float
00160   NullOutputStream::getVolume() {
00161     return m_volume;
00162   }
00163 
00164   
00165   void
00166   NullOutputStream::setPan(float pan) {
00167     m_pan = pan;
00168   }
00169 
00170   
00171   float
00172   NullOutputStream::getPan() {
00173     return m_pan;
00174   }
00175 
00176 
00177   void
00178   NullOutputStream::setPitchShift(float shift) {
00179     m_shift = shift;
00180   }
00181 
00182 
00183   float
00184   NullOutputStream::getPitchShift() {
00185     return m_shift;
00186   }
00187 
00188 
00189   bool
00190   NullOutputStream::isSeekable() {
00191     return m_source->isSeekable();
00192   }
00193 
00194 
00195   int
00196   NullOutputStream::getLength() {
00197     return m_source->getLength();
00198   }
00199 
00200 
00201   void
00202   NullOutputStream::setPosition(int position) {
00203     SYNCHRONIZED(m_device.get());
00204     m_source->setPosition(position);
00205     reset();
00206   }
00207 
00208 
00209   int
00210   NullOutputStream::getPosition() {
00211     return m_source->getPosition();
00212   }
00213 
00214 
00215   void
00216   NullOutputStream::doStop(bool internal) {
00217     if (m_is_playing) {
00218       m_is_playing = false;
00219       if (!internal) {
00220         // let subscribers know that the sound was stopped
00221         m_device->fireStopEvent(this, StopEvent::STOP_CALLED);
00222       }
00223     } else {
00224       m_is_playing = false;
00225     }
00226   }
00227 
00228 
00229   void
00230   NullOutputStream::resetTimer() {
00231     m_last_update = GetNow();
00232   }
00233 
00234 
00235   void
00236   NullOutputStream::update() {
00237     ADR_GUARD("NullOutputStream::update");
00238 
00239     if (m_is_playing) {
00240       ADR_LOG("Null output stream is playing");
00241 
00242       // get number of microseconds elapsed since last playing update
00243       // so we can read that much time worth of samples
00244       u64 now = GetNow();
00245       u64 elapsed = now - m_last_update;
00246 
00247       double shifted_time = m_shift * s64(elapsed) / 1000000.0;  // in seconds
00248       int samples_to_read = int(m_sample_rate * shifted_time);
00249 
00250       ADR_IF_DEBUG {
00251         char str[100];
00252         sprintf(str, "Samples to read: %d", samples_to_read);
00253         ADR_LOG(str);
00254       }
00255 
00256       int samples_read = dummyRead(samples_to_read);
00257 
00258       if (samples_read != samples_to_read) {
00259         ADR_LOG("Stopping null output stream");
00260         m_source->reset();
00261         doStop(true);
00262         m_device->fireStopEvent(this, StopEvent::STREAM_ENDED);
00263       }
00264 
00265       m_last_update = now;
00266     }
00267   }
00268 
00269 
00270   int
00271   NullOutputStream::dummyRead(int samples_to_read) {
00272     int total = 0;  // number of samples read so far
00273 
00274     const int bytes_per_sample = GetSampleSize(m_sample_format);
00275 
00276     // read samples into dummy buffer, counting the number we actually read
00277     u8* dummy = new u8[1024 * m_channel_count * bytes_per_sample];
00278     while (samples_to_read > 0) {
00279       int read = std::min(1024, samples_to_read);
00280       int actual_read = m_source->read(read, dummy);
00281       total += actual_read;
00282       samples_to_read -= actual_read;
00283       if (actual_read < read) {
00284         break;
00285       }
00286     }
00287 
00288     delete[] dummy;
00289     return total;
00290   }
00291 
00292 }

Generated on Mon Feb 13 23:07:46 2006 for audiere by  doxygen 1.4.6