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

soundbuffer_stream_dx.cpp

Go to the documentation of this file.
00001 
00002 #include "Core/precomp.h"
00003 
00004 #include <iostream>
00005 #include "API/Core/System/cl_assert.h"
00006 
00007 #include "soundbuffer_stream_dx.h"
00008 
00009 #define STREAM_BUFFER_LENGTH_SECS 2
00010 
00011 CL_CardSoundBufferPlaybackStream_DX::CL_CardSoundBufferPlaybackStream_DX(
00012         CL_SoundCard_DX *card,
00013         CL_SoundBuffer_Generic_Stream *parent_buffer)
00014 {
00015         buffer = parent_buffer;
00016         parent_card = card;
00017         provider = parent_buffer->get_stream_provider();
00018         provider_session = provider->begin_session();
00019 
00020         int num_channels;
00021         int bps;
00022 
00023         switch (provider_session->get_format())
00024         {
00025         case sf_8bit_signed:
00026                 num_channels = 1;
00027                 bps = 8;
00028                 break;
00029         case sf_8bit_signed_stereo:
00030                 num_channels = 2;
00031                 bps = 8;
00032                 break;
00033         case sf_16bit_signed:
00034                 num_channels = 1;
00035                 bps = 16;
00036                 break;
00037         case sf_16bit_signed_stereo:
00038                 num_channels = 2;
00039                 bps = 16;
00040                 break;
00041         }
00042 
00043         WAVEFORMATEX format;
00044         format.wFormatTag = WAVE_FORMAT_PCM; 
00045         format.nChannels = num_channels; 
00046         format.nSamplesPerSec = provider_session->get_frequency(); 
00047         format.wBitsPerSample = bps; 
00048         format.nBlockAlign = format.wBitsPerSample * format.nChannels / 8; 
00049         format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; 
00050         format.cbSize = 0; 
00051  
00052         DSBUFFERDESC desc;
00053         desc.dwSize = sizeof(DSBUFFERDESC); 
00054         desc.dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
00055         //      DSBCAPS_CTRLDEFAULT has been removed in DirectX7
00056 
00057         desc.dwBufferBytes = format.nAvgBytesPerSec*STREAM_BUFFER_LENGTH_SECS; 
00058         desc.dwReserved = 0; 
00059         desc.lpwfxFormat = &format; 
00060 
00061         size_buffer = desc.dwBufferBytes;
00062         secure_distance = int(float(format.nAvgBytesPerSec) / 10);
00063         fill_position = 0;
00064 
00065         soundbuffer = NULL;
00066 
00067         if (parent_card->soundcard != NULL)
00068         {
00069                 HRESULT err = parent_card->soundcard->CreateSoundBuffer(&desc, &soundbuffer, NULL);
00070         }
00071 
00072         sound_is_playing = false;
00073         empty_pos = -1;
00074 
00075         update_buffer();
00076 }
00077 
00078 CL_CardSoundBufferPlaybackStream_DX::~CL_CardSoundBufferPlaybackStream_DX()
00079 {
00080         provider->end_session(provider_session);
00081         if (soundbuffer != NULL) soundbuffer->Release();
00082 }
00083 
00084 int CL_CardSoundBufferPlaybackStream_DX::get_position()
00085 {
00086         return -1;
00087 }
00088 
00089 float CL_CardSoundBufferPlaybackStream_DX::get_position_relative()
00090 {
00091         return -1;
00092 }
00093 
00094 bool CL_CardSoundBufferPlaybackStream_DX::set_position(int new_pos)
00095 {
00096         return false;
00097 }
00098 
00099 
00100 bool CL_CardSoundBufferPlaybackStream_DX::set_position_relative(float new_pos)
00101 {
00102         return false;
00103 }
00104 
00105 int CL_CardSoundBufferPlaybackStream_DX::get_length()
00106 {
00107         return -1;
00108 }
00109 
00110 CL_SoundBuffer_Generic *CL_CardSoundBufferPlaybackStream_DX::get_owner()
00111 {
00112         return buffer;
00113 }
00114 
00115 int CL_CardSoundBufferPlaybackStream_DX::get_frequency()
00116 {
00117         if (soundbuffer == NULL) return -1;
00118 
00119         DWORD ret;
00120         soundbuffer->GetFrequency(&ret);
00121         return ret;
00122 }
00123 
00124 bool CL_CardSoundBufferPlaybackStream_DX::set_frequency(int new_freq)
00125 {
00126         if (soundbuffer == NULL) return false;
00127 
00128         HRESULT err = soundbuffer->SetFrequency(new_freq);
00129         if (err != DS_OK) { return false; }
00130 
00131         return true;
00132 }
00133 
00134 float CL_CardSoundBufferPlaybackStream_DX::get_volume()
00135 {
00136         if (soundbuffer == NULL) return -1;
00137 
00138         long temp;
00139         soundbuffer->GetVolume(&temp);
00140 
00141         return pow(10, temp/20);
00142 }
00143 
00144 bool CL_CardSoundBufferPlaybackStream_DX::set_volume(float new_volume)
00145 {
00146         if (soundbuffer == NULL) return false;
00147 
00148         if (new_volume == 0) soundbuffer->SetVolume(DSBVOLUME_MIN);
00149         else soundbuffer->SetVolume(100*20*log10(new_volume));
00150 
00151         return true;
00152 }
00153 
00154 float CL_CardSoundBufferPlaybackStream_DX::get_pan()
00155 {
00156         if (soundbuffer == NULL) return -1;
00157 
00158         long ret;
00159         soundbuffer->GetPan(&ret);
00160 
00161         return ret;
00162 }
00163 
00164 bool CL_CardSoundBufferPlaybackStream_DX::set_pan(float new_pan)
00165 {
00166         if (soundbuffer == NULL) return false;
00167 
00168         if (new_pan < 0)
00169                 soundbuffer->SetPan(DSBPAN_CENTER-DSBPAN_LEFT*new_pan);
00170         else
00171                 soundbuffer->SetPan(DSBPAN_CENTER+DSBPAN_RIGHT*new_pan);
00172 
00173         return true;
00174 }
00175 
00176 void CL_CardSoundBufferPlaybackStream_DX::play()
00177 {
00178         if (soundbuffer == NULL) return;
00179 
00180         soundbuffer->SetCurrentPosition(0);
00181         soundbuffer->Play(0, 0, DSBPLAY_LOOPING);
00182         sound_is_playing = true;
00183 }
00184 
00185 void CL_CardSoundBufferPlaybackStream_DX::stop()
00186 {
00187         if (soundbuffer == NULL) return;
00188 
00189         soundbuffer->Stop();
00190         sound_is_playing = false;
00191 }
00192 
00193 bool CL_CardSoundBufferPlaybackStream_DX::is_playing()
00194 {
00195         if (soundbuffer == NULL) return false;
00196 
00197         DWORD status;
00198         soundbuffer->GetStatus(&status);
00199 
00200         return (status & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING;
00201 }
00202 
00203 void CL_CardSoundBufferPlaybackStream_DX::set_looping(bool loop)
00204 {
00205         if (soundbuffer == NULL) return;
00206 }
00207 
00208 char *get_dsounderr(HRESULT);
00209 void CL_CardSoundBufferPlaybackStream_DX::update_buffer()
00210 {
00211         if (soundbuffer == NULL) return;
00212 
00213         unsigned char *ptr1, *ptr2;
00214         DWORD size1, size2;
00215         DWORD written1 = 0;
00216         DWORD written2 = 0;
00217         DWORD playpos, writepos;
00218         HRESULT err;
00219         
00220         err = soundbuffer->GetCurrentPosition(&playpos, &writepos);
00221         cl_assert(err == DS_OK);
00222 
00223         if (playpos > fill_position) fill_length = playpos - fill_position - secure_distance;
00224         else fill_length = (size_buffer-fill_position) + playpos - secure_distance;
00225 
00226         if (fill_length > secure_distance)
00227         {
00228                 err = soundbuffer->Lock(fill_position, fill_length, (void **) &ptr1, &size1, (void **) &ptr2, &size2, 0);
00229                 if (err != DS_OK)
00230                 {
00231                         std::cout << "SHIT! We are going down!..." << std::endl;
00232                         std::cout << "fill_position: " << fill_position << ", fill_length: " << fill_length << std::endl;
00233                         std::cout << "size_buffer: " << size_buffer << ", playpos: " << playpos;
00234                         std::cout << ", writepos: " << writepos << std::endl;
00235                         char *error = get_dsounderr(err);
00236                         std::cout << error << std::endl;
00237                 }
00238                 cl_assert(err == DS_OK);
00239 
00240                 written1 = provider_session->get_data(ptr1, size1);
00241                 if (provider_session->get_format() == sf_8bit_signed)
00242                 {
00243                         for (DWORD i=0;i<written1;i++) ptr1[i] = (unsigned char) (short(ptr1[i])+128);
00244                 }
00245                 if (written1 == size1)
00246                 {
00247                         written2 = provider_session->get_data(ptr2, size2);
00248                         if (provider_session->get_format() == sf_8bit_signed)
00249                         {
00250                                 for (DWORD i=0;i<written2;i++) ptr2[i] = (unsigned char) (short(ptr2[i])+128);
00251                         }
00252                         if (written2 != size2)
00253                         {
00254                                 if (provider_session->get_format() == sf_8bit_signed) memset(&ptr2[written2], 128, size2-written2);
00255                                 else memset(&ptr2[written2], 0, size2-written2);
00256                                 written2 = size2;
00257                         }
00258                 }
00259                 else
00260                 {
00261                         if (provider_session->get_format() == sf_8bit_signed) 
00262                         {
00263                                 memset(&ptr1[written1], 128, size1-written1);
00264                                 written1 = size1;
00265                                 memset(ptr2, 128, size2);
00266                                 written2 = size2;
00267                         }
00268                         else
00269                         {
00270                                 memset(&ptr1[written1], 0, size1-written1);
00271                                 written1 = size1;
00272                                 memset(ptr2, 0, size2);
00273                                 written2 = size2;
00274                         }
00275                 }
00276 
00277                 soundbuffer->Unlock(ptr1, written1, ptr2, written2);
00278 
00279                 fill_position += fill_length;
00280                 if (fill_position >= size_buffer) fill_position -= size_buffer;
00281 
00282                 if (provider_session->eof() && empty_pos == -1)
00283                 {
00284                         empty_pos = fill_position;
00285                         wait_for_play_wrap = playpos >= empty_pos;
00286                 }
00287 
00288                 if (empty_pos != -1)
00289                 {
00290                         if (wait_for_play_wrap && playpos < empty_pos) wait_for_play_wrap = false;
00291                         if (!wait_for_play_wrap && playpos >= empty_pos)
00292                         {
00293                                 soundbuffer->Stop();
00294                                 sound_is_playing = false;
00295                         }
00296                 }
00297         }
00298 }
00299 
00300 void CL_CardSoundBufferPlaybackStream_DX::keep_alive()
00301 {
00302         if (sound_is_playing)
00303         {
00304                 update_buffer();
00305         }
00306 }

Generated at Wed Apr 4 19:54:03 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001