Exemple #1
0
        public IDjmainArchive Decode(IDjmainChunk chunk, DjmainDecodeOptions options)
        {
            if (chunk.Data.Length != 0x1000000)
            {
                throw new RhythmCodexException("Chunk length must be exactly 16mb (0x1000000 bytes)");
            }

            if (chunk.Format == DjmainChunkFormat.Unknown ||
                !Enum.IsDefined(typeof(DjmainChunkFormat), chunk.Format))
            {
                throw new RhythmCodexException($"{nameof(chunk.Format)} is not recognized");
            }

            using (var stream = new ReadOnlyMemoryStream(chunk.Data))
            {
                var swappedStream = new ByteSwappedReadStream(stream);

                var chartSoundMap = _offsetProvider.GetSampleChartMap(chunk.Format)
                                    .Select((offset, index) => new KeyValuePair <int, int>(index, offset))
                                    .ToDictionary(kv => kv.Key, kv => kv.Value);
                var rawCharts     = ExtractCharts(stream, chunk.Format).Where(c => c.Value != null).ToList();
                var decodedCharts = DecodeCharts(rawCharts, chartSoundMap, chunk.Format);
                var sounds        = options.DisableAudio
                    ? null
                    : DecodeSounds(swappedStream, chunk.Format, chartSoundMap, rawCharts, decodedCharts, options)
                                    .ToDictionary(kv => kv.Key, kv => kv.Value.Select(s => s));

                return(new DjmainArchive
                {
                    RawCharts = rawCharts.ToDictionary(kv => kv.Key, kv => kv.Value),
                    Charts = decodedCharts?.Select(c => c.Value).ToList(),
                    Samples = sounds?.SelectMany(s => s.Value).Select(s => s.Value).ToList()
                });
            }
        }
        public ITask CreateDecodeDjmainHdd()
        {
            return(Build("Extract DJMAIN HDD", task =>
            {
                var files = GetInputFiles(task);
                if (!files.Any())
                {
                    task.Message = "No input files.";
                    return false;
                }

                ParallelProgress(task, files, file =>
                {
                    var options = new DjmainDecodeOptions
                    {
                        DisableAudio = !EnableExportingSounds
                    };

                    using (var stream = OpenRead(task, file))
                    {
                        long offset = 0;
                        var chunks = _djmainChunkStreamReader.Read(stream);
                        foreach (var chunk in chunks)
                        {
                            var chunkPath = $"{Alphabet.EncodeNumeric(chunk.Id, 4)}";
                            var decoded = _djmainDecoder.Decode(chunk, options);
                            ExportKeysoundedChart(task, file, chunkPath, $"{Alphabet.EncodeNumeric(chunk.Id, 4)}",
                                                  decoded.Charts, decoded.Samples);

                            if (EnableExportingRaw)
                            {
                                foreach (var(key, value) in decoded.RawCharts)
                                {
                                    using (var rawChartStream = OpenWriteMulti(task, file,
                                                                               _ => Path.Combine(chunkPath, $"{Alphabet.EncodeNumeric(key, 2)}.cs5")))
                                    {
                                        _djmainChartEventStreamWriter.Write(rawChartStream, value);
                                        rawChartStream.Flush();
                                    }
                                }
                            }
Exemple #3
0
        private IDictionary <int, IDictionary <int, ISound> > DecodeSounds(Stream stream,
                                                                           DjmainChunkFormat format,
                                                                           IReadOnlyDictionary <int, int> chartSoundMap,
                                                                           IEnumerable <KeyValuePair <int, IEnumerable <IDjmainChartEvent> > > charts,
                                                                           IEnumerable <KeyValuePair <int, IChart> > decodedCharts,
                                                                           DjmainDecodeOptions options)
        {
            return(_offsetProvider.GetSampleMapOffsets(format)
                   .Select((offset, index) => new KeyValuePair <int, int>(index, offset))
                   .ToDictionary(kv => kv.Key, kv =>
            {
                var chartData = charts
                                .Where(c => chartSoundMap[c.Key] == kv.Key)
                                .SelectMany(c => c.Value)
                                .ToList();
                var samples = DecodeSamples(stream, format, kv.Value, chartData);
                var decodedSamples = _soundDecoder.Decode(samples);
                if (!options.DoNotConsolidateSamples)
                {
                    _soundConsolidator.Consolidate(decodedSamples.Values,
                                                   decodedCharts.SelectMany(dc => dc.Value?.Events ?? Enumerable.Empty <IEvent>()));
                }

                foreach (var sample in decodedSamples.Where(s => s.Value.Samples.Any()))
                {
                    var s = sample.Value;
                    s[NumericData.SampleMap] = kv.Key;
                }

                foreach (var discardedSample in decodedSamples.Where(s => !s.Value.Samples.Any()).ToList())
                {
                    decodedSamples.Remove(discardedSample);
                }

                return decodedSamples;
            }));
        }