// S_LoadSound private static sfxcache_t LoadSound(sfx_t s) { // see if still in memory sfxcache_t sc = (sfxcache_t)Cache.Check(s.cache); if (sc != null) { return(sc); } // load it in string namebuffer = "sound/" + s.name; byte[] data = common.LoadFile(namebuffer); if (data == null) { Con.Print("Couldn't load {0}\n", namebuffer); return(null); } wavinfo_t info = GetWavInfo(s.name, data); if (info.channels != 1) { Con.Print("{0} is a stereo sample\n", s.name); return(null); } float stepscale = info.rate / (float)_shm.speed; int len = (int)(info.samples / stepscale); len *= info.width * info.channels; s.cache = Cache.Alloc(len, s.name); if (s.cache == null) { return(null); } sc = new sfxcache_t(); sc.length = info.samples; sc.loopstart = info.loopstart; sc.speed = info.rate; sc.width = info.width; sc.stereo = info.channels; s.cache.data = sc; ResampleSfx(s, sc.speed, sc.width, new ByteArraySegment(data, info.dataofs)); return(sc); }
// GetWavinfo private static wavinfo_t GetWavInfo(string name, byte[] wav) { wavinfo_t info = new wavinfo_t(); if (wav == null) { return(info); } // debug //using (FileStream fs = new FileStream(Path.GetFileName(name), FileMode.Create, FileAccess.Write, FileShare.Read)) //{ // fs.Write(wav, 0, wav.Length); //} WavHelper helper = new WavHelper(wav); int offset = 0; // find "RIFF" chunk int riff = helper.FindChunk("RIFF", offset); if (riff == -1) { Con.Print("Missing RIFF chunk\n"); return(info); } string wave = Encoding.ASCII.GetString(wav, offset + 8, 4); if (wave != "WAVE") { Con.Print("RIFF chunk is not WAVE\n"); return(info); } // get "fmt " chunk offset += 12; //iff_data = data_p + 12; int fmt = helper.FindChunk("fmt ", offset); if (fmt == -1) { Con.Print("Missing fmt chunk\n"); return(info); } int format = helper.GetLittleShort(fmt + 8); if (format != 1) { Con.Print("Microsoft PCM format only\n"); return(info); } info.channels = helper.GetLittleShort(fmt + 10); info.rate = helper.GetLittleLong(fmt + 12); info.width = helper.GetLittleShort(fmt + 16 + 4 + 2) / 8; // get cue chunk int cue = helper.FindChunk("cue ", offset); if (cue != -1) { info.loopstart = helper.GetLittleLong(cue + 32); // if the next chunk is a LIST chunk, look for a cue length marker int list = helper.FindChunk("LIST", cue); if (list != -1) { string mark = Encoding.ASCII.GetString(wav, list + 28, 4); if (mark == "mark") { // this is not a proper parse, but it works with cooledit... int i = helper.GetLittleLong(list + 24); // samples in loop info.samples = info.loopstart + i; } } } else { info.loopstart = -1; } // find data chunk int data = helper.FindChunk("data", offset); if (data == -1) { Con.Print("Missing data chunk\n"); return(info); } int samples = helper.GetLittleLong(data + 4) / info.width; if (info.samples > 0) { if (samples < info.samples) { Sys.Error("Sound {0} has a bad loop length", name); } } else { info.samples = samples; } info.dataofs = data + 8; return(info); }