Jelajahi Sumber

implement SoundCompiler

mikymod 12 tahun lalu
induk
melakukan
61290f3c0b

+ 3 - 0
engine/CMakeLists.txt

@@ -59,6 +59,7 @@ set (CROWN_INCLUDES
 	${CMAKE_SOURCE_DIR}/engine/compilers
 	${CMAKE_SOURCE_DIR}/engine/compilers/lua
 	${CMAKE_SOURCE_DIR}/engine/compilers/texture
+	${CMAKE_SOURCE_DIR}/engine/compilers/sound
 	${CMAKE_SOURCE_DIR}/engine/compilers/mesh
 )
 
@@ -336,6 +337,7 @@ set (COMPILER_SRC
 	compilers/BundleCompiler.cpp
 	compilers/lua/LuaCompiler.cpp
 	compilers/texture/TextureCompiler.cpp
+	compilers/sound/SoundCompiler.cpp
 )
 
 set (COMPILER_HEADER
@@ -343,6 +345,7 @@ set (COMPILER_HEADER
 	compilers/BundleCompiler.h
 	compilers/lua/LuaCompiler.h
 	compilers/texture/TextureCompiler.h
+	compilers/sound/SoundCompiler.h
 )
 
 set (CROWN_LIBRARIES)

+ 4 - 0
engine/compilers/BundleCompiler.cpp

@@ -99,6 +99,10 @@ bool BundleCompiler::compile(const char* bundle_dir, const char* source_dir)
 		{
 			result = m_lua.compile(source_dir, bundle_dir, filename, out_name);
 		}
+		else if(resource_type_hash == SOUND_TYPE)
+		{
+			result = m_sound.compile(source_dir, bundle_dir, filename, out_name);
+		}
 		else
 		{
 			Log::e("Oops, unknown resource type!");

+ 2 - 0
engine/compilers/BundleCompiler.h

@@ -28,6 +28,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #include "TextureCompiler.h"
 #include "LuaCompiler.h"
+#include "SoundCompiler.h"
 #include "DynamicString.h"
 #include "Vector.h"
 #include "DiskFilesystem.h"
@@ -51,6 +52,7 @@ private:
 
 	TextureCompiler	m_texture;
 	LuaCompiler 	m_lua;
+	SoundCompiler	m_sound;
 };
 
 } // namespace crown

+ 181 - 0
engine/compilers/sound/SoundCompiler.cpp

