예제 #1
0
        public static void CreateSRS(SortedList <int, TrackData> tracks, FileData file, FileInfo inFile, FileInfo srsFile, bool bigFile)
        {
            using (FileStream fsOut = srsFile.Create())
                using (RiffReader rdr = new RiffReader(inFile.FullName, RiffReadMode.AVI))
                {
                    while (rdr.Read())
                    {
                        fsOut.Write(rdr.Chunk.RawHeader, 0, rdr.Chunk.RawHeader.Length);

                        if (rdr.ChunkType == RiffChunkType.List)
                        {
                            // in store mode, create and write our custom chunks as the first child of LIST movi
                            // we put them after the avi headers so mediainfo can still read them from the SRS
                            if (rdr.List.ListType == "LIST" && rdr.List.FourCC == "movi")
                            {
                                byte[] fileChunk = file.SerializeAsRiff();
                                fsOut.Write(fileChunk, 0, fileChunk.Length);
                                if (fileChunk.Length % 2 == 1)
                                {
                                    fsOut.WriteByte(0);
                                }

                                foreach (TrackData track in tracks.Values)
                                {
                                    if (bigFile)
                                    {
                                        track.Flags |= TrackData.TrackDataFlags.BigFile;
                                    }
                                    byte[] trackChunk = track.SerializeAsRiff();
                                    fsOut.Write(trackChunk, 0, trackChunk.Length);
                                    if (trackChunk.Length % 2 == 1)
                                    {
                                        fsOut.WriteByte(0);
                                    }
                                }
                            }

                            rdr.MoveToChild();
                        }
                        else
                        {
                            if (rdr.ChunkType == RiffChunkType.Movi)
                            {
                                rdr.SkipContents();                         // don't copy stream data
                            }
                            else
                            {
                                fsOut.Write(rdr.ReadContents(), 0, (int)rdr.Chunk.Length);                         // do copy everything else
                            }
                            if (rdr.HasPad)
                            {
                                fsOut.WriteByte(rdr.PadByte);
                            }
                        }
                    }
                }
        }
예제 #2
0
        public static DlsCollection Read(Stream stream)
        {
            using (var reader = new RiffReader(stream))
            {
                var collectionVersion = default(Version);
                var instruments       = new List <DlsInstrument>();
                var wavePool          = new List <DlsWaveFile>();
                var info = new DlsInfo();
                var id   = default(Guid?);

                foreach (var dlsSubchunk in reader.ReadRiff("DLS ").ReadList())
                {
                    switch (dlsSubchunk.Name)
                    {
                    case "vers":
                        var minor    = dlsSubchunk.ReadUInt16();
                        var major    = dlsSubchunk.ReadUInt16();
                        var revision = dlsSubchunk.ReadUInt16();
                        var build    = dlsSubchunk.ReadUInt16();
                        collectionVersion = new Version(major, minor, build, revision);
                        break;

                    case "dlid":
                        id = ReadDlsId(dlsSubchunk);
                        break;

                    case "lins":
                        instruments.AddRange(
                            from lrgnSubchunk in dlsSubchunk.ReadList()
                            where lrgnSubchunk.Name == "ins "
                            let instrument = ReadDlsInstrument(lrgnSubchunk)
                                             where instrument != null
                                             select instrument.Value);
                        break;

                    case "wvpl":
                        wavePool.AddRange(
                            from wvplSubchunk in dlsSubchunk.ReadList()
                            where wvplSubchunk.Name == "wave"
                            let waveFile = ReadDlsWaveFile(wvplSubchunk)
                                           where waveFile != null
                                           select waveFile.Value);
                        break;

                    case "INFO":
                        info = ReadDlsInfo(dlsSubchunk);
                        break;
                    }
                }

                return(new DlsCollection(id, collectionVersion, info, instruments, wavePool));
            }
        }
예제 #3
0
        /// <summary>
        /// Read the RIFF.
        /// </summary>
        /// <param name="r">The reader.</param>
        public override void Read(FileReader r)
        {
            //Init.
            using (RiffReader rr = new RiffReader(r.BaseStream)) {
                //Format.
                rr.OpenChunk(rr.Chunks.Where(x => x.Magic.Equals("fmt ")).FirstOrDefault());
                if (rr.ReadUInt16() != 1)
                {
                    throw new Exception("Unexpected standard WAV data format.");
                }
                int numChannels = rr.ReadUInt16();
                SampleRate = rr.ReadUInt32();
                rr.ReadUInt32(); //Byte rate.
                rr.ReadUInt16(); //Blocks.
                ushort bitsPerSample = rr.ReadUInt16();
                LoopStart = 0;
                LoopEnd   = 0;
                Loops     = false;
                if (bitsPerSample != 8 && bitsPerSample != 16)
                {
                    throw new Exception("This tool only accepts 8-bit or 16-bit WAV files.");
                }

                //Sample.
                var smpl = rr.Chunks.Where(x => x.Magic.Equals("smpl")).FirstOrDefault();
                if (smpl != null)
                {
                    rr.OpenChunk(smpl);
                    rr.ReadUInt32s(7);
                    Loops = rr.ReadUInt32() > 0;
                    if (Loops)
                    {
                        rr.ReadUInt32s(3);
                        LoopStart = r.ReadUInt32(); //(uint)(r.ReadUInt32() / (bitsPerSample / 8));
                        LoopEnd   = r.ReadUInt32(); //(uint)(r.ReadUInt32() / (bitsPerSample / 8));
                    }
                }

                //Data.
                rr.OpenChunk(rr.Chunks.Where(x => x.Magic.Equals("data")).FirstOrDefault());
                uint dataSize  = rr.Chunks.Where(x => x.Magic.Equals("data")).FirstOrDefault().Size;
                uint numBlocks = (uint)(dataSize / numChannels / (bitsPerSample / 8));
                r.Position = rr.Position;
                Audio.Read(r, bitsPerSample == 16 ? typeof(PCM16) : typeof(PCM8), numChannels, numBlocks, (uint)bitsPerSample / 8, 1, (uint)bitsPerSample / 8, 1, 0);
                Audio.ChangeBlockSize(-1);
            }
        }
