1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
/*
$Id: static_provider_wave.cpp,v 1.3 2001/12/11 20:44:24 mbn Exp $
------------------------------------------------------------------------
ClanLib, the platform independent game SDK.
This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
version 2. See COPYING for details.
For a total list of contributers see CREDITS.
------------------------------------------------------------------------
File purpose:
Simple sample support.
*/
#ifdef WIN32
#pragma warning (disable:4786)
#endif
#include "API/Core/IOData/inputsource_provider.h"
#include "API/Core/IOData/inputsource.h"
#include "API/Core/System/cl_assert.h"
#include "API/Core/System/error.h"
#include "API/Sound/SoundProviders/static_provider_raw.h"
#include "API/Sound/SoundProviders/static_provider_wave.h"
CL_SoundBuffer *CL_Sample::create(const std::string &sample_id, CL_InputSourceProvider *provider)
{
return CL_SoundBuffer::create(new CL_Sample(sample_id, provider), true);
}
CL_Sample::CL_Sample(const std::string &s_id, CL_InputSourceProvider *_provider) : sample_id(s_id)
{
if (_provider == NULL)
{
provider = CL_InputSourceProvider::create_file_provider(".");
}
else
{
provider = _provider->clone();
}
sample_data = NULL;
}
CL_Sample::~CL_Sample()
{
delete[] sample_data;
delete provider;
}
void CL_Sample::load_data()
{
CL_InputSource *source = provider->open_source(sample_id.c_str());
cl_assert(source != NULL);
// Check to see if this is really a .wav-file
char temp[12];
source->read(temp, 4);
source->seek(4, CL_InputSource::seek_cur);
source->read(&temp[4], 8);
source->seek(4, CL_InputSource::seek_cur);
if (memcmp(temp, "RIFFWAVEfmt ", 12) != 0)
{
throw CL_Error("Invalid RIFF WAVE header!");
}
// cl_assert(!(memcmp(temp, "RIFFWAVEfmt ", 12)));
WAVE_FORMAT format;
source->read(&format, sizeof(WAVE_FORMAT));
// Another sanity check
source->read(temp, 4);
temp[4] = 0;
if (memcmp(temp, "data", 4) != 0)
{
throw CL_Error("Invalid RIFF data chunk!");
}
// cl_assert(!(memcmp(temp, "data", 4)));
sample_size = source->read_int32();
sample_freq = format.nSamplesPerSec;
int bytes_per_sample = format.nAvgBytesPerSec / format.nSamplesPerSec;
if (format.nChannels == 2 && bytes_per_sample == 4) sample_format = sf_16bit_signed_stereo;
else if (format.nChannels == 2 && bytes_per_sample == 2) sample_format = sf_8bit_signed_stereo;
else if (format.nChannels == 1 && bytes_per_sample == 2) sample_format = sf_16bit_signed;
else if (format.nChannels == 1 && bytes_per_sample == 1) sample_format = sf_8bit_signed;
else
{
std::cout <<" Invalid wave file format " <<std::endl;
std::cout <<"---------------------------------" <<std::endl;
std::cout <<"Sample size: " << sample_size <<std::endl;
std::cout <<"Sample frequency: " << sample_freq <<std::endl;
std::cout <<"Number of channels: " << format.nChannels <<std::endl;
std::cout <<"Number of bytes pr. sample: " << bytes_per_sample <<std::endl;
std::cout <<"---------------------------------" <<std::endl;
throw CL_Error("Invalid wave file format");
}
sample_data = new char[sample_size];
if (sample_format == sf_8bit_signed || sample_format == sf_8bit_signed_stereo)
{
unsigned char *temp = new unsigned char[sample_size];
source->read(temp, sample_size);
for (int i=0;i<sample_size;i++) sample_data[i] = char(short(temp[i])-128);
delete[] temp;
}
else
{
source->read(sample_data, sample_size);
}
delete source;
}
void CL_Sample::lock()
{
if (sample_data != NULL) return;
load_data();
}
void CL_Sample::unlock()
{
delete[] sample_data;
sample_data = NULL;
}
SoundFormat CL_Sample::get_format() const
{
return sample_format;
}
int CL_Sample::data_size() const
{
return sample_size;
}
void *CL_Sample::get_data() const
{
return sample_data;
}
int CL_Sample::get_frequency() const
{
return sample_freq;
}
|