예제 #1
0
        private void ExtractISO(PbpDiscEntry disc, string path, ExtractOptions extractInfo, CancellationToken cancellationToken)
        {
            try
            {
                disc.ProgressEvent += ProgressEvent;

                if (!ContinueIfFileExists(extractInfo, path))
                {
                    return;
                }

                Notify?.Invoke(PopstationEventEnum.Info, $"Writing {path}...");
                Notify?.Invoke(PopstationEventEnum.GetIsoSize, disc.IsoSize);
                Notify?.Invoke(PopstationEventEnum.ExtractStart, disc.Index);

                var cueFilename = Path.GetFileNameWithoutExtension(path) + ".cue";
                var dirPath     = Path.GetDirectoryName(path);
                var cuePath     = Path.Combine(dirPath, cueFilename);

                TempFiles.Add(path);
                TempFiles.Add(cuePath);

                using (var isoStream = new FileStream(path, FileMode.Create, FileAccess.Write))
                {
                    disc.CopyTo(isoStream, cancellationToken);
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                TempFiles.Remove(path);

                if (!extractInfo.CreateCuesheet)
                {
                    return;
                }


                var cueFile = TOCHelper.TOCtoCUE(disc.TOC, Path.GetFileName(path));

                CueFileWriter.Write(cueFile, cuePath);

                TempFiles.Remove(cuePath);

                Notify?.Invoke(PopstationEventEnum.ExtractComplete, null);
            }
            finally
            {
                disc.ProgressEvent -= ProgressEvent;
            }
        }
예제 #2
0
        private static CueFile TOCtoCUE(List <TOCEntry> tocEntries, string dataPath)
        {
            var cueFile = new CueFileEntry()
            {
                FileName = dataPath,
                Tracks   = new List <CueTrack>(),
                FileType = "BINARY"
            };

            var audioLeadin = new IndexPosition {
                Seconds = 2
            };

            foreach (var track in tocEntries)
            {
                var position = new IndexPosition
                {
                    Minutes = track.Minutes,
                    Seconds = track.Seconds,
                    Frames  = track.Frames,
                };

                var indexes = new List <CueIndex>();

                if (track.TrackType == TrackTypeEnum.Audio)
                {
                    indexes.Add(new CueIndex()
                    {
                        Number   = 0,
                        Position = position - audioLeadin,
                    });
                }

                indexes.Add(new CueIndex()
                {
                    Number   = 1,
                    Position = position,
                });

                var cueTrack = new CueTrack()
                {
                    DataType = TOCHelper.GetDataType(track.TrackType),
                    Indexes  = indexes,
                    Number   = track.TrackNo
                };


                cueFile.Tracks.Add(cueTrack);
            }

            return(new CueFile(new[] { cueFile }));
        }
예제 #3
0
        public static byte[] GetTOCData(this CueFile cue, uint isosize)
        {
            var tracks = cue.FileEntries.SelectMany(cf => cf.Tracks).ToList();

            byte[] tocData = new byte[0xA * (tracks.Count + 3)];

            var trackBuffer = new byte[0xA];

            var frames   = isosize / 2352;
            var position = TOCHelper.PositionFromFrames(frames);

            var ctr = 0;

            trackBuffer[0] = (byte)TOCHelper.GetTrackType(tracks.First().DataType);
            trackBuffer[1] = 0x00;
            trackBuffer[2] = 0xA0;
            trackBuffer[3] = 0x00;
            trackBuffer[4] = 0x00;
            trackBuffer[5] = 0x00;
            trackBuffer[6] = 0x00;
            trackBuffer[7] = TOCHelper.ToBinaryDecimal(tracks.First().Number);
            trackBuffer[8] = TOCHelper.ToBinaryDecimal(0x20);
            trackBuffer[9] = 0x00;

            Array.Copy(trackBuffer, 0, tocData, ctr, 0xA);
            ctr += 0xA;

            trackBuffer[0] = (byte)TOCHelper.GetTrackType(tracks.Last().DataType);
            trackBuffer[2] = 0xA1;
            trackBuffer[7] = TOCHelper.ToBinaryDecimal(tracks.Last().Number);
            trackBuffer[8] = 0x00;

            Array.Copy(trackBuffer, 0, tocData, ctr, 0xA);
            ctr += 0xA;

            trackBuffer[0] = 0x01;
            trackBuffer[2] = 0xA2;
            trackBuffer[7] = TOCHelper.ToBinaryDecimal(position.Minutes);
            trackBuffer[8] = TOCHelper.ToBinaryDecimal(position.Seconds);
            trackBuffer[9] = TOCHelper.ToBinaryDecimal(position.Frames);

            Array.Copy(trackBuffer, 0, tocData, ctr, 0xA);
            ctr += 0xA;

            foreach (var track in tracks)
            {
                trackBuffer[0] = (byte)TOCHelper.GetTrackType(track.DataType);
                trackBuffer[1] = 0x00;
                trackBuffer[2] = TOCHelper.ToBinaryDecimal(track.Number);
                var pos = track.Indexes.First(idx => idx.Number == 1).Position;
                trackBuffer[3] = TOCHelper.ToBinaryDecimal(pos.Minutes);
                trackBuffer[4] = TOCHelper.ToBinaryDecimal(pos.Seconds);
                trackBuffer[5] = TOCHelper.ToBinaryDecimal(pos.Frames);
                trackBuffer[6] = 0x00;
                pos            = pos + (2 * 75); // add 2 seconds for lead in (75 frames / second)
                trackBuffer[7] = TOCHelper.ToBinaryDecimal(pos.Minutes);
                trackBuffer[8] = TOCHelper.ToBinaryDecimal(pos.Seconds);
                trackBuffer[9] = TOCHelper.ToBinaryDecimal(pos.Frames);

                Array.Copy(trackBuffer, 0, tocData, ctr, 0xA);
                ctr += 0xA;
            }

            //0x00    1 byte Track type - 0x41 = data track, 0x01 = audio track
            //0x01    1 byte Always null
            //0x02    1 byte The track number in "binary decimal"
            //0x03    3 bytes The absolute track start address in "binary decimal" - first byte is minutes, second is seconds, third is frames
            //0x06    1 byte Always null
            //0x07    3 bytes The "relative" track address -same as before, and uses MM: SS: FF format

            return(tocData);
        }
예제 #4
0
        static MergedBin MergeBins(string file, CueFile cueFilex, string tempPath)
        {
            var mergedBin = new MergedBin();

            mergedBin.CueFile = new CueFile();

            var cueFilePath = Path.GetDirectoryName(file);


            long currentFrame = 0;

            var mergedFilename = Path.GetFileNameWithoutExtension(file) + " - MERGED.bin";

            mergedBin.Path = Path.Combine(tempPath, mergedFilename);

            var mcueFile = new CueFileEntry()
            {
                FileName = mergedFilename,
                FileType = "BINARY",
                Tracks   = new List <CueTrack>()
            };

            mergedBin.CueFile.FileEntries.Add(mcueFile);

            using (var joinedFile = new FileStream(mergedBin.Path, FileMode.Create))
            {
                foreach (var cueFileEntry in cueFilex.FileEntries)
                {
                    var binPath = cueFileEntry.FileName;
                    if (Path.GetDirectoryName(binPath) == "" || Path.GetDirectoryName(binPath).StartsWith("..") || Path.GetDirectoryName(binPath).StartsWith("."))
                    {
                        binPath = Path.Combine(cueFilePath, cueFileEntry.FileName);
                    }

                    using (var srcStream = new FileStream(binPath, FileMode.Open))
                    {
                        srcStream.CopyTo(joinedFile);

                        foreach (var item in cueFileEntry.Tracks)
                        {
                            var indexes = new List <CueIndex>();
                            foreach (var idx in item.Indexes)
                            {
                                var newIndex = new CueIndex
                                {
                                    Number   = idx.Number,
                                    Position = idx.Position + TOCHelper.PositionFromFrames(currentFrame)
                                };
                                indexes.Add(newIndex);
                            }
                            var newTrack = new CueTrack()
                            {
                                DataType = item.DataType,
                                Number   = item.Number,
                                Indexes  = indexes
                            };
                            mcueFile.Tracks.Add(newTrack);
                        }

                        var frames = srcStream.Length / 2352;
                        currentFrame += frames;
                    }
                }
            }

            return(mergedBin);
        }