예제 #1
0
파일: BnkFile.cs 프로젝트: STPKITT/OpenNFS1
        private void ReadSample(BinaryReader reader, int sampleIndex)
        {
            BnkSample sample = new BnkSample();
            reader.BaseStream.Position += 0x28;
            string id = new string(reader.ReadChars(4));
            sample.SampleRate = reader.ReadInt32();
            byte bytesPerSample = reader.ReadByte();
            sample.NbrChannels = reader.ReadByte();
            byte compression = reader.ReadByte();
            byte type = reader.ReadByte();

            int totalLength = reader.ReadInt32();
            sample.LoopStart = reader.ReadInt32();
            int loopLength = reader.ReadInt32();
            int dataOffset = reader.ReadInt32();
            int unk3 = reader.ReadInt32();

            // HACKS to avoid popping sounds.. Not sure why we need to do this.. maybe NFS finds values near
            // loop start/end which are the best match
            //if (_filename == "SUPRA_SW.bnk" && sampleIndex == 0)
            //	loopLength += 10;

            //Debug.WriteLine(String.Format("{0}: sampleRate:{5} bps: {1} loopStart: {2} loopLen: {3} totalLen: {4}, offset: {6}, channels: {7}",
            //	headerIndex, bytesPerSample, sample.LoopStart, loopLength, sample.NbrSamples, sample.SampleRate, dataOffset, sample.NbrChannels));

            reader.BaseStream.Position = dataOffset + (bytesPerSample * sample.NbrChannels * sample.LoopStart);
            sample.NbrSamples = loopLength == 0 ? totalLength : loopLength;
            byte[] soundData = reader.ReadBytes(bytesPerSample * sample.NbrChannels * sample.NbrSamples);

            if (bytesPerSample == 1)  //convert 8 bit signed PCM data to unsigned
            {
                for (int i = 0; i < soundData.Length; i++)
                    soundData[i] = (byte)(soundData[i] + 0x80);
            }

            if (ForceMono && sample.NbrChannels == 2)
            {
                MemoryStream ms = new MemoryStream();
                for (int i = 0; i < soundData.Length; i += bytesPerSample * 2)
                {
                    ms.Write(soundData, i, bytesPerSample);
                }
                soundData = ms.ToArray();
                sample.NbrChannels = 1;
            }

            /*
            if (sample.NbrChannels == 2)
            {
                MemoryStream ms = new MemoryStream();
                for (int i = 0; i < soundData.Length - 4; i += 4)
                {
                    ms.Write(soundData, i, 2);
                }
                soundData = ms.ToArray();
                sample.NbrChannels = 1;

                short[] sdata = new short[soundData.Length / 2];
                Buffer.BlockCopy(soundData, 0, sdata, 0, soundData.Length);
                soundData = new byte[sdata.Length * 2];
                Buffer.BlockCopy(sdata, 0, soundData, 0, loopLength * 2);
            }

            if (sample.NbrChannels == 3)
            {
                short lowestValue = short.MaxValue;
                int lowestValueSample = 0;
                short[] sdata = new short[soundData.Length / 2];
                Buffer.BlockCopy(soundData, 0, sdata, 0, soundData.Length);
                for (int i = loopLength; i < loopLength + 20; i++)
                {
                    if (Math.Abs(sdata[i]) < Math.Abs(lowestValue))
                    {
                        lowestValue = sdata[i];
                        lowestValueSample = i;
                    }
                    Debug.WriteLine(sdata[i]);
                }
                Debug.WriteLine("was " + loopLength + ", now " + lowestValueSample);
                loopLength = lowestValueSample;
                soundData = new byte[lowestValueSample * 2];
                Buffer.BlockCopy(sdata, 0, soundData, 0, lowestValueSample * 2);
            }*/

            sample.PCMData = soundData;
            Samples.Add(sample);

            //WavWriter.Write(String.Format("c:\\temp\\test{0}.wav", headerIndex),
            //	nbrSamples, channels, soundData);
        }
