⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 waveloader.java

📁 Jake2是一个Java 3D游戏引擎.
💻 JAVA
字号:
/* * SND_MEM.java * Copyright (C) 2004 *  * $Id: WaveLoader.java,v 1.7 2006/01/01 15:07:30 cawe Exp $ *//*Copyright (C) 1997-2001 Id Software, Inc.This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of 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 ofMERCHANTABILITY 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 Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.*/package jake2.sound;import jake2.Defines;import jake2.qcommon.Com;import jake2.qcommon.FS;import java.io.ByteArrayInputStream;import java.io.IOException;import java.nio.ByteOrder;import javax.sound.sampled.*;/** * SND_MEM */public class WaveLoader {	/** 	 * The ResampleSfx can squeeze and stretch samples to a default sample rate. 	 * Since Joal and lwjgl sound drivers support this, we don't need it and the samples	 * can keep their original sample rate. Use this switch for reactivating resampling.	 */	private static boolean DONT_DO_A_RESAMPLING_FOR_JOAL_AND_LWJGL = true;		/**	 * This is the maximum sample length in bytes which has to be replaced by 	 * a configurable variable.	 */	private static int maxsamplebytes = 2048 * 1024;		/** 	 * Loads a sound from a wav file. 	 */	public static sfxcache_t LoadSound(sfx_t s) {		if (s.name.charAt(0) == '*')			return null;		// see if still in memory		sfxcache_t sc = s.cache;		if (sc != null)			return sc;		String name;		// load it in		if (s.truename != null)			name = s.truename;		else			name = s.name;		String namebuffer;		if (name.charAt(0) == '#')			namebuffer = name.substring(1);		else			namebuffer = "sound/" + name;		byte[] data = FS.LoadFile(namebuffer);		if (data == null) {			Com.DPrintf("Couldn't load " + namebuffer + "\n");			return null;		}				int size = data.length;		wavinfo_t info = GetWavinfo(s.name, data, size);		if (info.channels != 1)		{			Com.Printf(s.name + " is a stereo sample - ignoring\n");			return null;		}		float stepscale;		if (DONT_DO_A_RESAMPLING_FOR_JOAL_AND_LWJGL)			stepscale = 1; 		else			stepscale = (float)info.rate / S.getDefaultSampleRate();				int len = (int) (info.samples / stepscale);		len = len * info.width * info.channels;		// TODO: handle max sample bytes with a cvar		if (len >= maxsamplebytes)		{			Com.Printf(s.name + " is too long: " + len + " bytes?! ignoring.\n");			return null;		}		sc = s.cache = new sfxcache_t(len);		                 sc.length = info.samples;        sc.loopstart = info.loopstart;        sc.speed = info.rate;        sc.width = info.width;        sc.stereo = info.channels;		ResampleSfx(s, sc.speed, sc.width, data, info.dataofs);		data = null;		return sc;	}	/** 	 * Converts sample data with respect to the endianess and adjusts 	 * the sample rate of a loaded sample, see flag DONT_DO_A_RESAMPLING_FOR_JOAL_AND_LWJGL.	 */	public static void ResampleSfx (sfx_t sfx, int inrate, int inwidth, byte data[], int offset)	{        int             outcount;        int             srcsample;        int             i;        int             sample, samplefrac, fracstep;        sfxcache_t      sc;                sc = sfx.cache;                if (sc == null)        	return;        // again calculate the stretching factor.        // this is usually 0.5, 1, or 2                float stepscale;        if (DONT_DO_A_RESAMPLING_FOR_JOAL_AND_LWJGL)        	stepscale = 1;        else        	stepscale = (float)inrate / S.getDefaultSampleRate();          outcount = (int) (sc.length/stepscale);        sc.length = outcount;                if (sc.loopstart != -1)                sc.loopstart = (int) (sc.loopstart / stepscale);        // if resampled, sample has now the default sample rate        if (DONT_DO_A_RESAMPLING_FOR_JOAL_AND_LWJGL == false)        	sc.speed = S.getDefaultSampleRate();        sc.width = inwidth;        sc.stereo = 0;        samplefrac = 0;        fracstep = (int) (stepscale * 256);                for (i = 0; i < outcount; i++) {            srcsample = samplefrac >> 8;            samplefrac += fracstep;            if (inwidth == 2) {                sample = (data[offset + srcsample * 2] & 0xff)                        + (data[offset + srcsample * 2 + 1] << 8);            } else {                sample = ((data[offset + srcsample] & 0xff) - 128) << 8;            }            if (sc.width == 2) {                if (Defines.LITTLE_ENDIAN) {                    sc.data[i * 2] = (byte) (sample & 0xff);                    sc.data[i * 2 + 1] = (byte) ((sample >>> 8) & 0xff);                } else {                    sc.data[i * 2] = (byte) ((sample >>> 8) & 0xff);                    sc.data[i * 2 + 1] = (byte) (sample & 0xff);                }            } else {                sc.data[i] = (byte) (sample >> 8);            }        }    }	static byte[] data_b;	static int data_p;	static int iff_end;	static int last_chunk;	static int iff_data;	static int iff_chunk_len;	static short GetLittleShort() {		int val = 0;		val = data_b[data_p] & 0xFF;		data_p++;		val |= ((data_b[data_p] & 0xFF) << 8);		data_p++;		return (short)val;	}	static int GetLittleLong() {		int val = 0;		val = data_b[data_p] & 0xFF;		data_p++;		val |= ((data_b[data_p] & 0xFF) << 8);		data_p++;		val |= ((data_b[data_p] & 0xFF) << 16);		data_p++;		val |= ((data_b[data_p] & 0xFF) << 24);		data_p++;		return val;	}	static void FindNextChunk(String name) {		while (true) {			data_p = last_chunk;			if (data_p >= iff_end) { // didn't find the chunk				data_p = 0;				return;			}			data_p += 4;			iff_chunk_len = GetLittleLong();						if (iff_chunk_len < 0) {				data_p = 0;				return;			}			if (iff_chunk_len > 1024*1024) {				Com.Println(" Warning: FindNextChunk: length is past the 1 meg sanity limit");			}			data_p -= 8;			last_chunk = data_p + 8 + ((iff_chunk_len + 1) & ~1);			String s = new String(data_b, data_p, 4);			if (s.equals(name))				return;		}	}	static void FindChunk(String name) {		last_chunk = iff_data;		FindNextChunk(name);	}	/*	============	GetWavinfo	============	*/	static wavinfo_t GetWavinfo(String name, byte[] wav, int wavlength) {		wavinfo_t info = new wavinfo_t();		int i;		int format;		int samples;		if (wav == null)			return info;		iff_data = 0;		iff_end = wavlength;		data_b = wav;		// find "RIFF" chunk		FindChunk("RIFF");		String s = new String(data_b, data_p + 8, 4);		if (!s.equals("WAVE")) {			Com.Printf("Missing RIFF/WAVE chunks\n");			return info;		}		//	   get "fmt " chunk		iff_data = data_p + 12;		//	   DumpChunks ();		FindChunk("fmt ");		if (data_p == 0) {			Com.Printf("Missing fmt chunk\n");			return info;		}		data_p += 8;		format = GetLittleShort();		if (format != 1) {			Com.Printf("Microsoft PCM format only\n");			return info;		}		info.channels = GetLittleShort();		info.rate = GetLittleLong();		data_p += 4 + 2;		info.width = GetLittleShort() / 8;		//	   get cue chunk		FindChunk("cue ");		if (data_p != 0) {			data_p += 32;			info.loopstart = GetLittleLong();			//			Com_Printf("loopstart=%d\n", sfx->loopstart);			// if the next chunk is a LIST chunk, look for a cue length marker			FindNextChunk("LIST");			if (data_p != 0) {				if (data_b.length >= data_p + 32) {					s = new String(data_b, data_p + 28, 4);					if (s.equals("MARK")) { // this is not a proper parse, but											// it works with cooledit...						data_p += 24;						i = GetLittleLong(); // samples in loop						info.samples = info.loopstart + i;						//					Com_Printf("looped length: %i\n", i);					}				}			}		} else			info.loopstart = -1;		//	   find data chunk		FindChunk("data");		if (data_p == 0) {			Com.Printf("Missing data chunk\n");			return info;		}		data_p += 4;		samples = GetLittleLong() / info.width;		if (info.samples != 0) {			if (samples < info.samples)				Com.Error(Defines.ERR_DROP, "Sound " + name + " has a bad loop length");		} else {			info.samples = samples;			if (info.loopstart > 0) info.samples -= info.loopstart;		}				info.dataofs = data_p;		return info;	}	static class wavinfo_t {		int rate;		int width;		int channels;		int loopstart;		int samples;		int dataofs; // chunk starts this many bytes from file start	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -