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/IOData/inputsource_provider.h"
00024 #include "API/Core/IOData/inputsource.h"
00025 #include "API/Core/System/cl_assert.h"
00026 #include "API/Core/System/error.h"
00027 #include "API/Sound/SoundProviders/static_provider_raw.h"
00028 #include "API/Sound/SoundProviders/static_provider_wave.h"
00029
00030 CL_SoundBuffer *CL_Sample::create(const char *sample_id, CL_InputSourceProvider *provider)
00031 {
00032 return CL_SoundBuffer::create(new CL_Sample(sample_id, provider), true);
00033 }
00034
00035 CL_Sample::CL_Sample(const char *s_id, CL_InputSourceProvider *_provider) : sample_id(s_id)
00036 {
00037 if (_provider == NULL)
00038 {
00039 provider = CL_InputSourceProvider::create_file_provider(".");
00040 }
00041 else
00042 {
00043 provider = _provider->clone();
00044 }
00045 sample_data = NULL;
00046 }
00047
00048 CL_Sample::~CL_Sample()
00049 {
00050 delete[] sample_data;
00051 delete provider;
00052 }
00053
00054 void CL_Sample::load_data()
00055 {
00056 CL_InputSource *source = provider->open_source(sample_id.c_str());
00057 cl_assert(source != NULL);
00058
00059
00060 char temp[12];
00061 source->read(temp, 4);
00062 source->seek(4, CL_InputSource::seek_cur);
00063 source->read(&temp[4], 8);
00064 source->seek(4, CL_InputSource::seek_cur);
00065
00066 if (memcmp(temp, "RIFFWAVEfmt ", 12) != 0)
00067 {
00068 throw CL_Error("Invalid RIFF WAVE header!");
00069 }
00070
00071
00072 WAVE_FORMAT format;
00073 source->read(&format, sizeof(WAVE_FORMAT));
00074
00075
00076 source->read(temp, 4);
00077 temp[4] = 0;
00078 if (memcmp(temp, "data", 4) != 0)
00079 {
00080 throw CL_Error("Invalid RIFF data chunk!");
00081 }
00082
00083
00084 sample_size = source->read_int32();
00085 sample_freq = format.nSamplesPerSec;
00086
00087 int bytes_per_sample = format.nAvgBytesPerSec / format.nSamplesPerSec;
00088
00089 if (format.nChannels == 2 && bytes_per_sample == 4) sample_format = sf_16bit_signed_stereo;
00090 else if (format.nChannels == 2 && bytes_per_sample == 2) sample_format = sf_8bit_signed_stereo;
00091 else if (format.nChannels == 1 && bytes_per_sample == 2) sample_format = sf_16bit_signed;
00092 else if (format.nChannels == 1 && bytes_per_sample == 1) sample_format = sf_8bit_signed;
00093 else
00094 {
00095 std::cout <<" Invalid wave file format " <<std::endl;
00096 std::cout <<"---------------------------------" <<std::endl;
00097 std::cout <<"Sample size: " << sample_size <<std::endl;
00098 std::cout <<"Sample frequency: " << sample_freq <<std::endl;
00099 std::cout <<"Number of channels: " << format.nChannels <<std::endl;
00100 std::cout <<"Number of bytes pr. sample: " << bytes_per_sample <<std::endl;
00101 std::cout <<"---------------------------------" <<std::endl;
00102
00103 throw CL_Error("Invalid wave file format");
00104 }
00105
00106 sample_data = new char[sample_size];
00107 if (bytes_per_sample == 1)
00108 {
00109 unsigned char *temp = new unsigned char[sample_size];
00110 source->read(temp, sample_size);
00111 for (int i=0;i<sample_size;i++) sample_data[i] = char(short(temp[i])-128);
00112 delete[] temp;
00113 }
00114 else
00115 {
00116 source->read(sample_data, sample_size);
00117 }
00118
00119 delete source;
00120 }
00121
00122 void CL_Sample::lock()
00123 {
00124 if (sample_data != NULL) return;
00125
00126 load_data();
00127 }
00128
00129 void CL_Sample::unlock()
00130 {
00131 delete[] sample_data;
00132 sample_data = NULL;
00133 }
00134
00135 SoundFormat CL_Sample::get_format() const
00136 {
00137 return sample_format;
00138 }
00139
00140 int CL_Sample::data_size() const
00141 {
00142 return sample_size;
00143 }
00144
00145 void *CL_Sample::get_data() const
00146 {
00147 return sample_data;
00148 }
00149
00150 int CL_Sample::get_frequency() const
00151 {
00152 return sample_freq;
00153 }