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

stream_provider_wave.cpp

Go to the documentation of this file.
00001 /*
00002         $Id: stream_provider_wave.cpp,v 1.1 2001/03/06 15:09:26 mbn Exp $
00003 
00004         ------------------------------------------------------------------------
00005         ClanLib, the platform independent game SDK.
00006 
00007         This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
00008         version 2. See COPYING for details.
00009 
00010         For a total list of contributers see CREDITS.
00011 
00012         ------------------------------------------------------------------------
00013 
00014         File purpose:
00015                 Streamed sample
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       CL_Streamed_WaveSample
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   CL_Streamed_WaveSample_Session
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         // Check to see if this is really a .wav-file
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 //      cl_assert(!(memcmp(temp, "RIFFWAVEfmt ", 12)));
00101 
00102         WAVE_FORMAT format;
00103         input->read(&format, sizeof(WAVE_FORMAT));
00104 
00105         // Another sanity check
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 //      cl_assert(!(memcmp(temp, "data", 4)));
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 }

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