@@ -0,0 +1,181 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <stdio.h>
+#include <limits.h>
+#include <errno.h>
+
+#include <ogg/ogg.h>
+#include <vorbis/codec.h>
+#include <vorbis/vorbisenc.h>
+#include <vorbis/vorbisfile.h>
+
+#include "SoundCompiler.h"
+#include "Allocator.h"
+#include "Filesystem.h"
+#include "StringUtils.h"
+#include "DynamicString.h"
+#include "OS.h"
+
+namespace crown
+{
+
+//-----------------------------------------------------------------------------
+SoundCompiler::SoundCompiler() :
+	m_sound_data_size(0),
+	m_sound_data(NULL)
+{
+}
+
+//-----------------------------------------------------------------------------
+SoundCompiler::~SoundCompiler()
+{
+}
+
+//-----------------------------------------------------------------------------
+size_t SoundCompiler::compile_impl(Filesystem& fs, const char* resource_path)
+{
+	size_t size = 0;
+	
+	size = compile_if_wav(fs, resource_path);
+
+	if (size == 0)
+	{
+		size = compile_if_ogg(fs, resource_path);
+	}
+	
+	return size;
+}
+
+//-----------------------------------------------------------------------------
+void SoundCompiler::write_impl(File* out_file)
+{
+	out_file->write((char*)&m_sound_header, sizeof(SoundHeader));
+	out_file->write((char*)m_sound_data, m_sound_data_size);
+
+	if (m_sound_data)
+	{
+
+		default_allocator().deallocate(m_sound_data);
+		m_sound_data_size = 0;
+		m_sound_data = NULL;
+	}
+}
+
+//-----------------------------------------------------------------------------
+size_t SoundCompiler::compile_if_wav(Filesystem& fs, const char* resource_path)
+{
+	File* in_file = fs.open(resource_path, FOM_READ);
+
+	WAVHeader header;
+
+	in_file->read((char*)&header, sizeof(WAVHeader));
+
+	if (header.riff[0] != 'R' && header.riff[1] != 'I' && header.riff[2] != 'F' && header.riff[3] != 'F')
+	{
+		if (header.wave[0] != 'W' && header.wave[1] != 'A' && header.wave[2] != 'V' && header.wave[3] != 'E')
+		{
+			if (header.fmt[0] != 'f' && header.fmt[1] != 'm' && header.fmt[2] != 't' && header.fmt[3] != ' ')
+			{
+				fs.close(in_file);
+				return 0;
+			}
+		}
+	}
+
+	m_sound_header.version = SOUND_VERSION;
+	m_sound_header.size = header.data_size;
+	m_sound_header.sample_rate = header.fmt_sample_rate;
+	m_sound_header.channels = header.fmt_channels;
+	m_sound_header.bits_per_sample = header.fmt_bits_per_sample;
+	m_sound_header.sound_type = ST_WAV;
+
+	m_sound_data_size = header.data_size;
+	m_sound_data = (uint8_t*)default_allocator().allocate(m_sound_data_size);
+
+	in_file->read((char*)m_sound_data, m_sound_data_size);
+
+	fs.close(in_file);
+
+	return sizeof(SoundHeader) + m_sound_data_size;
+}
+
+//-----------------------------------------------------------------------------
+size_t SoundCompiler::compile_if_ogg(Filesystem& fs, const char* resource_path)
+{
+	FILE* tmp_file;
+
+	// Retrieves resource absolute path
+	DynamicString s(default_allocator());
+	fs.get_absolute_path(resource_path, s);
+	const char* abs_path = s.c_str();
+
+	Log::i("abs_path = %s", abs_path);
+
+	if ((tmp_file = fopen(abs_path, "rb")) == NULL)
+	{
+		printf("Unable to open file: '%s'\n", resource_path);
+		perror("Reason");
+		return 0;	
+	}
+
+	OggVorbis_File ogg_stream;
+
+	bool result = ov_open(tmp_file, &ogg_stream, NULL, 0) == 0;
+
+	if (result == false)
+	{
+		return 0;
+	}
+
+	vorbis_info* info = ov_info(&ogg_stream, -1);
+
+	int64_t size = ov_raw_total(&ogg_stream, -1);
+	int32_t rate = info->rate;
+	int32_t channels = info->channels;
+
+	ov_clear(&ogg_stream);
+
+	File* in_file = fs.open(resource_path, FOM_READ);
+
+	m_sound_header.version = SOUND_VERSION;
+	m_sound_header.size = size;
+	m_sound_header.sample_rate = rate;
+	m_sound_header.channels = channels;
+	m_sound_header.bits_per_sample = 16;
+	m_sound_header.sound_type = ST_OGG;
+
+	m_sound_data_size = size;
+	m_sound_data = (uint8_t*)default_allocator().allocate(m_sound_data_size);
+
+	in_file->read((char*)m_sound_data, m_sound_data_size);
+
+	fs.close(in_file);
+
+	return sizeof(SoundHeader) + m_sound_data_size;
+}
+
+} // namespace crown

+ 79 - 0
engine/compilers/sound/SoundCompiler.h

@@ -0,0 +1,79 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include <cstdio>
+
+#include "Compiler.h"
+#include "SoundResource.h"
+
+
+namespace crown
+{
+
+//-----------------------------------------------------------------------------
+struct WAVHeader
+{
+	char 			riff[4];				// Should contains 'RIFF'
+	int32_t			chunk_size;				// Not Needed
+	char 			wave[4];				// Should contains 'WAVE'
+	char 			fmt[4];					// Should contains 'fmt '
+	int32_t			fmt_size;				// Size of format chunk
+	int16_t			fmt_tag;				// Identifies way data is stored, 1 means no compression
+	int16_t			fmt_channels;			// Channel, 1 means mono, 2 means stereo
+	int32_t			fmt_sample_rate;		// Sample per second
+	int32_t			fmt_avarage;			// Not needed, here for completness
+	int16_t			fmt_block_align;		// Block alignment
+	int16_t			fmt_bits_per_sample;	// Number of bits per sample
+	char 			data[4];				// Should contains 'data'
+	int32_t			data_size;				// Data dimension
+};
+
+//-----------------------------------------------------------------------------
+class SoundCompiler : public Compiler
+{
+public:
+
+						SoundCompiler();
+						~SoundCompiler();
+
+	size_t				compile_impl(Filesystem& fs, const char* resource_path);
+	void				write_impl(File* out_file);
+
+private:
+
+	size_t				compile_if_wav(Filesystem& fs, const char* resource_path);
+	size_t				compile_if_ogg(Filesystem& fs, const char* resource_path);
+
+private:
+
+	SoundHeader			m_sound_header;
+	size_t				m_sound_data_size;
+	uint8_t*			m_sound_data;
+};
+
+} // namespace crown

+ 1 - 0
engine/resource/SoundResource.h

@@ -30,6 +30,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Resource.h"
 #include "Bundle.h"
 #include "Allocator.h"
+#include "File.h"
 
 namespace crown
 {