| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- using FFmpeg.AutoGen;
- using System;
- using System.IO;
- namespace OpenVIII.AV
- {
- /// <summary>
- /// Used only when reading ADPCM data from memory.
- /// </summary>
- public struct BufferData
- {
- #region Fields
- private IntPtr _header;
- private long _totalReadData;
- #endregion Fields
- #region Enums
- public enum TargetFile
- {
- SoundDat,
- OtherZzz
- }
- #endregion Enums
- #region Properties
- public static string DataFileName { get; set; }
- public long DataSeekLoc { get; set; }
- public long DataSize { get; set; }
- public uint HeaderSize { get; set; }
- public TargetFile Target { get; set; }
- #endregion Properties
- #region Methods
- public unsafe int Read(byte* buf, int bufSize)
- {
- int ret;
- if (HeaderSize > 0 && (ret = ReadHeader(buf, bufSize)) != ffmpeg.AVERROR_EOF)
- return ret;
- return ReadData(buf, bufSize);
- }
- public unsafe void SetHeader(byte* value) => _header = (IntPtr)value;
- internal long Seek(long offset, int whence)
- {
- switch (whence)
- {
- case ffmpeg.AVSEEK_SIZE:
- return offset == 0
- ? _totalReadData
- : throw new Exception($"unknown {nameof(whence)}: {whence}, {nameof(offset)}: {offset}");
- case 0:
- offset -= _totalReadData;
- break;
- default:
- throw new Exception($"unknown {nameof(whence)}: {whence}");
- }
- DataSeekLoc += offset;
- _totalReadData += offset;
- DataSize -= offset;
- return _totalReadData;
- }
- private unsafe int ReadData(byte* buf, int bufSize)
- {
- if (string.IsNullOrWhiteSpace(DataFileName))
- DataFileName = Path.Combine(Memory.FF8DirData, "Sound", "audio.dat");
- bufSize = Math.Min(bufSize, (int)DataSize);
- if (bufSize == 0)
- {
- return ffmpeg.AVERROR_EOF;
- }
- Stream s;
- ArchiveZzz other;
- switch (Target)
- {
- case TargetFile.SoundDat:
- if (File.Exists(DataFileName))
- {
- s = new FileStream(DataFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
- }
- else
- {
- other = (ArchiveZzz)ArchiveZzz.Load(Memory.Archives.ZZZ_OTHER);
- s = new MemoryStream(other.GetBinaryFile("audio.dat", true), false);
- }
- break;
- case TargetFile.OtherZzz:
- other = (ArchiveZzz)ArchiveZzz.Load(Memory.Archives.ZZZ_OTHER);
- s = other.OpenStream();
- break;
- default:
- throw new ArgumentOutOfRangeException(
- $"{nameof(BufferData)}::{nameof(ReadData)}::{nameof(Target)} Value out of range! Target = {{{Target}}}");
- }
- // binaryReader disposes of fs
- if (s == null) throw new NullReferenceException($"{nameof(BufferData)}::{nameof(ReadData)} stream is null");
- using (var br = new BinaryReader(s))
- {
- s.Seek(DataSeekLoc, SeekOrigin.Begin);
- using (var ums = new UnmanagedMemoryStream(buf, bufSize, bufSize, FileAccess.Write))
- {
- // copy public buffer data to buf
- ums.Write(br.ReadBytes(bufSize), 0, bufSize);
- DataSeekLoc += bufSize;
- _totalReadData += bufSize;
- DataSize -= bufSize;
- return bufSize;
- }
- }
- }
- private unsafe int ReadHeader(byte* buf, int bufSize)
- {
- bufSize = Math.Min(bufSize, (int)HeaderSize);
- if (bufSize == 0)
- {
- return ffmpeg.AVERROR_EOF;
- }
- // copy public buffer data to buf
- Buffer.MemoryCopy((void*)_header, buf, bufSize, bufSize);
- _header += bufSize;
- HeaderSize -= (uint)bufSize;
- return bufSize;
- }
- #endregion Methods
- }
- }
|