Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

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   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       // get number of microseconds elapsed since last playing update
00223       // so we can read that much time worth of samples
00224       u64 now = GetNow();
00225       u64 elapsed = now - m_last_update;
00226 
00227       double shifted_time = m_shift * s64(elapsed) / 1000000.0;  // in seconds
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;  // number of samples read so far
00252 
00253     const int bytes_per_sample = GetSampleSize(m_sample_format);
00254 
00255     // read samples into dummy buffer, counting the number we actually read
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 }

Generated on Sat Oct 12 01:43:02 2002 for audiere by doxygen1.2.17