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 #include "API/Core/System/cl_assert.h"
00024 #include "API/Core/System/error.h"
00025 #include "API/Core/IOData/inputsource.h"
00026 #include "API/Sound/SoundProviders/stream_provider_wave.h"
00027
00028 #include <iostream>
00029
00030
00031
00032
00033
00034 CL_SoundBuffer *CL_Streamed_WaveSample::create(
00035 const char *filename,
00036 CL_InputSourceProvider *inputprovider,
00037 bool looped)
00038 {
00039 return CL_SoundBuffer::create(
00040 new CL_Streamed_WaveSample(
00041 filename,
00042 inputprovider,
00043 looped),
00044 true);
00045 }
00046
00047 CL_Streamed_WaveSample::CL_Streamed_WaveSample(const char *_filename, CL_InputSourceProvider *_inputprovider, bool _looped)
00048 {
00049 filename = _filename;
00050 looped = _looped;
00051
00052 if (_inputprovider == NULL)
00053 {
00054 inputprovider = CL_InputSourceProvider::create_file_provider(".");
00055 }
00056 else
00057 {
00058 inputprovider = _inputprovider->clone();
00059 }
00060 }
00061
00062 CL_Streamed_WaveSample::~CL_Streamed_WaveSample()
00063 {
00064 delete inputprovider;
00065 }
00066
00067 CL_StreamSoundProvider_Session *CL_Streamed_WaveSample::begin_session()
00068 {
00069 return new CL_Streamed_WaveSample_Session(
00070 inputprovider->open_source(filename.c_str()),
00071 looped);
00072 }
00073
00074 void CL_Streamed_WaveSample::end_session(CL_StreamSoundProvider_Session *session)
00075 {
00076 delete session;
00077 }
00078
00079
00080
00081
00082
00083 CL_Streamed_WaveSample_Session::CL_Streamed_WaveSample_Session(
00084 CL_InputSource *_input, bool _looped)
00085 {
00086 input = _input;
00087 looped = _looped;
00088 cl_assert(input != NULL);
00089
00090
00091 char temp[12];
00092 input->read(temp, 4);
00093 input->seek(4, CL_InputSource::seek_cur);
00094 input->read(&temp[4], 8);
00095 input->seek(4, CL_InputSource::seek_cur);
00096
00097 if (memcmp(temp, "RIFFWAVEfmt ", 12) != 0)
00098 throw CL_Error("Invalid RIFF WAVE header");
00099
00100
00101
00102 WAVE_FORMAT format;
00103 input->read(&format, sizeof(WAVE_FORMAT));
00104
00105
00106 input->read(temp, 4);
00107 temp[4] = 0;
00108 if (memcmp(temp, "data", 4) != 0)
00109 throw CL_Error("Invalid RIFF data header");
00110
00111
00112 sample_size = input->read_int32();
00113 sample_freq = format.nSamplesPerSec;
00114
00115 int bytes_per_sample = format.nAvgBytesPerSec / format.nSamplesPerSec;
00116
00117 if (format.nChannels == 2 && bytes_per_sample == 4) sample_format = sf_16bit_signed_stereo;
00118 else if (format.nChannels == 2 && bytes_per_sample == 2) sample_format = sf_8bit_signed_stereo;
00119 else if (format.nChannels == 1 && bytes_per_sample == 2) sample_format = sf_16bit_signed;
00120 else if (format.nChannels == 1 && bytes_per_sample == 1) sample_format = sf_8bit_signed;
00121 else
00122 {
00123 std::cout << " Invalid wave file format " << std::endl;
00124 std::cout << "---------------------------------" << std::endl;
00125 std::cout << "Sample size: " << sample_size << std::endl;
00126 std::cout << "Sample frequency: " << sample_freq << std::endl;
00127 std::cout << "Number of channels: " << format.nChannels << std::endl;
00128 std::cout << "Number of bytes pr. sample: " << bytes_per_sample << std::endl;
00129 std::cout << "---------------------------------" << std::endl;
00130
00131 throw CL_Error("Invalid wave file format");
00132 }
00133
00134 sample_left = sample_size;
00135 }
00136
00137 CL_Streamed_WaveSample_Session::~CL_Streamed_WaveSample_Session()
00138 {
00139 delete input;
00140 }
00141
00142 bool CL_Streamed_WaveSample_Session::eof() const
00143 {
00144 if (sample_left <= 0 && !looped) return true;
00145 return false;
00146 }
00147
00148 int CL_Streamed_WaveSample_Session::get_data(void *data_ptr, int data_requested)
00149 {
00150 if (sample_left <= 0)
00151 {
00152 if (looped)
00153 {
00154 sample_left = sample_size;
00155 input->seek(0, CL_InputSource::seek_set);
00156 }
00157 else
00158 {
00159 return 0;
00160 }
00161 }
00162
00163 if (looped)
00164 {
00165 if (data_requested > sample_left)
00166 {
00167 int pos = 0;
00168 while (data_requested > 0)
00169 {
00170 input->read(&((unsigned char *) data_ptr)[pos], sample_left);
00171 if (get_format() == sf_8bit_signed)
00172 {
00173 for (int i=0;i<sample_left;i++)
00174 {
00175 ((unsigned char *) data_ptr)[pos+i] = char(short(((unsigned char *) data_ptr)[pos+i])+128);
00176 }
00177 }
00178 data_requested -= sample_left;
00179 pos += sample_left;
00180
00181 input->seek(0, CL_InputSource::seek_set);
00182
00183 int bytes_read = input->read(&((unsigned char *)data_ptr)[pos], data_requested);
00184 data_requested -= bytes_read;
00185 if (get_format() == sf_8bit_signed)
00186 {
00187 for (int i=0;i<bytes_read;i++)
00188 {
00189 ((unsigned char *) data_ptr)[pos+i] = char(short(((unsigned char *) data_ptr)[pos+i])+128);
00190 }
00191 }
00192 pos += bytes_read;
00193
00194 sample_left = sample_size - bytes_read;
00195 }
00196
00197 return data_requested;
00198 }
00199 else
00200 {
00201 sample_left -= data_requested;
00202 int read = input->read(data_ptr, data_requested);
00203 if (get_format() == sf_8bit_signed)
00204 {
00205 for (int i=0;i<read;i++)
00206 {
00207 ((unsigned char *) data_ptr)[i] = char(short(((unsigned char *) data_ptr)[i])+128);
00208 }
00209 }
00210 return read;
00211 }
00212 }
00213 else
00214 {
00215 sample_left -= data_requested;
00216 if (sample_left < 0)
00217 {
00218 data_requested += sample_left;
00219 }
00220 int read = input->read(data_ptr, data_requested);
00221 if (get_format() == sf_8bit_signed)
00222 {
00223 for (int i=0;i<read;i++)
00224 {
00225 ((unsigned char *) data_ptr)[i] = char(short(((unsigned char *) data_ptr)[i])+128);
00226 }
00227 }
00228
00229 return read;
00230 }
00231 }
00232
00233 int CL_Streamed_WaveSample_Session::get_frequency() const
00234 {
00235 return sample_freq;
00236 }
00237
00238 SoundFormat CL_Streamed_WaveSample_Session::get_format() const
00239 {
00240 return sample_format;
00241 }