00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef WIN32
00020 #pragma warning (disable:4786)
00021 #endif
00022
00023 #ifdef USE_CLANSOUND
00024
00025 #include <API/Core/System/mutex.h>
00026 #include <API/Sound/stream_soundprovider.h>
00027 #include "API/Core/System/cl_assert.h"
00028 #include <Sound/Sound/ClanSound/cardplayback_clan.h>
00029 #include <Sound/Sound/ClanSound/playback_stream.h>
00030 #include <Sound/Sound/ClanSound/soundcard_clan.h>
00031
00032 CL_Playback_Stream::CL_Playback_Stream(
00033 CL_SoundCard_ClanSound *card,
00034 CL_StreamSoundProvider *_provider,
00035 CL_SoundBuffer_Generic *owner)
00036 : CL_CardPlayback_ClanSound(card)
00037 {
00038 this->owner = owner;
00039 provider = _provider;
00040 provider_session = provider->begin_session();
00041
00042 frequency = provider_session->get_frequency();
00043 volume = 256;
00044
00045 format = provider_session->get_format();
00046 pos = 0;
00047 playing = false;
00048 filled_pos = 0;
00049 first_time = true;
00050
00051 buffer_size = frequency/4;
00052 ring_buffer = new short[buffer_size*2];
00053 stream_eof = false;
00054
00055 card->add(this);
00056 }
00057
00058 CL_Playback_Stream::~CL_Playback_Stream()
00059 {
00060 card->remove(this);
00061
00062 delete[] ring_buffer;
00063 provider->end_session(provider_session);
00064 }
00065
00066 void CL_Playback_Stream::keep_alive()
00067 {
00068 int bytes_wanted = ask_update();
00069 if (bytes_wanted == 0) return;
00070
00071 char *copy_buffer = new char[bytes_wanted];
00072 int bytes_given = provider_session->get_data(copy_buffer, bytes_wanted);
00073
00074 if (bytes_given > 0) update(copy_buffer, bytes_given);
00075 delete[] copy_buffer;
00076
00077 if (provider_session->eof())
00078 {
00079 stream_eof = true;
00080 playing = false;
00081 }
00082 }
00083
00084 int CL_Playback_Stream::get_position()
00085 {
00086 return (int) pos;
00087 }
00088
00089 float CL_Playback_Stream::get_position_relative()
00090 {
00091 return pos / get_length();
00092 }
00093
00094 bool CL_Playback_Stream::set_position_relative(float new_pos)
00095 {
00096 return set_position((int) (new_pos * get_length()));
00097 }
00098
00099 int CL_Playback_Stream::get_length()
00100 {
00101 return -1;
00102 }
00103
00104 int CL_Playback_Stream::get_frequency()
00105 {
00106 return frequency;
00107 }
00108
00109 bool CL_Playback_Stream::set_frequency(int new_freq)
00110 {
00111 frequency = new_freq;
00112 return true;
00113 }
00114
00115 float CL_Playback_Stream::get_volume()
00116 {
00117 return volume;
00118 }
00119
00120 bool CL_Playback_Stream::set_volume(float new_volume)
00121 {
00122 volume = new_volume;
00123 return true;
00124 }
00125
00126 float CL_Playback_Stream::get_pan()
00127 {
00128 return pan;
00129 }
00130
00131 bool CL_Playback_Stream::set_pan(float new_pan)
00132 {
00133 pan = new_pan;
00134 return true;
00135 }
00136
00137 void CL_Playback_Stream::set_looping(bool looping)
00138 {
00139 static bool warning = true;
00140
00141 if (warning)
00142 {
00143 cl_info(info_sound, "Not implemented yet.");
00144 warning = false;
00145 }
00146 }
00147
00148 bool CL_Playback_Stream::get_looping()
00149 {
00150 return false;
00151 }
00152
00153 void CL_Playback_Stream::play()
00154 {
00155 playing = true;
00156 }
00157
00158 void CL_Playback_Stream::stop()
00159 {
00160 playing = false;
00161 }
00162
00163 bool CL_Playback_Stream::is_playing()
00164 {
00165 return playing;
00166 }
00167
00168 bool CL_Playback_Stream::set_position(int new_pos)
00169 {
00170 if (provider_session->set_position(new_pos))
00171 {
00172 flush();
00173 return true;
00174 }
00175
00176 return false;
00177 }
00178
00179 void CL_Playback_Stream::flush()
00180 {
00181 }
00182
00183 void CL_Playback_Stream::get_playback_data(int *data, int num_samples)
00184 {
00185 int i;
00186 int freq = frequency;
00187 int vol = (int) (volume*128);
00188
00189 if (freq == 0 || vol == 0)
00190 {
00191 memset(data, 0, num_samples*sizeof(int)*2);
00192 return;
00193 }
00194
00195 double speed = freq/(double) 22050;
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 double cached_pos = pos;
00210 int *ptr = data;
00211 for (i=0; i<num_samples; i++)
00212 {
00213 int cur_pos = (int) cached_pos;
00214
00215 if (cur_pos == filled_pos)
00216 {
00217 ring_buffer[cur_pos*2+0] = 0;
00218 ring_buffer[cur_pos*2+1] = 0;
00219 continue;
00220 }
00221
00222 if (cur_pos < buffer_size)
00223 {
00224 *(ptr++) = ring_buffer[cur_pos*2+0];
00225 *(ptr++) = ring_buffer[cur_pos*2+1];
00226 }
00227
00228 cached_pos += speed;
00229 if (cur_pos != (int) cached_pos)
00230 {
00231 ring_buffer[cur_pos*2+0] = 0;
00232 ring_buffer[cur_pos*2+1] = 0;
00233 }
00234
00235 if (cached_pos >= buffer_size) cached_pos -= buffer_size;
00236 }
00237 pos = cached_pos;
00238
00239
00240
00241
00242 ptr = data;
00243 int left_pan = int (128-pan*128);
00244 int right_pan = int (128+pan*128);
00245 if (left_pan < 0) left_pan = 0;
00246 if (left_pan > 128) left_pan = 128;
00247 if (right_pan < 0) right_pan = 0;
00248 if (right_pan > 128) right_pan = 128;
00249
00250 for (i=0; i<num_samples; i++)
00251 {
00252
00253 (*ptr) = (*ptr)*vol*left_pan/16384; ptr++;
00254
00255
00256 (*ptr) = (*ptr)*vol*right_pan/16384; ptr++;
00257 }
00258 }
00259
00260 void CL_Playback_Stream::mix_to(int *data, int num_samples)
00261 {
00262 if (playing == false) return;
00263
00264 static int temp[16*1024*2];
00265
00266 for (int i=0; i<num_samples; i+=16*1024)
00267 {
00268 int size = num_samples-i;
00269 if (size > 16*1024) size = 16*1024;
00270
00271 get_playback_data(temp, size);
00272 filter(temp, size);
00273 int k = i*2;
00274 for (int j=0; j<size*2; j++) data[k+j] += temp[j];
00275 }
00276 }
00277
00278 int CL_Playback_Stream::get_samples_available()
00279 {
00280 if (pos < filled_pos) return (int) (pos+(buffer_size-filled_pos));
00281 if (pos > filled_pos) return (int) (filled_pos - pos);
00282
00283 return 0;
00284 }
00285
00286 int CL_Playback_Stream::ask_update()
00287 {
00288
00289
00290 int _filled_pos = filled_pos;
00291 int _pos = (int) pos;
00292
00293 int space_left = buffer_size;
00294
00295 if (_pos < _filled_pos) space_left = (int) (buffer_size-_filled_pos+_pos);
00296 if (_pos > _filled_pos) space_left = (int) (_pos-_filled_pos);
00297
00298
00299
00300 space_left -= 16;
00301 if (space_left <= buffer_size/5) return 0;
00302
00303 switch (format)
00304 {
00305 case sf_8bit_signed:
00306 break;
00307
00308 case sf_8bit_signed_stereo:
00309 case sf_16bit_signed:
00310 space_left *= 2;
00311 break;
00312
00313 case sf_16bit_signed_stereo:
00314 space_left *= 4;
00315 break;
00316
00317 default:
00318 cl_assert(false);
00319 }
00320
00321 return space_left;
00322 }
00323
00324 int CL_Playback_Stream::update(void *data, int data_size)
00325 {
00326
00327
00328 if (first_time)
00329 {
00330 first_time = false;
00331 filled_pos = (int) pos;
00332 }
00333
00334 int num_samples = data_size;
00335 int sample_size=0;
00336
00337 switch (format)
00338 {
00339 case sf_8bit_signed:
00340 sample_size = 1;
00341 break;
00342
00343 case sf_8bit_signed_stereo:
00344 case sf_16bit_signed:
00345 sample_size = 2;
00346 break;
00347
00348 case sf_16bit_signed_stereo:
00349 sample_size = 4;
00350 break;
00351
00352 default:
00353 cl_assert(false);
00354 }
00355
00356 num_samples /= sample_size;
00357
00358 if (filled_pos+num_samples > buffer_size)
00359 {
00360 char *_data = (char *) data;
00361
00362 int fill_length = buffer_size - filled_pos;
00363
00364 update_format(filled_pos, fill_length, data);
00365 update_format(0, num_samples - fill_length, _data+fill_length*sample_size);
00366
00367 filled_pos = num_samples - fill_length;
00368 }
00369 else
00370 {
00371 update_format(filled_pos, num_samples, data);
00372 filled_pos += num_samples;
00373 }
00374
00375 return 0;
00376 }
00377
00378 void CL_Playback_Stream::update_format(int pos, int num_samples, void *data)
00379 {
00380 switch (format)
00381 {
00382 case sf_8bit_signed:
00383 {
00384 unsigned char *input_c = (unsigned char *) data;
00385 for (int i=0; i<num_samples; i++)
00386 {
00387 ring_buffer[(pos+i)*2+0] = input_c[i];
00388 ring_buffer[(pos+i)*2+1] = input_c[i];
00389 }
00390 }
00391 break;
00392
00393 case sf_8bit_signed_stereo:
00394 {
00395 unsigned char *input_c = (unsigned char *) data;
00396 for (int i=0; i<num_samples; i++)
00397 {
00398 ring_buffer[(pos+i)*2+0] = input_c[i*2+0];
00399 ring_buffer[(pos+i)*2+1] = input_c[i*2+1];
00400 }
00401 }
00402 break;
00403
00404 case sf_16bit_signed:
00405 {
00406 short *input_s = (short *) data;
00407 for (int i=0; i<num_samples; i++)
00408 {
00409 ring_buffer[(pos+i)*2+0] = input_s[i];
00410 ring_buffer[(pos+i)*2+1] = input_s[i];
00411 }
00412 }
00413 break;
00414
00415 case sf_16bit_signed_stereo:
00416 {
00417 short *input_s = (short *) data;
00418 for (int i=0; i<num_samples; i++)
00419 {
00420 ring_buffer[(pos+i)*2+0] = input_s[i*2+0];
00421 ring_buffer[(pos+i)*2+1] = input_s[i*2+1];
00422 }
00423 }
00424 break;
00425
00426 default:
00427 cl_assert(false);
00428 }
00429 }
00430
00431 #endif