commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
119
include/framework/audio/sample_wav_factory.cpp
Normal file
119
include/framework/audio/sample_wav_factory.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "audio/sample_wav_factory.h"
|
||||
#include "audio/sample_wav.h"
|
||||
#include "filesystem/filesystem.h"
|
||||
#include "filesystem/io_handle.h"
|
||||
#include "memory/endian.h"
|
||||
#include "platform.h"
|
||||
#include "log/log.h"
|
||||
|
||||
using namespace GS;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ISample *SampleWavFactory::Load(const char *path)
|
||||
{
|
||||
AutoPtr <IO::Handle> h(Platform::Get().io->Open(path));
|
||||
if (h.IsNull())
|
||||
return NULL;
|
||||
|
||||
// Verify format.
|
||||
char header[4];
|
||||
h->Read(header, 4);
|
||||
if (memcmp(header, "RIFF", 4))
|
||||
return NULL;
|
||||
h->Seek(4);
|
||||
h->Read(header, 4);
|
||||
if (memcmp(header, "WAVE", 4))
|
||||
return NULL;
|
||||
|
||||
// Create sample.
|
||||
AutoPtr <SampleWav> sample(new SampleWav);
|
||||
if (sample.IsNull())
|
||||
return NULL;
|
||||
|
||||
// Parse format.
|
||||
bool has_format = false, has_data = false;
|
||||
|
||||
struct Format
|
||||
{
|
||||
short wFormatTag;
|
||||
unsigned short wChannels;
|
||||
unsigned long dwSamplesPerSec;
|
||||
unsigned long dwAvgBytesPerSec;
|
||||
unsigned short wBlockAlign;
|
||||
unsigned short wBitsPerSample;
|
||||
};
|
||||
Format format;
|
||||
|
||||
Memory::Set(&format, 0, sizeof(Format));
|
||||
|
||||
forever
|
||||
{
|
||||
// Chunk + size.
|
||||
if (h->Read(header, 4) != 4)
|
||||
break;
|
||||
uint chunk_size = h->Read <uint> ();
|
||||
|
||||
// WAV format tag.
|
||||
if (!memcmp(header, "fmt ", 4))
|
||||
{
|
||||
uint cs = chunk_size;
|
||||
if (cs > sizeof(Format))
|
||||
{
|
||||
__LOG_W__ << "Unexpected WAV 'format' chunk size. Found " << cs << ", expected " << (int)sizeof(Format) << ".\n";
|
||||
cs = sizeof(Format);
|
||||
}
|
||||
if (h->Read(&format, cs) != cs)
|
||||
__ERR__(__LOG_E__ << "Mangled WAV 'format' chunk in '" << path << "'.\n", NULL)
|
||||
|
||||
Endian::ToHost(&format.wFormatTag, 2, Endian::Intel);
|
||||
Endian::ToHost(&format.wChannels, 2, Endian::Intel);
|
||||
Endian::ToHost(&format.dwSamplesPerSec, 4, Endian::Intel);
|
||||
Endian::ToHost(&format.dwAvgBytesPerSec, 4, Endian::Intel);
|
||||
Endian::ToHost(&format.wBlockAlign, 2, Endian::Intel);
|
||||
Endian::ToHost(&format.wBitsPerSample, 2, Endian::Intel);
|
||||
|
||||
has_format = true;
|
||||
|
||||
// Finish skipping tag.
|
||||
if (cs != chunk_size)
|
||||
h->Seek(chunk_size - cs);
|
||||
}
|
||||
|
||||
// WAV data tag.
|
||||
else if (!memcmp(header, "data", 4))
|
||||
{
|
||||
if (has_format)
|
||||
{
|
||||
char *pcm = sample->AllocAs(chunk_size / (format.wBitsPerSample / 8) / format.wChannels, SampleFormat(SampleFormat::Format_PCM, format.wChannels, format.dwSamplesPerSec, (uchar)format.wBitsPerSample));
|
||||
if (!pcm)
|
||||
__ERR__(__LOG_E__ << "failed to allocate WAV data chunk for '" << path << "'.\n", NULL)
|
||||
if (h->Read(pcm, chunk_size) != chunk_size)
|
||||
__ERR__(__LOG_E__ << "mangled WAV 'data' chunk in '" << path << "'.\n", NULL)
|
||||
}
|
||||
else
|
||||
__ERR__(__LOG_E__ << "WAV data with no format in '" << path << "'.\n", NULL)
|
||||
|
||||
has_data = true;
|
||||
}
|
||||
else
|
||||
h->Seek(chunk_size);
|
||||
}
|
||||
|
||||
if (!has_format || !has_data)
|
||||
return NULL;
|
||||
|
||||
SampleFormat sample_format;
|
||||
if (!sample->GetSampleFormat(sample_format))
|
||||
return NULL;
|
||||
|
||||
__LOG__ << "Sample format: " << sample_format.frequency / 1000 << "KHz@" << sample_format.resolution << "bit, " << sample_format.channels << " channel(s).\n";
|
||||
return sample.Detach();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user