예제 #4
0
        public override Buffer CreateResource(ResourceManager resourceManager)
        {
            var buffer = base.CreateResource(resourceManager);

            using (var reader = new BinaryReader(OpenResource(FileName)))
            {
                RiffHeader header;
                RiffReader.ReadHeader(reader, out header);

                var format     = header.GetFormat();
                var sampleData = new byte[header.DataLength];
                var bytesRead  = reader.Read(sampleData, 0, sampleData.Length);
                if (bytesRead < sampleData.Length)
                {
                    throw new InvalidOperationException("Unable to read audio data. Sound WAV file may be corrupted or truncated.");
                }

                AL.BufferData(buffer.Id, format, sampleData, sampleData.Length, (int)header.SampleRate);
            }

            return(buffer);
        }
예제 #5
0
 public static void LoadSRS(SortedList <int, TrackData> tracks, ref FileData file, FileInfo inFile)
 {
     using (RiffReader rdr = new RiffReader(inFile.FullName, RiffReadMode.SRS))
     {
         bool done = false;
         while (!done && rdr.Read())
         {
             if (rdr.ChunkType == RiffChunkType.List)
             {
                 rdr.MoveToChild();
             }
             else
             {
                 if (rdr.Chunk.FourCC == "SRSF")                         // resample file
                 {
                     byte[] buff = rdr.ReadContents();
                     file = new FileData(buff);
                 }
                 else if (rdr.Chunk.FourCC == "SRST")                         // resample track
                 {
                     byte[]    buff  = rdr.ReadContents();
                     TrackData track = new TrackData(buff);
                     tracks.Add(track.TrackNumber, track);
                 }
                 else if (rdr.ChunkType == RiffChunkType.Movi)
                 {
                     // if we get here in load mode, we have already got what we need, so bail out
                     done = true;
                     continue;
                 }
                 else
                 {
                     rdr.SkipContents();
                 }
             }
         }
     }
 }
예제 #6
0
        private void bgWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            const int        COPY_LEN = 50 * 1024;
            BackgroundWorker worker   = sender as BackgroundWorker;

            string[] files = (string[])e.Argument;

            try {
                using (RiffReader rr = new RiffReader(files[0]))
                    using (RiffWriter rw = new RiffWriter(files[1])) {
                        // 読み取りファイル解析
                        bool b = rr.Parse();
                        if (!b)
                        {
                            e.Result = -2;
                            return;
                        }

                        WaveFormatEx wf = rr.WaveFormat;

                        // 拡張ヘッダーを無効化できる条件
                        if (wf.Channels <= 2 && wf.Extensible && wf.BitsPerSample != 32)
                        {
                            wf.Extensible = false;
                            wf.FormatTag  = WaveFormatTag.PCM;
                        }
                        // ヘッダーの書き出し
                        b = rw.WriteHeader(wf);
                        if (!b)
                        {
                            e.Result = -1;
                            return;
                        }

                        // ループ回数を計算。進捗にも使う
                        long max = rr.Length / COPY_LEN;
                        if ((rr.Length % COPY_LEN) > 0)
                        {
                            max++;
                        }

                        for (long i = 0; i < max; i++)
                        {
                            byte[] arr = rr.Read8(COPY_LEN);
                            if (!rw.WriteStream8(arr))
                            {
                                e.Result = -1;
                                return;
                            }

                            int percentage = (int)((i + 1) * 100 / max);
                            worker.ReportProgress(percentage);
                        }

                        if (!rw.WriteFinalize())
                        {
                            return;
                        }
                    }
            } catch {
                // エラー
                e.Result = -3;
                return;
            }
            e.Result = 0;
        }
예제 #7
0
        public static FileData RebuildSample(FileData file, SortedList <int, TrackData> tracks, FileInfo srsFile, DirectoryInfo outDir)
        {
            uint crc = Crc32.StartValue;

            using (RiffReader rdr = new RiffReader(srsFile.FullName, RiffReadMode.SRS))
                using (FileStream fsOut = new FileStream(Path.Combine(outDir.FullName, file.Name), FileMode.Create))
                {
                    int blockcount = 0;
                    while (rdr.Read())
                    {
                        // skip over our custom chunks in rebuild mode (only read it in load mode)
                        if (rdr.Chunk.FourCC == "SRSF" || rdr.Chunk.FourCC == "SRST")
                        {
                            rdr.SkipContents();
                            continue;
                        }

                        fsOut.Write(rdr.Chunk.RawHeader, 0, rdr.Chunk.RawHeader.Length);
                        crc = Crc32.GetCrc(crc, rdr.Chunk.RawHeader);

                        if (rdr.ChunkType == RiffChunkType.List)
                        {
                            rdr.MoveToChild();
                        }
                        else
                        {
                            if (rdr.ChunkType == RiffChunkType.Movi)
                            {
                                if (++blockcount % 15 == 0)
                                {
                                    Console.Write("\b{0}", Program.spinners[blockcount % Program.spinners.Length]);
                                }

                                TrackData track = tracks[rdr.MoviChunk.StreamNumber];
                                byte[]    buff  = new byte[rdr.MoviChunk.Length];
                                track.TrackFile.Read(buff, 0, buff.Length);
                                fsOut.Write(buff, 0, buff.Length);
                                crc = Crc32.GetCrc(crc, buff);
                                rdr.SkipContents();
                            }
                            else
                            {
                                byte[] buff = rdr.ReadContents();
                                fsOut.Write(buff, 0, buff.Length);
                                crc = Crc32.GetCrc(crc, buff);
                            }

                            if (rdr.HasPad)
                            {
                                fsOut.WriteByte(rdr.PadByte);
                                crc = Crc32.GetCrc(crc, new byte[] { rdr.PadByte });
                            }
                        }
                    }
                }
            Console.Write('\b');

            FileData newFile = new FileData(Path.Combine(outDir.FullName, file.Name));

            newFile.Crc32 = ~crc;

            return(newFile);
        }
