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* )
00033 {
00034 return true;
00035 }
00036
00038
00039 void
00040 NullOutputContext::Update()
00041 {
00042
00043
00044
00045
00046
00047
00048
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
00166
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;
00202
00203
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