about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/engine/client/snd.cpp85
-rw-r--r--src/engine/interface.h1
-rw-r--r--src/game/client/game_client.cpp10
3 files changed, 95 insertions, 1 deletions
diff --git a/src/engine/client/snd.cpp b/src/engine/client/snd.cpp
index 2b01fc84..69cca0f5 100644
--- a/src/engine/client/snd.cpp
+++ b/src/engine/client/snd.cpp
@@ -4,6 +4,10 @@
 
 #include <engine/interface.h>
 
+extern "C" {
+#include "../../wavpack/wavpack.h"
+}
+
 using namespace baselib;
 
 static const int NUM_FRAMES_STOP = 512;
@@ -244,6 +248,87 @@ static int snd_alloc_sound()
 	return id;
 }
 
+static FILE *file = NULL;
+
+static int read_data(void *buffer, int size)
+{
+	return fread(buffer, 1, size, file);	
+}
+
+int snd_load_wv(const char *filename)
+{
+	sound_data snd;
+	int id = -1;
+
+	char error[100];
+
+	file = fopen(filename, "r");
+
+	WavpackContext *context = WavpackOpenFileInput(read_data, error);
+	if (context)
+	{
+		int samples = WavpackGetNumSamples(context);
+		int bitspersample = WavpackGetBitsPerSample(context);
+		int bytespersample = WavpackGetBytesPerSample(context);
+		unsigned int samplerate = WavpackGetSampleRate(context);
+		int channels = WavpackGetNumChannels(context);
+
+		snd.channels = channels;
+		snd.rate = samplerate;
+
+		if(snd.channels > 2)
+		{
+			dbg_msg("sound/wv", "file is not mono or stereo. filename='%s'", filename);
+			return -1;
+		}
+
+		if(snd.rate != 44100)
+		{
+			dbg_msg("sound/wv", "file is %d Hz, not 44100 Hz. filename='%s'", snd.rate, filename);
+			return -1;
+		}
+		
+		if(bitspersample != 16)
+		{
+			dbg_msg("sound/wv", "bps is %d, not 16, filname='%s'", bitspersample, filename);
+			return -1;
+		}
+
+		int *data = (int *)mem_alloc(4*samples*channels, 1);
+		WavpackUnpackSamples(context, data, samples); // TODO: check return value
+		int *src = data;
+		
+		snd.data = (short *)mem_alloc(2*samples*channels, 1);
+		short *dst = snd.data;
+
+		for (int i = 0; i < samples*channels; i++)
+			*dst++ = (short)*src++;
+
+		mem_free(data);
+
+		snd.num_samples = samples;
+		snd.sustain_start = -1;
+		snd.sustain_end = -1;
+		snd.last_played = 0;
+		id = snd_alloc_sound();
+		sounds[id].sound = snd;
+	}
+	else
+	{
+		dbg_msg("sound/wv", "failed to open %s: %s", filename, error);
+	}
+
+	fclose(file);
+	file = NULL;
+
+	if(id >= 0)
+		dbg_msg("sound/wv", "loaded %s", filename);
+	else
+		dbg_msg("sound/wv", "failed to load %s", filename);
+
+	return id;
+}
+
 int snd_load_wav(const char *filename)
 {
 	sound_data snd;
diff --git a/src/engine/interface.h b/src/engine/interface.h
index 1f8a02b7..4d92e87f 100644
--- a/src/engine/interface.h
+++ b/src/engine/interface.h
@@ -333,6 +333,7 @@ bool snd_init();
 float snd_get_master_volume();
 void snd_set_master_volume(float val);
 int snd_load_wav(const char *filename);
+int snd_load_wv(const char *filename);
 int snd_play(int sound, int loop = SND_PLAY_ONCE, float vol = 1.0f, float pan = 0.0f);
 void snd_stop(int id);
 void snd_set_vol(int id, float vol);
diff --git a/src/game/client/game_client.cpp b/src/game/client/game_client.cpp
index 91bc2fa3..7d70d7e4 100644
--- a/src/game/client/game_client.cpp
+++ b/src/game/client/game_client.cpp
@@ -447,7 +447,15 @@ void modc_init()
 	// load sounds
 	for(int s = 0; s < data->num_sounds; s++)
 		for(int i = 0; i < data->sounds[s].num_sounds; i++)
-			data->sounds[s].sounds[i].id = snd_load_wav(data->sounds[s].sounds[i].filename);
+		{
+			int id;
+			if (strcmp(data->sounds[s].sounds[i].filename + strlen(data->sounds[s].sounds[i].filename) - 3, ".wv") == 0)
+				id = snd_load_wv(data->sounds[s].sounds[i].filename);
+			else
+				id = snd_load_wav(data->sounds[s].sounds[i].filename);
+
+			data->sounds[s].sounds[i].id = id;
+		}
 	
 	// load textures
 	for(int i = 0; i < data->num_images; i++)