예제 #2
0
        private void ReadSample(BinaryReader reader, int sampleIndex)
        {
            BnkSample sample = new BnkSample();

            reader.BaseStream.Position += 0x28;
            string id = new string(reader.ReadChars(4));

            sample.SampleRate = reader.ReadInt32();
            byte bytesPerSample = reader.ReadByte();

            sample.NbrChannels = reader.ReadByte();
            byte compression = reader.ReadByte();
            byte type        = reader.ReadByte();

            int totalLength = reader.ReadInt32();

            sample.LoopStart = reader.ReadInt32();
            int loopLength = reader.ReadInt32();
            int dataOffset = reader.ReadInt32();
            int unk3       = reader.ReadInt32();

            // HACKS to avoid popping sounds.. Not sure why we need to do this.. maybe NFS finds values near
            // loop start/end which are the best match
            //if (_filename == "SUPRA_SW.bnk" && sampleIndex == 0)
            //	loopLength += 10;

            //Debug.WriteLine(String.Format("{0}: sampleRate:{5} bps: {1} loopStart: {2} loopLen: {3} totalLen: {4}, offset: {6}, channels: {7}",
            //	headerIndex, bytesPerSample, sample.LoopStart, loopLength, sample.NbrSamples, sample.SampleRate, dataOffset, sample.NbrChannels));

            reader.BaseStream.Position = dataOffset + (bytesPerSample * sample.NbrChannels * sample.LoopStart);
            sample.NbrSamples          = loopLength == 0 ? totalLength : loopLength;
            byte[] soundData = reader.ReadBytes(bytesPerSample * sample.NbrChannels * sample.NbrSamples);

            if (bytesPerSample == 1)              //convert 8 bit signed PCM data to unsigned
            {
                for (int i = 0; i < soundData.Length; i++)
                {
                    soundData[i] = (byte)(soundData[i] + 0x80);
                }
            }

            if (ForceMono && sample.NbrChannels == 2)
            {
                MemoryStream ms = new MemoryStream();
                for (int i = 0; i < soundData.Length; i += bytesPerSample * 2)
                {
                    ms.Write(soundData, i, bytesPerSample);
                }
                soundData          = ms.ToArray();
                sample.NbrChannels = 1;
            }

            /*
             * if (sample.NbrChannels == 2)
             * {
             *      MemoryStream ms = new MemoryStream();
             *      for (int i = 0; i < soundData.Length - 4; i += 4)
             *      {
             *              ms.Write(soundData, i, 2);
             *      }
             *      soundData = ms.ToArray();
             *      sample.NbrChannels = 1;
             *
             *      short[] sdata = new short[soundData.Length / 2];
             *      Buffer.BlockCopy(soundData, 0, sdata, 0, soundData.Length);
             *      soundData = new byte[sdata.Length * 2];
             *      Buffer.BlockCopy(sdata, 0, soundData, 0, loopLength * 2);
             * }
             *
             * if (sample.NbrChannels == 3)
             * {
             *      short lowestValue = short.MaxValue;
             *      int lowestValueSample = 0;
             *      short[] sdata = new short[soundData.Length / 2];
             *      Buffer.BlockCopy(soundData, 0, sdata, 0, soundData.Length);
             *      for (int i = loopLength; i < loopLength + 20; i++)
             *      {
             *              if (Math.Abs(sdata[i]) < Math.Abs(lowestValue))
             *              {
             *                      lowestValue = sdata[i];
             *                      lowestValueSample = i;
             *              }
             *              Debug.WriteLine(sdata[i]);
             *      }
             *      Debug.WriteLine("was " + loopLength + ", now " + lowestValueSample);
             *      loopLength = lowestValueSample;
             *      soundData = new byte[lowestValueSample * 2];
             *      Buffer.BlockCopy(sdata, 0, soundData, 0, lowestValueSample * 2);
             * }*/

            sample.PCMData = soundData;
            Samples.Add(sample);

            //WavWriter.Write(String.Format("c:\\temp\\test{0}.wav", headerIndex),
            //	nbrSamples, channels, soundData);
        }