예제 #8
0
        public static void ExtractSampleStreams(SortedList <int, TrackData> tracks, FileData file, FileInfo inFile, DirectoryInfo outDir)
        {
            Stream fs;

            if (RarFileNameComparer.IsRarFile(inFile.Name))
            {
                fs = new RarStream(inFile.FullName);
            }
            else
            {
                fs = inFile.OpenRead();
            }

            using (RiffReader rdr = new RiffReader(fs, RiffReadMode.AVI))
            {
                long startOffset = long.MaxValue;
                foreach (TrackData track in tracks.Values)
                {
                    if (track.MatchOffset > 0)
                    {
                        startOffset = Math.Min(track.MatchOffset, startOffset);
                    }
                }

                int  blockcount = 0;
                bool done       = false;
                while (rdr.Read() && !done)
                {
                    if (rdr.ChunkType == RiffChunkType.List)
                    {
                        rdr.MoveToChild();
                    }
                    else                     // normal chunk
                    {
                        if (rdr.ChunkType == RiffChunkType.Movi)
                        {
                            if (++blockcount % 15 == 0)
                            {
                                Console.Write("\b{0}", Program.spinners[blockcount % Program.spinners.Length]);
                            }

                            if (!tracks.ContainsKey(rdr.MoviChunk.StreamNumber))
                            {
                                tracks.Add(rdr.MoviChunk.StreamNumber, new TrackData());
                            }

                            TrackData track = tracks[rdr.MoviChunk.StreamNumber];

                            if (rdr.MoviChunk.ChunkStartPos + rdr.MoviChunk.RawHeader.Length + rdr.MoviChunk.Length > track.MatchOffset)
                            {
                                if (track.TrackFile == null)
                                {
                                    track.TrackFile = new FileStream(Path.Combine(outDir.FullName, inFile.Name + "." + track.TrackNumber.ToString("d3")), FileMode.Create, FileAccess.ReadWrite, FileShare.Read, 0x10000, FileOptions.DeleteOnClose);
                                }

                                if (track.TrackFile.Position < track.DataLength)
                                {
                                    if (rdr.MoviChunk.ChunkStartPos + rdr.MoviChunk.RawHeader.Length >= track.MatchOffset)
                                    {
                                        track.TrackFile.Write(rdr.ReadContents(), 0, (int)rdr.MoviChunk.Length);
                                    }
                                    else
                                    {
                                        int chunkOffset = (int)(track.MatchOffset - (rdr.MoviChunk.ChunkStartPos + rdr.MoviChunk.RawHeader.Length));
                                        track.TrackFile.Write(rdr.ReadContents(), chunkOffset, (int)rdr.MoviChunk.Length - chunkOffset);
                                    }
                                }

                                bool tracksDone = true;
                                foreach (TrackData t in tracks.Values)
                                {
                                    if (t.TrackFile == null || t.TrackFile.Length < t.DataLength)
                                    {
                                        tracksDone = false;
                                        break;
                                    }
                                }
                                done = tracksDone;
                            }

                            rdr.SkipContents();
                        }
                        else
                        {
                            rdr.SkipContents();
                        }
                    }
                }
            }

            Console.Write('\b');
        }
