/*  TA3D, a remake of Total Annihilation
    Copyright (C) 2005  Roland BROCHARD

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA*/

/*-----------------------------------------------------------------------------------\
|                                       sound.cpp                                    |
|   Ce module contient les structures, classes et fonctions nécessaires à la gestion |
| des sons.                                                                          |
|                                                                                    |
\-----------------------------------------------------------------------------------*/

#include <allegro.h>
#include "sound.h"

SOUND_MANAGER sound_manager;

SAMPLE *load_memory_wav(byte *data,int size)				// Charge un fichier wav contenu dans une mémoire tampon pointée par *data
{
	char buffer[25];
	int i;
	int length, len;
	int freq = 22050;
	int bits = 8;
	int channels = 1;
	int s;
	SAMPLE *spl = NULL;

	memset(buffer, 0, sizeof buffer);

	int pos=0;

	memcpy(buffer, data+pos, 12);	pos+=12;			/* check RIFF header */
	if (memcmp(buffer, "RIFF", 4) || memcmp(buffer+8, "WAVE", 4))
		goto getout;

	while (TRUE) {
		if(pos+4>size)
			break;
		memcpy(buffer, data+pos, 4);
		pos+=4;

		length = *((int*)(data+pos));			/* read chunk length */
		pos+=4;

		if (memcmp(buffer, "fmt ", 4) == 0) {
			i = *((short*)(data+pos));			/* read chunk length */
			pos+=2;
			length -= 2;
			if (i != 1) 
				goto getout;

			channels = *((short*)(data+pos));			/* read chunk length */
			pos+=2;
			length -= 2;
			if ((channels != 1) && (channels != 2))
				goto getout;

			freq = *((int*)(data+pos));			/* read chunk length */
			pos+=4;
			length -= 4;

			pos+=6;
			length -= 6;

			bits = *((short*)(data+pos));			/* read chunk length */
			pos+=2;
			length -= 2;
			if ((bits != 8) && (bits != 16))
				goto getout;
			}
		else if (memcmp(buffer, "data", 4) == 0) {
			len = length / channels;

			if (bits == 16)
				len /= 2;

			spl = create_sample(bits, ((channels == 2) ? TRUE : FALSE), freq, len);

			if (spl) {
				if (bits == 8) {
					if(pos+length>size) {
						destroy_sample(spl);
						spl = NULL;
						}
					else {
						memcpy(spl->data, data+pos, length);
						pos+=length;
						}
					}
				else {
					for (i=0; i<len*channels; i++) {
						if(pos+2>size) {
							destroy_sample(spl);
							spl = NULL;
							break;
							}
						s = *((short*)(data+pos));			/* read chunk length */
						pos+=2;
						((signed short *)spl->data)[i] = (signed short)s^0x8000;
						}
					}

				length = 0;
				}
			}

		if(length>0)
			pos+=length;
		length=0;
		if(pos>=size)
			break;
		}

	getout:
	return spl;
}
