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

output_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 "output_null.hpp"
00009 #include "input.hpp"
00010 #include "timer.hpp"
00011 #include "threads.hpp"
00012 #include "utility.hpp"
00013 
00014 
00016 
00017 NullOutputContext::NullOutputContext()
00018 {
00019 }
00020 
00022 
00023 NullOutputContext::~NullOutputContext()
00024 {
00025   ADR_ASSERT(m_streams.size() == 0,
00026     "Null output context should not die with open streams");
00027 }
00028 
00030 
00031 bool
00032 NullOutputContext::Initialize(const char* /*parameters*/)
00033 {
00034   return true;
00035 }
00036 
00038 
00039 void
00040 NullOutputContext::Update()
00041 {
00042   /*
00043     UGH.  We can't use VC6 here because you can't use mem_fun with void
00044     functions.  :(
00045   std::for_each(
00046     m_streams.begin(),
00047     m_streams.end(),
00048     std::mem_fun(&NullOutputStream::Update));
00049   */
00050 
00051   StreamList::iterator i = m_streams.begin();
00052   for (; i != m_streams.end(); ++i) {
00053     (*i)->Update();
00054   }
00055 
00056   AI_Sleep(50);
00057 }
00058 
00060 
00061 IOutputStream*
00062 NullOutputContext::OpenStream(ISampleSource* source)
00063 {
00064   NullOutputStream* stream = new NullOutputStream(this, source);
00065   m_streams.insert(stream);
00066   return stream;
00067 }
00068 
00070 
00071 void
00072 NullOutputContext::RemoveStream(NullOutputStream* stream) {
00073   m_streams.erase(stream);
00074 }
00075 
00077 
00078 NullOutputStream::NullOutputStream(
00079   NullOutputContext* context,
00080   ISampleSource* source)
00081 : m_context(context)
00082 , m_source(source)
00083 , m_is_playing(false)
00084 , m_volume(ADR_VOLUME_MAX)
00085 , m_last_update(0)
00086 {
00087   m_source->GetFormat(m_channel_count, m_sample_rate, m_bits_per_sample);
00088 }
00089 
00091 
00092 NullOutputStream::~NullOutputStream()
00093 {
00094   m_context->RemoveStream(this);
00095 }
00096 
00098 
00099 void
00100 NullOutputStream::Play()
00101 {
00102   ADR_GUARD("NullOutputStream::Play");
00103   m_is_playing = true;
00104   ResetTimer();
00105 }
00106 
00108 
00109 void
00110 NullOutputStream::Stop()
00111 {
00112   m_is_playing = false;
00113 }
00114 
00116 
00117 void
00118 NullOutputStream::Reset()
00119 {
00120   ResetTimer();
00121 }
00122 
00124 
00125 bool
00126 NullOutputStream::IsPlaying()
00127 {
00128   return m_is_playing;
00129 }
00130 
00132 
00133 void
00134 NullOutputStream::SetVolume(int volume)
00135 {
00136   m_volume = volume;
00137 }
00138 
00140 
00141 int
00142 NullOutputStream::GetVolume()
00143 {
00144   return m_volume;
00145 }
00146 
00148 
00149 void
00150 NullOutputStream::ResetTimer()
00151 {
00152   m_last_update = GetNow();
00153 }
00154 
00156 
00157 void
00158 NullOutputStream::Update()
00159 {
00160   ADR_GUARD("NullOutputStream::Update");
00161 
00162   if (m_is_playing) {
00163     ADR_LOG("Null output stream is playing");
00164 
00165     // get number of milliseconds elapsed since last playing update
00166     // so we can read that much time worth of samples
00167     adr_u64 now = GetNow();
00168     adr_u64 elapsed = now - m_last_update;
00169 
00170     ADR_IF_DEBUG {
00171       char str[100];
00172       sprintf(str, "Elapsed: %I64d", elapsed);
00173       ADR_LOG(str);
00174     }
00175 
00176     int samples_to_read = int(m_sample_rate * elapsed / 1000000);
00177 
00178     ADR_IF_DEBUG {
00179       char str[100];
00180       sprintf(str, "Samples to read: %d", samples_to_read);
00181       ADR_LOG(str);
00182     }
00183 
00184     int samples_read = DummyRead(samples_to_read);
00185 
00186     if (samples_read != samples_to_read) {
00187       ADR_LOG("Stopping null output stream");
00188       m_source->Reset();
00189       Stop();
00190     }
00191 
00192     m_last_update = now;
00193   }
00194 }
00195 
00197 
00198 int
00199 NullOutputStream::DummyRead(int samples_to_read)
00200 {
00201   int total = 0;  // number of samples read so far
00202 
00203   // read samples into dummy buffer, counting the number we actually read
00204   adr_u8* dummy = new adr_u8[1024 * m_channel_count * m_bits_per_sample / 8];
00205   while (samples_to_read > 0) {
00206     int read = adr_min(1024, samples_to_read);
00207     int actual_read = m_source->Read(read, dummy);
00208     total += actual_read;
00209     samples_to_read -= actual_read;
00210     if (actual_read < read) {
00211       break;
00212     }
00213   }
00214 
00215   delete[] dummy;
00216   return total;
00217 }
00218 

Generated at Mon Jun 10 02:55:12 2002 for audiere by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001