예제 #9
0
        public static void FindSampleStreams(SortedList <int, TrackData> tracks, FileInfo inFile)
        {
            Stream fs;

            if (RarFileNameComparer.IsRarFile(inFile.Name))
            {
                fs = new RarStream(inFile.FullName);
            }
            else
            {
                fs = inFile.OpenRead();
            }

            using (RiffReader rdr = new RiffReader(fs, RiffReadMode.AVI))
            {
                int  blockcount = 0;
                bool done       = false;
                while (rdr.Read() && !done)
                {
                    if (rdr.ChunkType == RiffChunkType.List)
                    {
                        rdr.MoveToChild();
                    }
                    else                     // normal chunk
                    {
                        if (rdr.ChunkType == RiffChunkType.Movi)
                        {
                            if (++blockcount % 15 == 0)
                            {
                                Console.Write("\b{0}", Program.spinners[blockcount % Program.spinners.Length]);
                            }

                            int trackno = rdr.MoviChunk.StreamNumber;
                            if (!tracks.ContainsKey(trackno))
                            {
                                tracks.Add(trackno, new TrackData());
                            }

                            TrackData track = tracks[trackno];
                            track.TrackNumber = (byte)trackno;

                            if (track.MatchOffset == 0 || track.CheckBytes.Length < track.SignatureBytes.Length)
                            {
                                // it's possible the sample didn't require or contain data for all tracks in the main file
                                //  if that happens, we obviously don't want to try to match the data
                                if (track.SignatureBytes != null)
                                {
                                    if (track.CheckBytes != null && track.CheckBytes.Length < track.SignatureBytes.Length)
                                    {
                                        byte[] checkBytes = new byte[Math.Min(track.SignatureBytes.Length, rdr.MoviChunk.Length + track.CheckBytes.Length)];
                                        track.CheckBytes.CopyTo(checkBytes, 0);
                                        Buffer.BlockCopy(rdr.ReadContents(), 0, checkBytes, track.CheckBytes.Length, checkBytes.Length - track.CheckBytes.Length);

                                        if (ByteArrayComparer.AreEqual(track.SignatureBytes, checkBytes, checkBytes.Length))
                                        {
                                            track.CheckBytes = checkBytes;
                                        }
                                        else
                                        {
                                            // it was only a partial match.  start over
                                            track.CheckBytes  = null;
                                            track.MatchOffset = 0;
                                            track.MatchLength = 0;
                                        }
                                    }

                                    // this is a bit weird, but if we had a false positive match going and discovered it above, we check this frame again
                                    //  to see if it's the start of a new match (probably will never happen with AVI, but it does in MKV, so just in case...)
                                    if (track.CheckBytes == null)
                                    {
                                        byte[] chunkBytes = rdr.ReadContents();

                                        byte searchByte = track.SignatureBytes[0];
                                        int  foundPos   = -1;
                                        while ((foundPos = Array.IndexOf <byte>(chunkBytes, searchByte, foundPos + 1)) > -1)
                                        {
                                            byte[] checkBytes = new byte[Math.Min(track.SignatureBytes.Length, chunkBytes.Length - foundPos)];
                                            Buffer.BlockCopy(chunkBytes, foundPos, checkBytes, 0, checkBytes.Length);

                                            if (ByteArrayComparer.AreEqual(track.SignatureBytes, checkBytes, checkBytes.Length))
                                            {
                                                track.CheckBytes  = checkBytes;
                                                track.MatchOffset = rdr.Chunk.ChunkStartPos + rdr.Chunk.RawHeader.Length + foundPos;
                                                track.MatchLength = Math.Min(track.DataLength, chunkBytes.Length - foundPos);
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        track.MatchLength += Math.Min(track.DataLength - track.MatchLength, rdr.MoviChunk.Length);
                                    }
                                }
                            }
                            else if (track.MatchLength < track.DataLength)
                            {
                                track.MatchLength += Math.Min(track.DataLength - track.MatchLength, rdr.MoviChunk.Length);

                                bool tracksDone = true;
                                foreach (TrackData t in tracks.Values)
                                {
                                    if (t.MatchLength < t.DataLength)
                                    {
                                        tracksDone = false;
                                        break;
                                    }
                                }
                                done = tracksDone;
                            }

                            rdr.SkipContents();
                        }
                        else
                        {
                            rdr.SkipContents();
                        }
                    }
                }
            }

            Console.Write('\b');
        }
예제 #10
0
        public static int ProfileSample(FileData file, SortedList <int, TrackData> tracks)
        {
            long otherLength = 0;
            int  blockcount  = 0;

            file.Crc32 = Crc32.StartValue;
            using (RiffReader rdr = new RiffReader(file.Name, RiffReadMode.Sample))
            {
                while (rdr.Read())
                {
                    otherLength += rdr.Chunk.RawHeader.Length;
                    file.Crc32   = Crc32.GetCrc(file.Crc32, rdr.Chunk.RawHeader);

                    if (rdr.ChunkType == RiffChunkType.List)
                    {
                        if (rdr.List.ListType == "RIFF" && rdr.List.ChunkStartPos + rdr.List.RawHeader.Length + rdr.List.Length > file.Size)
                        {
                            Program.ReportError(string.Format("\nWarning: File size does not appear to be correct!\n\t Expected at least: {0:n0}\n\t Found            : {1:n0}\n", rdr.List.ChunkStartPos + rdr.List.RawHeader.Length + rdr.List.Length, file.Size));
                        }

                        rdr.MoveToChild();
                    }
                    else                                         // normal chunk
                    {
                        if (rdr.ChunkType == RiffChunkType.Movi) // chunk containing stream data (our main focus)
                        {
                            if (++blockcount % 15 == 0)
                            {
                                Console.Write("\b{0}", Program.spinners[blockcount % Program.spinners.Length]);
                            }

                            int trackno = rdr.MoviChunk.StreamNumber;
                            if (!tracks.ContainsKey(trackno))
                            {
                                tracks.Add(trackno, new TrackData());
                            }

                            TrackData track = tracks[trackno];
                            track.TrackNumber = (byte)trackno;
                            track.DataLength += rdr.MoviChunk.Length;

                            byte[] moviData = rdr.ReadContents();
                            file.Crc32 = Crc32.GetCrc(file.Crc32, moviData);

                            // in profile mode, we want to build track signatures
                            if (track.SignatureBytes == null || track.SignatureBytes.Length < Program.sigSize)
                            {
                                if (track.SignatureBytes != null)
                                {
                                    byte[] sig = new byte[Math.Min(Program.sigSize, track.SignatureBytes.Length + rdr.MoviChunk.Length)];
                                    track.SignatureBytes.CopyTo(sig, 0);
                                    Buffer.BlockCopy(moviData, 0, sig, track.SignatureBytes.Length, sig.Length - track.SignatureBytes.Length);
                                    track.SignatureBytes = sig;
                                }
                                else
                                {
                                    track.SignatureBytes = new byte[Math.Min(Program.sigSize, rdr.MoviChunk.Length)];
                                    Buffer.BlockCopy(moviData, 0, track.SignatureBytes, 0, track.SignatureBytes.Length);
                                }
                            }
                        }
                        else
                        {
                            otherLength += rdr.Chunk.Length;
                            file.Crc32   = Crc32.GetCrc(file.Crc32, rdr.ReadContents());
                        }

                        if (rdr.HasPad)
                        {
                            otherLength++;
                            file.Crc32 = Crc32.GetCrc(file.Crc32, new byte[] { rdr.PadByte });
                        }
                    }
                }
            }

            Console.Write('\b');

            file.Crc32 = ~file.Crc32;
            long totalSize = otherLength;

            Console.WriteLine("File Details:   Size           CRC");
            Console.WriteLine("                -------------  --------");
            Console.WriteLine("                {0,13:n0}  {1:X8}\n", file.Size, file.Crc32);

            Console.WriteLine();
            Console.WriteLine("Stream Details:  Stream  Length");
            Console.WriteLine("                 ------  -------------");
            foreach (TrackData track in tracks.Values)
            {
                Console.WriteLine("                 {0,6:n0}  {1,13:n0}", track.TrackNumber, track.DataLength);
                totalSize += track.DataLength;
            }

            Console.WriteLine();
            Console.WriteLine("Parse Details:   Metadata     Stream Data    Total");
            Console.WriteLine("                 -----------  -------------  -------------");
            Console.WriteLine("                 {0,11:n0}  {1,13:n0}  {2,13:n0}\n", otherLength, totalSize - otherLength, totalSize);

            if (file.Size != totalSize)
            {
                Program.ReportError("\nError: Parsed size does not equal file size.\n       The sample is likely corrupted or incomplete.\n");
                return(2);
            }

            return(0);
        }
예제 #11
0
        private bool CheckFileType()
        {
            try {
                using (RiffReader f1 = new RiffReader(textBoxFile1.Text))
                    using (RiffReader f2 = new RiffReader(textBoxFile2.Text)) {
                        bool b1 = f1.Parse();
                        bool b2 = f2.Parse();

                        if (b1 && b2)
                        {
                            if (f1.WaveFormat.Channels != f2.WaveFormat.Channels)
                            {
                                MessageBox.Show("チャンネル数が異なります。比較を中断します。", "情報", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                return(false);
                            }
                            else if (f1.WaveFormat.FormatTag != f2.WaveFormat.FormatTag)
                            {
                                MessageBox.Show("フォーマットが異なります。比較を中断します。", "情報", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                return(false);
                            }
                            else if (f1.WaveFormat.SamplesPerSecond != f2.WaveFormat.SamplesPerSecond)
                            {
                                MessageBox.Show("サンプリングレートが異なります。比較を中断します。", "情報", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                return(false);
                            }
                            else if (f1.WaveFormat.BitsPerSample != f2.WaveFormat.BitsPerSample)
                            {
                                MessageBox.Show("量子化ビット数が異なります。比較を中断します。", "情報", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                return(false);
                            }
                            else
                            {
                                m_Comp.type = CompType.Wavs;
                            }
                        }
                        else if (!b1 && !b2)
                        {
                            MessageBox.Show("どちらもWAVファイルではありません。先頭からバイト単位で比較します。", "情報", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            m_Comp.type = CompType.Raws;
                        }
                        else
                        {
#if true
                            m_Comp.type = CompType.Raws;
                            if (b1)
                            {
                                MessageBox.Show("ファイル2はWAVファイルではありません。先頭からバイト単位で比較します。", "情報", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                m_Comp.rawFile = 1;
                            }
                            else
                            {
                                MessageBox.Show("ファイル1はWAVファイルではありません。先頭からバイト単位で比較します。", "情報", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                m_Comp.rawFile = 0;
                            }
#else
                            m_Comp.type = CompType.RawWav;
                            if (b1)
                            {
                                MessageBox.Show("ファイル2はWAVファイルではありません。Rawストリームとみなして比較します。", "情報", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                m_Comp.rawFile = 1;
                            }
                            else
                            {
                                MessageBox.Show("ファイル1はWAVファイルではありません。Rawストリームとみなして比較します。", "情報", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                m_Comp.rawFile = 0;
                            }
#endif
                        }
                        return(true);
                    }
            } catch (Exception) {
                MessageBox.Show("ファイルがオープンできません。比較を中断します。", "情報", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return(false);
            }
        }
예제 #12
0
        private int CompareWav(BackgroundWorker worker, string[] files, CompareInfo ci, DiffWriter sw)
        {
            CompareCore cc = new CompareCore(sw);

            cc.HexOut = ci.setting.hexOut;
            int ret = 0;

            try {
                using (RiffReader rr1 = new RiffReader(files[0]))
                    using (RiffReader rr2 = new RiffReader(files[1])) {
                        if (!rr1.Parse())
                        {
                            return(-1);
                        }
                        if (!rr2.Parse())
                        {
                            return(-1);
                        }
                        if (!ci.setting.streamOrigin)
                        {
                            cc.Offset = rr1.StreamOffset;
                        }

                        // 読み込み終端。単位に注意
                        long limit = 0;
                        if (ci.setting.sampleOrder)
                        {
                            limit = (rr1.Samples > rr2.Samples) ? rr2.Samples : rr1.Samples;
                        }
                        else
                        {
                            limit = (rr1.Length > rr2.Length) ? rr2.Length : rr1.Length;
                        }
                        // 現在処理位置。単位に注意
                        long read         = 0;
                        int  prevProgress = 0;

                        int BLOCK_LENGTH = 2 * 1024 * 1024;
                        while (read < limit)
                        {
                            int size = BLOCK_LENGTH;
                            if (read + BLOCK_LENGTH > limit)
                            {
                                size = (int)(limit - read);
                            }

                            if (ci.setting.sampleOrder)
                            {
                                int q = rr1.WaveFormat.BitsPerSample / 8;

                                // まとめて読んで比較
                                if (q == 1)
                                {
                                    byte[] ba1 = rr1.Read8(size);
                                    byte[] ba2 = rr2.Read8(size);
                                    if (cc.CompareLoop(ba1, ba2, read))
                                    {
                                        ret = 1;
                                    }
                                }
                                else if (q == 2)
                                {
                                    short[] sa1 = rr1.Read16(size);
                                    short[] sa2 = rr2.Read16(size);
                                    if (cc.CompareLoop(sa1, sa2, read * q))
                                    {
                                        ret = 1;
                                    }
                                }
                                else if (q == 3)
                                {
                                    int[] sa1 = rr1.Read24(size);
                                    int[] sa2 = rr2.Read24(size);
                                    if (cc.CompareLoop(sa1, sa2, read * q, q))
                                    {
                                        ret = 1;
                                    }
                                }
                                else if (q == 4)
                                {
                                    if (rr1.WaveFormat.FormatTag == WaveFormatTag.IEEE_FLOAT)
                                    {
                                        float[] sa1 = rr1.Read32F(size);
                                        float[] sa2 = rr2.Read32F(size);
                                        if (cc.CompareLoop(sa1, sa2, read * q))
                                        {
                                            ret = 1;
                                        }
                                    }
                                    else
                                    {
                                        int[] sa1 = rr1.Read32(size);
                                        int[] sa2 = rr2.Read32(size);
                                        if (cc.CompareLoop(sa1, sa2, read * q, q))
                                        {
                                            ret = 1;
                                        }
                                    }
                                }
                                else
                                {
                                    return(-1);
                                }
                            }
                            else
                            {
                                // まとめて読んで比較
                                byte[] ba1 = rr1.Read8(size);
                                byte[] ba2 = rr2.Read8(size);
                                if (cc.CompareLoop(ba1, ba2, read))
                                {
                                    ret = 1;
                                }
                            }

                            read += size;

                            // 進捗を通知
                            int progress = (int)(read * 100 / limit);
                            if (progress > prevProgress)
                            {
                                prevProgress = progress;
                                worker.ReportProgress(progress);
                            }
                        }
                    }
            } catch {
                return(-1);
            }
            if (sw != null && ret == 1)
            {
                if (cc.DiffType)
                {
                    sw.PrintResult(cc.Count, cc.Max);
                }
                else
                {
                    sw.PrintResult(cc.Count, cc.fMax);
                }
            }
            return(ret);
        }
예제 #13
0
 public CprFileFormat(string filename)
 {
     using var reader = new RiffReader(filename);
     _content         = reader.Read();
 }
예제 #14
0
        /// <summary>
        /// Read the file.
        /// </summary>
        /// <param name="r2">The file reader.</param>
        public override void Read(FileReader r2)
        {
            //Use a RIFF reader.
            using (RiffReader r = new RiffReader(r2.BaseStream)) {
                //Get the number of instruments.
                r.OpenChunk(r.GetChunk("colh"));
                uint numInsts = r.ReadUInt32();

                //Pointer table is skipped since it's just offsets to wave data relative to the first wave identifier.

                //Read wave data.
                Waves = new List <RiffWave>();
                foreach (var c in (r.GetChunk("wvpl") as ListChunk).Chunks)
                {
                    //Open block.
                    r.OpenChunk(c);

                    //Set position for proper RIFF reading.
                    r.BaseStream.Position -= 8;
                    int len = r.ReadInt32() + 8;
                    r.BaseStream.Position -= 8;
                    RiffWave wav = new RiffWave();
                    wav.Read(r.ReadBytes(len));
                    Waves.Add(wav);
                }

                //Read each instrument.
                foreach (ListChunk c in (r.GetChunk("lins") as ListChunk).Chunks)
                {
                    //Open block.
                    r.OpenChunk(c);

                    //New instrument.
                    Instrument inst = new Instrument();

                    //Read header.
                    r.OpenChunk(c.GetChunk("insh"));
                    r.ReadUInt32();
                    inst.BankId       = r.ReadUInt32();
                    inst.InstrumentId = r.ReadUInt32();

                    //Read regions.
                    foreach (ListChunk g in (c.GetChunk("lrgn") as ListChunk).Chunks)
                    {
                        //New region.
                        Region reg = new Region();

                        //Region header.
                        r.OpenChunk(g.GetChunk("rgnh"));
                        reg.NoteLow        = r.ReadUInt16();
                        reg.NoteHigh       = r.ReadUInt16();
                        reg.VelocityLow    = r.ReadUInt16();
                        reg.VelocityHigh   = r.ReadUInt16();
                        reg.DoublePlayback = r.ReadUInt16() > 0;
                        reg.KeyGroup       = (byte)r.ReadUInt16();
                        reg.Layer          = r.ReadUInt16();

                        //Note information.
                        r.OpenChunk(g.GetChunk("wsmp"));
                        r.ReadUInt32();
                        reg.RootNote = (byte)r.ReadUInt16();
                        reg.Tuning   = r.ReadInt16();
                        reg.Gain     = r.ReadInt32();
                        uint flags = r.ReadUInt32();
                        reg.NoTruncation  = (flags & 0b1) > 0;
                        reg.NoCompression = (flags & 0b10) > 0;
                        reg.Loops         = r.ReadUInt32() > 0;
                        if (reg.Loops)
                        {
                            r.ReadUInt32();
                            reg.LoopAndRelease = r.ReadUInt32() > 0;
                            reg.LoopStart      = r.ReadUInt32();
                            reg.LoopLength     = r.ReadUInt32();
                        }

                        //Wave link.
                        r.OpenChunk(g.GetChunk("wlnk"));
                        uint flg = r.ReadUInt16();
                        reg.PhaseMaster  = (flg & 0b1) > 0;
                        reg.MultiChannel = (flg & 0b10) > 0;
                        reg.PhaseGroup   = r.ReadUInt16();
                        reg.ChannelFlags = r.ReadUInt32();
                        reg.WaveId       = r.ReadUInt32();

                        //Loop.
                        Waves[(int)reg.WaveId].Loops = reg.Loops;
                        if (reg.Loops)
                        {
                            Waves[(int)reg.WaveId].LoopStart = reg.LoopStart;
                            Waves[(int)reg.WaveId].LoopEnd   = reg.LoopLength == 0 ? (uint)Waves[(int)reg.WaveId].Audio.NumSamples : reg.LoopStart + reg.LoopLength;
                        }

                        //Articulators.
                        var lar = g.GetChunk("lar2");
                        if (lar == null)
                        {
                            lar = g.GetChunk("lar1");
                        }
                        foreach (Chunk art in (g.GetChunk("lar2") as ListChunk).Chunks)
                        {
                            //Read articulator.
                            Articulator a = new Articulator();
                            r.OpenChunk(art);
                            r.ReadUInt32();
                            uint numCons = r.ReadUInt32();
                            for (uint i = 0; i < numCons; i++)
                            {
                                Connection con = new Connection();
                                con.SourceConnection      = (SourceConnection)r.ReadUInt16();
                                con.ControlConnection     = r.ReadUInt16();
                                con.DestinationConnection = (DestinationConnection)r.ReadUInt16();
                                con.TransformConnection   = (TransformConnection)r.ReadUInt16();
                                con.Scale = r.ReadInt32();
                                a.Connections.Add(con);
                            }
                            reg.Articulators.Add(a);
                        }

                        //Add region.
                        inst.Regions.Add(reg);
                    }

                    //Read name.
                    var info = c.GetChunk("INFO");
                    if (info != null)
                    {
                        var inam = (info as ListChunk).GetChunk("INAM");
                        if (inam != null)
                        {
                            r.OpenChunk(inam);
                            r.BaseStream.Position -= 4;
                            uint siz = r.ReadUInt32();
                            inst.Name = new string(r.ReadChars((int)siz).Where(x => x != 0).ToArray());
                        }
                    }

                    //Add instrument.
                    Instruments.Add(inst);
                }
            }
        }
예제 #15
0
        /// <summary>
        /// Read the file.
        /// </summary>
        /// <param name="r2">The reader.</param>
        public override void Read(FileReader r2)
        {
            //Use a RIFF reader.
            using (RiffReader r = new RiffReader(r2.BaseStream)) {
                //Get INFO data.
                var info = (ListChunk)r.GetChunk("INFO");

                //Sound engine.
                r.OpenChunk(info.GetChunk("isng"));
                SoundEngine = r.ReadNullTerminated();

                //Bank name.
                r.OpenChunk(info.GetChunk("INAM"));
                BankName = r.ReadNullTerminated();

                //ROM name.
                if (info.GetChunk("irom") != null)
                {
                    r.OpenChunk(info.GetChunk("irom"));
                    RomName = r.ReadNullTerminated();
                }

                //ROM version.
                if (info.GetChunk("iver") != null)
                {
                    r.OpenChunk(info.GetChunk("iver"));
                    RomVersion = new Tuple <ushort, ushort>(r.ReadUInt16(), r.ReadUInt16());
                }

                //Creation date.
                if (info.GetChunk("ICRD") != null)
                {
                    r.OpenChunk(info.GetChunk("ICRD"));
                    CreationDate = r.ReadNullTerminated();
                }

                //Sound designer.
                if (info.GetChunk("IENG") != null)
                {
                    r.OpenChunk(info.GetChunk("IENG"));
                    SoundDesigner = r.ReadNullTerminated();
                }

                //Product.
                if (info.GetChunk("IPRD") != null)
                {
                    r.OpenChunk(info.GetChunk("IPRD"));
                    Product = r.ReadNullTerminated();
                }

                //Copyright.
                if (info.GetChunk("ICOP") != null)
                {
                    r.OpenChunk(info.GetChunk("ICOP"));
                    Copyright = r.ReadNullTerminated();
                }

                //Comment.
                if (info.GetChunk("ICMT") != null)
                {
                    r.OpenChunk(info.GetChunk("ICMT"));
                    Comment = r.ReadNullTerminated();
                }

                //Tools.
                if (info.GetChunk("ISFT") != null)
                {
                    r.OpenChunk(info.GetChunk("ISFT"));
                    Tools = r.ReadNullTerminated();
                }

                //Get wave table position.
                long waveTablePos = ((ListChunk)r.GetChunk("sdta")).GetChunk("smpl").Pos;

                //The hydra.
                Presets     = new List <Preset>();
                Instruments = new List <Instrument>();
                Samples     = new List <SampleItem>();
                var hydra = (ListChunk)r.GetChunk("pdta");

                //Get presets.
                r.OpenChunk(hydra.GetChunk("phdr"));
                uint numPresets = hydra.GetChunk("phdr").Size / 38 - 1;
                for (uint i = 0; i < numPresets; i++)
                {
                    Presets.Add(r.Read <Preset>());
                }

                //Get preset bags.
                List <Tuple <ushort, ushort> > presetGenModIndices = new List <Tuple <ushort, ushort> >();
                List <Zone> presetZones = new List <Zone>();
                r.OpenChunk(hydra.GetChunk("pbag"));
                uint numPbags = hydra.GetChunk("pbag").Size / 4 - 1;
                for (uint i = 0; i < numPbags; i++)
                {
                    presetGenModIndices.Add(new Tuple <ushort, ushort>(r.ReadUInt16(), r.ReadUInt16()));
                    presetZones.Add(new Zone());
                }

                //Get preset modulators.
                List <Modulator> pMods = new List <Modulator>();
                r.OpenChunk(hydra.GetChunk("pmod"));
                uint numPmods = hydra.GetChunk("pmod").Size / 10 - 1;
                for (uint i = 0; i < numPmods; i++)
                {
                    pMods.Add(r.Read <Modulator>());
                }

                //Get preset generators.
                List <Generator> pGens = new List <Generator>();
                r.OpenChunk(hydra.GetChunk("pgen"));
                uint numPgens = hydra.GetChunk("pgen").Size / 4 - 1;
                for (uint i = 0; i < numPgens; i++)
                {
                    pGens.Add(r.Read <Generator>());
                }

                //Get true generators and modulators.
                for (int i = 0; i < presetGenModIndices.Count; i++)
                {
                    //Index.
                    int startGen = presetGenModIndices[i].Item1;
                    int startMod = presetGenModIndices[i].Item2;
                    int numGen   = pGens.Count - startGen;
                    int numMod   = pMods.Count - startMod;
                    if (i + 1 <= presetGenModIndices.Count - 1)
                    {
                        numGen = presetGenModIndices[i + 1].Item1 - startGen;
                        numMod = presetGenModIndices[i + 1].Item2 - startMod;
                    }

                    //Get stuff.
                    for (int j = startGen; j < startGen + numGen; j++)
                    {
                        presetZones[i].Generators.Add(pGens[j]);
                    }
                    for (int j = startMod; j < startMod + numMod; j++)
                    {
                        presetZones[i].Modulators.Add(pMods[j]);
                    }
                }

                //Add the zones to the presets.
                for (int i = 0; i < Presets.Count; i++)
                {
                    //Index.
                    int startZone = Presets[i].ReadingBagIndex;
                    int numZones  = presetGenModIndices.Count - startZone;
                    if (i + 1 <= Presets.Count - 1)
                    {
                        numZones = Presets[i + 1].ReadingBagIndex - startZone;
                    }

                    //Get stuff.
                    for (int j = startZone; j < startZone + numZones; j++)
                    {
                        if (Presets[i].Zones.Count == 0 && presetZones[j].Generators.Where(x => x.Gen == SF2Generators.Instrument).Where(x => x.Gen == SF2Generators.Instrument).Count() < 1)
                        {
                            Presets[i].GlobalZone = presetZones[j];
                        }
                        else
                        {
                            Presets[i].Zones.Add(presetZones[j]);
                        }
                    }
                }

                //Get instruments.
                r.OpenChunk(hydra.GetChunk("inst"));
                uint numInstruments = hydra.GetChunk("inst").Size / 22 - 1;
                for (uint i = 0; i < numInstruments; i++)
                {
                    Instruments.Add(r.Read <Instrument>());
                }

                //Get instrument bags.
                List <Tuple <ushort, ushort> > instrumentGenModIndices = new List <Tuple <ushort, ushort> >();
                List <Zone> instrumentZones = new List <Zone>();
                r.OpenChunk(hydra.GetChunk("ibag"));
                uint numIbags = hydra.GetChunk("ibag").Size / 4 - 1;
                for (uint i = 0; i < numIbags; i++)
                {
                    instrumentGenModIndices.Add(new Tuple <ushort, ushort>(r.ReadUInt16(), r.ReadUInt16()));
                    instrumentZones.Add(new Zone());
                }

                //Get instrument modulators.
                List <Modulator> iMods = new List <Modulator>();
                r.OpenChunk(hydra.GetChunk("imod"));
                uint numImods = hydra.GetChunk("imod").Size / 10 - 1;
                for (uint i = 0; i < numImods; i++)
                {
                    iMods.Add(r.Read <Modulator>());
                }

                //Get instrument generators.
                List <Generator> iGens = new List <Generator>();
                r.OpenChunk(hydra.GetChunk("igen"));
                uint numIgens = hydra.GetChunk("igen").Size / 4 - 1;
                for (uint i = 0; i < numIgens; i++)
                {
                    iGens.Add(r.Read <Generator>());
                }

                //Get true generators and modulators.
                for (int i = 0; i < instrumentGenModIndices.Count; i++)
                {
                    //Index.
                    int startGen = instrumentGenModIndices[i].Item1;
                    int startMod = instrumentGenModIndices[i].Item2;
                    int numGen   = iGens.Count - startGen;
                    int numMod   = iMods.Count - startMod;
                    if (i + 1 <= instrumentGenModIndices.Count - 1)
                    {
                        numGen = instrumentGenModIndices[i + 1].Item1 - startGen;
                        numMod = instrumentGenModIndices[i + 1].Item2 - startMod;
                    }

                    //Get stuff.
                    for (int j = startGen; j < startGen + numGen; j++)
                    {
                        instrumentZones[i].Generators.Add(iGens[j]);
                    }
                    for (int j = startMod; j < startMod + numMod; j++)
                    {
                        instrumentZones[i].Modulators.Add(iMods[j]);
                    }
                }

                //Add the zones to the instruments.
                for (int i = 0; i < Instruments.Count; i++)
                {
                    //Index.
                    int startZone = Instruments[i].ReadingBagIndex;
                    int numZones  = instrumentGenModIndices.Count - startZone;
                    if (i + 1 <= Instruments.Count - 1)
                    {
                        numZones = Instruments[i + 1].ReadingBagIndex - startZone;
                    }

                    //Get stuff.
                    for (int j = startZone; j < startZone + numZones; j++)
                    {
                        if (Instruments[i].Zones.Count == 0 && instrumentZones[j].Generators.Where(x => x.Gen == SF2Generators.SampleID).Count() < 1)
                        {
                            Instruments[i].GlobalZone = instrumentZones[j];
                        }
                        else
                        {
                            Instruments[i].Zones.Add(instrumentZones[j]);
                        }
                    }
                }

                //Get samples.
                r.OpenChunk(hydra.GetChunk("shdr"));
                uint numSamples = hydra.GetChunk("shdr").Size / 46 - 1;
                r.CurrentOffset = waveTablePos;
                for (uint i = 0; i < numSamples; i++)
                {
                    Samples.Add(r.Read <SampleItem>());
                }
            }
        }