00001 #include "device_ds_buffer.h"
00002 #include "device_ds.h"
00003
00004
00005 namespace audiere {
00006
00007 DSOutputBuffer::DSOutputBuffer(
00008 DSAudioDevice* device,
00009 IDirectSoundBuffer* buffer,
00010 int length,
00011 int frame_size)
00012 {
00013 ADR_GUARD("DSOutputBuffer::DSOutputBuffer");
00014
00015 m_device = device;
00016 m_buffer = buffer;
00017 m_length = length;
00018 m_frame_size = frame_size;
00019
00020 DWORD frequency;
00021 m_buffer->GetFrequency(&frequency);
00022 m_base_frequency = frequency;
00023
00024 m_repeating = false;
00025 m_volume = 1;
00026 m_pan = 0;
00027
00028 m_stop_event = 0;
00029
00030
00031 IDirectSoundNotify* notify;
00032 HRESULT rv = m_buffer->QueryInterface(
00033 IID_IDirectSoundNotify, (void**)¬ify);
00034 if (SUCCEEDED(rv) && notify) {
00035 m_stop_event = CreateEvent(0, FALSE, FALSE, 0);
00036 if (!m_stop_event) {
00037 ADR_LOG("DSOutputBuffer stop event creation failed. Not firing stop events.");
00038 } else {
00039 DSBPOSITIONNOTIFY n;
00040 n.dwOffset = DSBPN_OFFSETSTOP;
00041 n.hEventNotify = m_stop_event;
00042 notify->SetNotificationPositions(1, &n);
00043 }
00044 }
00045 }
00046
00047
00048 DSOutputBuffer::~DSOutputBuffer() {
00049 ADR_GUARD("DSOutputBuffer::~DSOutputBuffer");
00050
00051 m_device->removeBuffer(this);
00052 m_buffer->Release();
00053 if (m_stop_event) {
00054 CloseHandle(m_stop_event);
00055 }
00056 }
00057
00058
00059 void
00060 DSOutputBuffer::play() {
00061 m_buffer->Play(0, 0, m_repeating ? DSBPLAY_LOOPING : 0);
00062 }
00063
00064
00065 void
00066 DSOutputBuffer::stop() {
00067 m_buffer->Stop();
00068 m_device->fireStopEvent(this, StopEvent::STOP_CALLED);
00069 }
00070
00071
00072 bool
00073 DSOutputBuffer::isPlaying() {
00074 DWORD status;
00075 HRESULT rv = m_buffer->GetStatus(&status);
00076 return (SUCCEEDED(rv) && status & DSBSTATUS_PLAYING);
00077 }
00078
00079
00080 void
00081 DSOutputBuffer::reset() {
00082 setPosition(0);
00083 }
00084
00085
00086 void
00087 DSOutputBuffer::setRepeat(bool repeat) {
00088 m_repeating = repeat;
00089 if (isPlaying()) {
00090
00091 play();
00092 }
00093 }
00094
00095
00096 bool
00097 DSOutputBuffer::getRepeat() {
00098 return m_repeating;
00099 }
00100
00101
00102 void
00103 DSOutputBuffer::setVolume(float volume) {
00104 m_volume = volume;
00105 m_buffer->SetVolume(DSAudioDevice::Volume_AudiereToDirectSound(volume));
00106 }
00107
00108
00109 float
00110 DSOutputBuffer::getVolume() {
00111 return m_volume;
00112 }
00113
00114
00115 void
00116 DSOutputBuffer::setPan(float pan) {
00117 m_pan = pan;
00118 m_buffer->SetPan(DSAudioDevice::Pan_AudiereToDirectSound(pan));
00119 }
00120
00121
00122 float
00123 DSOutputBuffer::getPan() {
00124 return m_pan;
00125 }
00126
00127
00128 void
00129 DSOutputBuffer::setPitchShift(float shift) {
00130 m_buffer->SetFrequency(DWORD(m_base_frequency * shift));
00131 }
00132
00133
00134 float
00135 DSOutputBuffer::getPitchShift() {
00136 DWORD frequency;
00137 m_buffer->GetFrequency(&frequency);
00138 return float(frequency) / m_base_frequency;
00139 }
00140
00141
00142 bool
00143 DSOutputBuffer::isSeekable() {
00144 return true;
00145 }
00146
00147
00148 int
00149 DSOutputBuffer::getLength() {
00150 return m_length;
00151 }
00152
00153
00154 void
00155 DSOutputBuffer::setPosition(int position) {
00156 m_buffer->SetCurrentPosition(position * m_frame_size);
00157 }
00158
00159
00160 int
00161 DSOutputBuffer::getPosition() {
00162 DWORD play;
00163 m_buffer->GetCurrentPosition(&play, 0);
00164 return play / m_frame_size;
00165 }
00166
00167 void
00168 DSOutputBuffer::update() {
00169 if (m_stop_event) {
00170 DWORD result = WaitForSingleObject(m_stop_event, 0);
00171 if (result == WAIT_OBJECT_0) {
00172 m_device->fireStopEvent(this, StopEvent::STREAM_ENDED);
00173 }
00174 }
00175 }
00176
00177 }