*
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\ISoundStream.cpp" />
|
||||
<ClCompile Include="src\OggStream.cpp" />
|
||||
<ClCompile Include="src\SoundSystem.cpp" />
|
||||
<ClCompile Include="src\StaticSound.cpp" />
|
||||
<ClCompile Include="src\StreamedSound.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\ISound.h" />
|
||||
<ClInclude Include="src\ISoundStream.h" />
|
||||
<ClInclude Include="src\OggStream.h" />
|
||||
<ClInclude Include="src\SoundInfo.h" />
|
||||
<ClInclude Include="src\SoundSystem.h" />
|
||||
<ClInclude Include="src\StaticSound.h" />
|
||||
<ClInclude Include="src\StreamedSound.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{AE2D1FB3-7F2E-4C11-9B47-5C44D3D3CAA8}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>LifeSound</RootNamespace>
|
||||
<SccProjectName><Project Location In Database></SccProjectName>
|
||||
<SccAuxPath><Source Control Database></SccAuxPath>
|
||||
<SccLocalPath><Local Binding Root of Project></SccLocalPath>
|
||||
<SccProvider>Mercurial Source Control Package</SccProvider>
|
||||
<VCTargetsPath Condition="'$(VCTargetsPath11)' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''">$(VCTargetsPath11)</VCTargetsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(ProjectName)\lib\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(ProjectName)\tmp\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<TargetName>$(ProjectName)_d</TargetName>
|
||||
<IntDir>$(SolutionDir)$(ProjectName)\tmp\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(ProjectName)\lib\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\Program Files %28x86%29\Visual Leak Detector\include;.\src;$(REPO_DIR)\OpenAL\include;$(SolutionDir)\LifeCore\src;$(REPO_DIR)\libvorbis\include;$(REPO_DIR)\libogg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalLibraryDirectories>C:\Program Files %28x86%29\Visual Leak Detector\lib;$(REPO_DIR)\OpenAL\libs\Win32;$(SolutionDir)\LifeCore\lib;$(REPO_DIR)\libvorbis\win32\VS2010\Win32\Release;$(REPO_DIR)\libogg\win32\VS2010\Win32\Release</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>LifeCore_d.lib;OpenAL32.lib</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\Program Files %28x86%29\Visual Leak Detector\include;.\include;$(REPO_DIR)\OpenAL\include;$(SolutionDir)\LifeCore\include;$(REPO_DIR)\libvorbis\include;$(REPO_DIR)\libogg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<OutputFile>lib\LifeSound_d.lib</OutputFile>
|
||||
<AdditionalLibraryDirectories>C:\Program Files %28x86%29\Visual Leak Detector\lib;$(REPO_DIR)\OpenAL\libs\Win32;$(SolutionDir)\LifeCore\lib;$(REPO_DIR)\libvorbis\win32\VS2010\Win32\Release;$(REPO_DIR)\libogg\win32\VS2010\Win32\Release</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>LifeCore_d.lib;libvorbis.lib;libogg.lib;libvorbisfile.lib;OpenAL32.lib</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.\src;$(REPO_DIR)\OpenAL\include;$(SolutionDir)\LifeCore\src;$(REPO_DIR)\libvorbis\include;$(REPO_DIR)\libogg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalDependencies>LifeCore.lib;OpenAL32.lib</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(REPO_DIR)\OpenAL\libs\Win32;$(SolutionDir)\LifeCore\lib;$(REPO_DIR)\libvorbis\win32\VS2010\Win32\Release;$(REPO_DIR)\libogg\win32\VS2010\Win32\Release</AdditionalLibraryDirectories>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.\include;$(REPO_DIR)\OpenAL\include;$(SolutionDir)\LifeCore\include;$(REPO_DIR)\libvorbis\include;$(REPO_DIR)\libogg\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<Lib>
|
||||
<OutputFile>lib\LifeSound.lib</OutputFile>
|
||||
<AdditionalDependencies>LifeCore.lib;libvorbis.lib;libogg.lib;libvorbisfile.lib;OpenAL32.lib</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(REPO_DIR)\OpenAL\libs\Win32;$(SolutionDir)\LifeCore\lib;$(REPO_DIR)\libvorbis\win32\VS2010\Win32\Release;$(REPO_DIR)\libogg\win32\VS2010\Win32\Release</AdditionalLibraryDirectories>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef ISound_h__
|
||||
#define ISound_h__
|
||||
|
||||
#include <math/LifeMath.h>
|
||||
#include <IDataStream.h>
|
||||
|
||||
namespace Sound
|
||||
{
|
||||
enum STREAMING_MODE
|
||||
{
|
||||
SM_DISABLED = 0,
|
||||
SM_ENABLED = 1,
|
||||
SM_AUTO = 2
|
||||
};
|
||||
class ISound
|
||||
{
|
||||
public:
|
||||
ISound() {}
|
||||
virtual void Play() = 0;
|
||||
virtual void Stop() = 0;
|
||||
virtual void Update() = 0;
|
||||
virtual void Move(const LifeMath::Vec3f& position) = 0;
|
||||
virtual bool IsPlaying() = 0;
|
||||
virtual size_t GetPlaybackPosition() = 0;
|
||||
virtual size_t GetByteLength(){return 0;}
|
||||
virtual void SetPlaybackPosition(float pos){}
|
||||
virtual double GetTimeLength(){return 0;}
|
||||
virtual double GetTimePosition(){return 0;}
|
||||
virtual void SeekTime(double position){}
|
||||
virtual ~ISound() {}
|
||||
};
|
||||
}
|
||||
#endif // Sound_h__
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "ISoundStream.h"
|
||||
|
||||
namespace Sound
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef ISoundStream_h__
|
||||
#define ISoundStream_h__
|
||||
|
||||
namespace Sound
|
||||
{
|
||||
class ISoundStream
|
||||
{
|
||||
public:
|
||||
ISoundStream();
|
||||
virtual ~ISoundStream();
|
||||
int seek();
|
||||
};
|
||||
}
|
||||
#endif // ISoundStream_h__
|
||||
@@ -0,0 +1,158 @@
|
||||
#include "OggStream.h"
|
||||
|
||||
namespace Sound
|
||||
{
|
||||
size_t ReadOgg(void *ptr, size_t size, size_t nmemb, void *datasource)
|
||||
{
|
||||
LifeCore::IDataStream *File = reinterpret_cast<LifeCore::IDataStream*>(datasource);
|
||||
int countRead = File->Read(ptr, size * nmemb);
|
||||
return countRead;
|
||||
}
|
||||
int SeekOgg(void *datasource, ogg_int64_t offset, int whence)
|
||||
{
|
||||
LifeCore::IDataStream *File = reinterpret_cast<LifeCore::IDataStream*>(datasource);
|
||||
int pos = 0;
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET: pos = (int)offset; break;
|
||||
case SEEK_CUR: pos = (int)offset + File->Tell(); break;
|
||||
case SEEK_END: pos = (int)offset + File->Length(); break;
|
||||
default: return -1;
|
||||
}
|
||||
if(pos > File->Length()) pos = File->Length();
|
||||
File->Seek(pos);
|
||||
return 0;
|
||||
}
|
||||
long TellOgg(void *datasource)
|
||||
{
|
||||
LifeCore::IDataStream *File = reinterpret_cast<LifeCore::IDataStream*>(datasource);
|
||||
return File->Tell();
|
||||
}
|
||||
int CloseOgg(void *datasource)
|
||||
{
|
||||
if(datasource)
|
||||
{
|
||||
LifeCore::IDataStream *File = reinterpret_cast<LifeCore::IDataStream*>(datasource);
|
||||
File->Close();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
ALint OggStream::GetPosition()
|
||||
{
|
||||
return position;
|
||||
}
|
||||
OggStream::OggStream(LifeCore::IFileSystem* fs)
|
||||
:ogg(0), position(0)
|
||||
{
|
||||
fileSystem = fs;
|
||||
}
|
||||
OggStream::~OggStream()
|
||||
{
|
||||
if(!ogg)
|
||||
{
|
||||
ov_clear(ogg);
|
||||
delete ogg;
|
||||
}
|
||||
}
|
||||
int OggStream::Open(const String& fn)
|
||||
{
|
||||
name = fn;
|
||||
|
||||
LifeCore::IFile* f;
|
||||
|
||||
if(fileSystem->GetFile(name, &f) != SC_OK)
|
||||
return SC_FAIL;
|
||||
|
||||
stm = f->OpenRead();
|
||||
|
||||
ogg = new OggVorbis_File();
|
||||
ov_callbacks cb;
|
||||
cb.read_func = ReadOgg;
|
||||
cb.close_func = CloseOgg;
|
||||
cb.seek_func = SeekOgg;
|
||||
cb.tell_func = TellOgg;
|
||||
|
||||
ov_open_callbacks(stm.get(), ogg, NULL, -1, cb);
|
||||
|
||||
//get uncompressed PCM data size
|
||||
|
||||
vorbis_info * oggInfo;
|
||||
oggInfo = ov_info(ogg, -1);
|
||||
rate = oggInfo->rate;
|
||||
format = (oggInfo->channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
|
||||
|
||||
pcmsize = ov_pcm_total(ogg, -1) * 2 * oggInfo->channels;
|
||||
return SC_OK;
|
||||
}
|
||||
|
||||
ALuint OggStream::GetFormat()
|
||||
{
|
||||
return format;
|
||||
}
|
||||
ALuint OggStream::GetRate()
|
||||
{
|
||||
return rate;
|
||||
}
|
||||
ALuint OggStream::GetPCMSize()
|
||||
{
|
||||
return pcmsize;
|
||||
}
|
||||
size_t OggStream::GetSourceSize()
|
||||
{
|
||||
return stm->Length();
|
||||
}
|
||||
void OggStream::SeekPCM(int _position)
|
||||
{
|
||||
int r = ov_pcm_seek(ogg, _position);
|
||||
position = _position;
|
||||
}
|
||||
double OggStream::GetTimeLength()
|
||||
{
|
||||
return ov_time_total(ogg, -1);
|
||||
}
|
||||
void OggStream::SeekTime(double time)
|
||||
{
|
||||
ov_time_seek(ogg, time);
|
||||
}
|
||||
double OggStream::GetTimePosition()
|
||||
{
|
||||
return ov_time_tell(ogg);
|
||||
}
|
||||
ALuint OggStream::Read(char* pData, int length, bool readLooped)
|
||||
{
|
||||
if(!length) return 0;
|
||||
int section;
|
||||
char* data = pData;
|
||||
int totalRead = 0;
|
||||
|
||||
while(totalRead < length)
|
||||
{
|
||||
int readCount = ov_read(ogg, data + totalRead, length - totalRead, 0, 2, 1, §ion);
|
||||
|
||||
if(readCount < 0) //error
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (readCount > 0) //read successful
|
||||
{
|
||||
totalRead += readCount;
|
||||
position+=readCount;
|
||||
}
|
||||
else //end of PCM stream
|
||||
{
|
||||
if(readLooped)
|
||||
{
|
||||
ov_pcm_seek(ogg, 0);
|
||||
position = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//memset(data + totalRead, 0, length - totalRead);
|
||||
return totalRead;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return totalRead;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#ifndef OggStream_h__
|
||||
#define OggStream_h__
|
||||
|
||||
#include <vfs/IFileSystem.h>
|
||||
#include <LString.h>
|
||||
#include <Types.h>
|
||||
#include <al.h>
|
||||
#include <alc.h>
|
||||
#include <ogg/ogg.h>
|
||||
#include <vorbis/codec.h>
|
||||
#include <vorbis/vorbisfile.h>
|
||||
#include <vorbis/vorbisenc.h>
|
||||
|
||||
namespace Sound
|
||||
{
|
||||
class OggStream
|
||||
{
|
||||
public:
|
||||
OggStream(LifeCore::IFileSystem* fs);
|
||||
~OggStream();
|
||||
int Open(const String& fn);
|
||||
ALuint GetFormat();
|
||||
ALuint GetRate();
|
||||
ALuint GetPCMSize();
|
||||
void SeekPCM(int position);
|
||||
ALuint Read(char* pData, int length, bool readLooped);
|
||||
ALint GetPosition();
|
||||
size_t GetSourceSize();
|
||||
double GetTimeLength();
|
||||
double GetTimePosition();
|
||||
void SeekTime(double time);
|
||||
//size_t GetSize();
|
||||
private:
|
||||
size_t position;
|
||||
LifeCore::IFileSystem* fileSystem;
|
||||
LifeCore::IDataStreamPtr stm;
|
||||
String name;
|
||||
vorbis_info info;
|
||||
ALuint rate;
|
||||
ALuint format;
|
||||
ALuint pcmsize;
|
||||
OggVorbis_File* ogg;
|
||||
};
|
||||
}
|
||||
#endif // OggStream_h__
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef SoundBuffer_h__
|
||||
#define SoundBuffer_h__
|
||||
|
||||
//#define BUFFER_SIZE (4096 * 8)
|
||||
|
||||
namespace Sound
|
||||
{
|
||||
struct SoundInfo
|
||||
{
|
||||
unsigned int id;
|
||||
unsigned int format;
|
||||
unsigned int rate;
|
||||
unsigned int size;
|
||||
};
|
||||
}
|
||||
#endif // SoundBuffer_h__
|
||||
@@ -0,0 +1,154 @@
|
||||
#include "SoundSystem.h"
|
||||
#include <al.h>
|
||||
#include <alc.h>
|
||||
#include <ogg/ogg.h>
|
||||
#include <vorbis/codec.h>
|
||||
#include <vorbis/vorbisfile.h>
|
||||
#include <vorbis/vorbisenc.h>
|
||||
#include "OggStream.h"
|
||||
#include "StaticSound.h"
|
||||
#include "StreamedSound.h"
|
||||
|
||||
//#define BUFFER_SIZE (4096 * 8)
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Sound
|
||||
{
|
||||
static ALCdevice* dev;
|
||||
static ALCcontext* context;
|
||||
static ALfloat ListenerPos[] = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
static std::vector<ISound*> sounds;
|
||||
|
||||
// Ñêîðîñòü ñëóøàòåëÿ.
|
||||
static ALfloat ListenerVel[] = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
// Îðèåíòàöèÿ ñëóøàòåëÿ. (Ïåðâûå 3 ýëåìåíòà – íàïðàâëåíèå «íà», ïîñëåäíèå 3 – «ââåðõ»)
|
||||
static ALfloat ListenerOri[] = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
|
||||
|
||||
SoundSystem::SoundSystem()
|
||||
{
|
||||
}
|
||||
SoundSystem::~SoundSystem()
|
||||
{
|
||||
for(CacheMapIter it = staticCache.begin(); it != staticCache.end(); it++)
|
||||
{
|
||||
if(it->second)
|
||||
{
|
||||
if(alIsBuffer(it->second->id))
|
||||
{
|
||||
alDeleteBuffers(1, &it->second->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
alcDestroyContext(context);
|
||||
alcCloseDevice(dev);
|
||||
}
|
||||
int SoundSystem::Init(LifeCore::IFileSystem* fs)
|
||||
{
|
||||
fileSystem = fs;
|
||||
|
||||
char* DefaultDevice = (char*)alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||
printf("%s\n", DefaultDevice);
|
||||
|
||||
dev = alcOpenDevice("Generic Software");
|
||||
|
||||
ALenum error = alGetError();
|
||||
if(error!= AL_NO_ERROR)
|
||||
{
|
||||
printf("Error initializing sound device context!\n");
|
||||
return -1;
|
||||
}
|
||||
context = alcCreateContext(dev, NULL);
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
return AL_FALSE;
|
||||
|
||||
alcMakeContextCurrent(context);
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
return AL_FALSE;
|
||||
alListenerfv(AL_POSITION, ListenerPos);
|
||||
alListenerfv(AL_VELOCITY, ListenerVel);
|
||||
alListenerfv(AL_ORIENTATION, ListenerOri);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SoundSystem::Update()
|
||||
{
|
||||
for(std::vector<ISound*>::iterator it = sounds.begin(); it != sounds.end(); it++)
|
||||
{
|
||||
(*it)->Update();
|
||||
}
|
||||
}
|
||||
|
||||
ISound* SoundSystem::getSound(const String& name, int streamingMode)
|
||||
{
|
||||
switch(streamingMode)
|
||||
{
|
||||
case SM_ENABLED:
|
||||
{
|
||||
OggStream* s = new OggStream(fileSystem);
|
||||
s->Open(name);
|
||||
ISound* sound = new StreamedSound(s, true);
|
||||
sounds.push_back(sound);
|
||||
return sound;
|
||||
}
|
||||
break;
|
||||
case SM_DISABLED:
|
||||
{
|
||||
CacheMapIter it = staticCache.find(name);
|
||||
SoundInfo* src = 0;
|
||||
if(it != staticCache.end())
|
||||
{
|
||||
src = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
OggStream s(fileSystem);
|
||||
s.Open(name);
|
||||
|
||||
src = new SoundInfo();
|
||||
src->size = s.GetPCMSize();
|
||||
src->format = s.GetFormat();
|
||||
src->rate = s.GetRate();
|
||||
|
||||
alGenBuffers(1, &src->id);
|
||||
|
||||
//read all PCM data
|
||||
char* pcmData = new char[src->size];
|
||||
if(s.Read(pcmData, src->size, false) != src->size)
|
||||
{
|
||||
//error!!!!!
|
||||
}
|
||||
|
||||
//copy PCM data to OpenAL sound buffer
|
||||
alBufferData(src->id, src->format, pcmData, src->size, src->rate);
|
||||
|
||||
//delete temporary PCM buffer
|
||||
delete[] pcmData;
|
||||
|
||||
staticCache[name] = src;
|
||||
}
|
||||
|
||||
if(src)
|
||||
{
|
||||
ISound* s = new StaticSound(src, true);
|
||||
sounds.push_back(s);
|
||||
return s;
|
||||
}
|
||||
else //error
|
||||
{
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SM_AUTO:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef SoundSystem_h__
|
||||
#define SoundSystem_h__
|
||||
|
||||
#include <vfs/IFileSystem.h>
|
||||
#include "ISound.h"
|
||||
#include <IMemoryStream.h>
|
||||
#include "SoundInfo.h"
|
||||
#include <map>
|
||||
|
||||
namespace Sound
|
||||
{
|
||||
class SoundSystem
|
||||
{
|
||||
private:
|
||||
typedef std::map<String, SoundInfo*> CacheMap;
|
||||
typedef std::map<String, SoundInfo*>::iterator CacheMapIter;
|
||||
LifeCore::IFileSystem* fileSystem;
|
||||
CacheMap staticCache;
|
||||
public:
|
||||
SoundSystem();
|
||||
~SoundSystem();
|
||||
int Init(LifeCore::IFileSystem* fs);
|
||||
void Update();
|
||||
ISound* getSound(const String& name, int streamingMode);
|
||||
};
|
||||
}
|
||||
#endif // SoundSystem_h__
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "StaticSound.h"
|
||||
#include <math/LifeMath.h>
|
||||
|
||||
namespace Sound
|
||||
{
|
||||
StaticSound::StaticSound(SoundInfo* src, bool looped)
|
||||
{
|
||||
velocity = position = LifeMath::Vec3f(0.0f, 0.0f, 0.0f);
|
||||
|
||||
data = src;
|
||||
alGenSources(1, &source);
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
printf("FUCK!");
|
||||
alSourcef (source, AL_PITCH, 1.0f);
|
||||
alSourcef (source, AL_GAIN, 1.0f);
|
||||
alSourcefv(source, AL_POSITION, reinterpret_cast<ALfloat*>(&position.X));
|
||||
alSourcefv(source, AL_VELOCITY, reinterpret_cast<ALfloat*>(&velocity.X));
|
||||
alSourcei (source, AL_LOOPING, looped);
|
||||
|
||||
//attach sound buffer to source
|
||||
alSourcei (source, AL_BUFFER, src->id);
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
printf("FUCK!");
|
||||
}
|
||||
size_t StaticSound::GetPlaybackPosition()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
StaticSound::~StaticSound()
|
||||
{
|
||||
if(alIsSource(source))
|
||||
alDeleteSources(1, &source);
|
||||
}
|
||||
void StaticSound::Play()
|
||||
{
|
||||
alSourcePlay(source);
|
||||
}
|
||||
bool StaticSound::IsPlaying()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void StaticSound::Stop()
|
||||
{
|
||||
alSourceStop(source);
|
||||
}
|
||||
void StaticSound::Update()
|
||||
{
|
||||
return;
|
||||
}
|
||||
void StaticSound::Move(const LifeMath::Vec3f& pos)
|
||||
{
|
||||
position = pos;
|
||||
alSourcefv(source, AL_POSITION, reinterpret_cast<ALfloat*>(&position.X));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef StaticSound_h__
|
||||
#define StaticSound_h__
|
||||
|
||||
#include "ISound.h"
|
||||
#include <al.h>
|
||||
#include <alc.h>
|
||||
#include "SoundInfo.h"
|
||||
|
||||
namespace Sound
|
||||
{
|
||||
class StaticSound : public ISound
|
||||
{
|
||||
public:
|
||||
StaticSound(SoundInfo* src, bool looped);
|
||||
~StaticSound();
|
||||
void Play();
|
||||
void Stop();
|
||||
void Update();
|
||||
void Move(const LifeMath::Vec3f& pos);
|
||||
bool IsPlaying();
|
||||
size_t GetPlaybackPosition();
|
||||
private:
|
||||
ALuint source;
|
||||
LifeMath::Vec3f position;
|
||||
LifeMath::Vec3f velocity;
|
||||
SoundInfo* data;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // StaticSound_h__
|
||||
@@ -0,0 +1,137 @@
|
||||
#include "StreamedSound.h"
|
||||
|
||||
namespace Sound
|
||||
{
|
||||
StreamedSound::StreamedSound(OggStream* stm, bool looped)
|
||||
:loop(looped), stopped(true)
|
||||
{
|
||||
data = stm;
|
||||
|
||||
velocity = position = LifeMath::Vec3f(0.0f, 0.0f, 0.0f);
|
||||
ALenum error;
|
||||
|
||||
data = stm;
|
||||
alGenSources(1, &source);
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
printf("FUCK!");
|
||||
alSourcef (source, AL_PITCH, 1.0f);
|
||||
alSourcef (source, AL_GAIN, 1.0f);
|
||||
alSourcefv(source, AL_POSITION, reinterpret_cast<ALfloat*>(&position.X));
|
||||
alSourcefv(source, AL_VELOCITY, reinterpret_cast<ALfloat*>(&velocity.X));
|
||||
alSourcei (source, AL_LOOPING, AL_FALSE);
|
||||
|
||||
error = alGetError();
|
||||
|
||||
if (error != AL_NO_ERROR)
|
||||
printf("%s\n", (char *)alGetString(error));
|
||||
//attach sound buffer to source
|
||||
//alSourcei (source, AL_BUFFER, src->id);
|
||||
|
||||
for(int i = 0; i< BUFFERS_COUNT; i++)
|
||||
{
|
||||
alGenBuffers(BUFFERS_COUNT, &buffers[i]);
|
||||
|
||||
error = alGetError();
|
||||
|
||||
if (error != AL_NO_ERROR)
|
||||
printf("%s\n", (char *)alGetString(error));
|
||||
|
||||
if(!alIsBuffer(buffers[i]))
|
||||
{
|
||||
printf("TRINDEC!!!!!\n");
|
||||
}
|
||||
|
||||
stm->Read(tempBuffer, BUFFER_SIZE, looped);
|
||||
alBufferData(buffers[i], stm->GetFormat(), &tempBuffer[0], BUFFER_SIZE, stm->GetRate() );
|
||||
|
||||
error = alGetError();
|
||||
|
||||
if (error != AL_NO_ERROR)
|
||||
printf("%s\n", (char *)alGetString(error));
|
||||
|
||||
alSourceQueueBuffers(source, 1, &buffers[i]);
|
||||
}
|
||||
|
||||
error = alGetError();
|
||||
|
||||
if (error != AL_NO_ERROR)
|
||||
printf("%s\n", (char *)alGetString(error));
|
||||
}
|
||||
StreamedSound::~StreamedSound()
|
||||
{
|
||||
}
|
||||
size_t StreamedSound::GetByteLength()
|
||||
{
|
||||
return data->GetPCMSize();
|
||||
//return data->GetSourceSize();
|
||||
}
|
||||
double StreamedSound::GetTimeLength()
|
||||
{
|
||||
return data->GetTimeLength();
|
||||
}
|
||||
double StreamedSound::GetTimePosition()
|
||||
{
|
||||
return data->GetTimePosition();
|
||||
}
|
||||
void StreamedSound::SetPlaybackPosition(float pos)
|
||||
{
|
||||
int a = GetPlaybackPosition();
|
||||
data->SeekPCM(int(float(data->GetPCMSize()) * pos));
|
||||
}
|
||||
void StreamedSound::SeekTime(double position)
|
||||
{
|
||||
data->SeekTime(position);
|
||||
}
|
||||
size_t StreamedSound::GetPlaybackPosition()
|
||||
{
|
||||
//ALint val;
|
||||
//alGetSourcei(source, AL_BYTE_OFFSET, &val);
|
||||
return abs(data->GetPosition());
|
||||
}
|
||||
bool StreamedSound::IsPlaying()
|
||||
{
|
||||
return !stopped;
|
||||
}
|
||||
void StreamedSound::Play()
|
||||
{
|
||||
alSourcePlay(source);
|
||||
stopped = false;
|
||||
}
|
||||
void StreamedSound::Stop()
|
||||
{
|
||||
alSourceStop(source);
|
||||
stopped = true;
|
||||
}
|
||||
void StreamedSound::Update()
|
||||
{
|
||||
if(!stopped)
|
||||
{
|
||||
int procCount = 0;
|
||||
alGetSourcei(source, AL_BUFFERS_PROCESSED, &procCount);
|
||||
ALuint bid;
|
||||
|
||||
while(procCount--)
|
||||
{
|
||||
alSourceUnqueueBuffers(source, 1, &bid);
|
||||
int cr = data->Read(tempBuffer, BUFFER_SIZE, loop);
|
||||
|
||||
if(cr == 0)
|
||||
{
|
||||
if(!loop)
|
||||
{
|
||||
Stop();
|
||||
data->SeekPCM(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
alBufferData(bid, data->GetFormat(), tempBuffer, cr, data->GetRate() );
|
||||
alSourceQueueBuffers(source, 1, &bid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void StreamedSound::Move(const LifeMath::Vec3f& pos)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef StreamedSound_h__
|
||||
#define StreamedSound_h__
|
||||
|
||||
#include "OggStream.h"
|
||||
#include <math/LifeMath.h>
|
||||
#include <vector>
|
||||
#include "ISound.h"
|
||||
|
||||
namespace Sound
|
||||
{
|
||||
#define BUFFERS_COUNT 2
|
||||
#define BUFFER_SIZE (4096 * 16)
|
||||
|
||||
class StreamedSound : public ISound
|
||||
{
|
||||
public:
|
||||
StreamedSound(OggStream* stm, bool looped);
|
||||
~StreamedSound();
|
||||
void Play();
|
||||
void Stop();
|
||||
void Update();
|
||||
void Move(const LifeMath::Vec3f& pos);
|
||||
bool IsPlaying();
|
||||
size_t GetPlaybackPosition();
|
||||
size_t GetByteLength();
|
||||
void SetPlaybackPosition(float pos);
|
||||
double GetTimeLength();
|
||||
void SeekTime(double position);
|
||||
double GetTimePosition();
|
||||
private:
|
||||
ALuint source;
|
||||
LifeMath::Vec3f position;
|
||||
LifeMath::Vec3f velocity;
|
||||
OggStream* data;
|
||||
char tempBuffer[BUFFER_SIZE];
|
||||
ALuint buffers[BUFFERS_COUNT];
|
||||
bool loop;
|
||||
bool stopped;
|
||||
};
|
||||
}
|
||||
#endif // StreamedSound_h__
|
||||
Reference in New Issue
Block a user