예제 #1
0
        public HcaAudioStream(Stream baseStream, DecodeParams decodeParams, AudioParams audioParams)
            : base(baseStream, decodeParams)
        {
            var decoder = new HcaDecoder(baseStream, decodeParams);

            _decoder     = decoder;
            _audioParams = audioParams;
            var buffer = new byte[GetTotalAfterDecodingWaveDataSize()];

            _memoryCache   = new MemoryStream(buffer, true);
            _decodedBlocks = new Dictionary <long, long>();
            _decodeBuffer  = new byte[decoder.GetMinWaveDataBufferSize()];
            _hasLoop       = decoder.HcaInfo.LoopFlag;

            PrepareDecoding();
        }
예제 #2
0
        public int WriteWaveHeader(byte[] stream, AudioParams audioParams)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            var hcaInfo = HcaInfo;

            if (hcaInfo.LoopFlag && audioParams.InfiniteLoop)
            {
                // See remarks of AudioParams.InfiniteLoop.
                throw new HcaException(ErrorMessages.GetInvalidParameter(nameof(audioParams.InfiniteLoop)), ActionResult.InvalidParameter);
            }
            var minimumHeaderBufferSize = GetMinWaveHeaderBufferSize();

            if (stream.Length < minimumHeaderBufferSize)
            {
                throw new HcaException(ErrorMessages.GetBufferTooSmall(minimumHeaderBufferSize, stream.Length), ActionResult.BufferTooSmall);
            }
            var sampleBits = GetSampleBitsFromParams();
            var wavRiff    = WaveRiffSection.CreateDefault();
            var wavNote    = WaveNoteSection.CreateDefault();
            var wavData    = WaveDataSection.CreateDefault();

            wavRiff.FmtType          = (ushort)(_decodeParams.Mode != SamplingMode.R32 ? 1 : 3);
            wavRiff.FmtChannels      = (ushort)hcaInfo.ChannelCount;
            wavRiff.FmtBitCount      = (ushort)(sampleBits > 0 ? sampleBits : sizeof(float));
            wavRiff.FmtSamplingRate  = hcaInfo.SamplingRate;
            wavRiff.FmtSamplingSize  = (ushort)(wavRiff.FmtBitCount / 8 * wavRiff.FmtChannels);
            wavRiff.FmtSamplesPerSec = wavRiff.FmtSamplingRate * wavRiff.FmtSamplingSize;
            if (hcaInfo.Comment != null)
            {
                wavNote.NoteSize = 4 + hcaInfo.CommentLength + 1;
                if ((wavNote.NoteSize & 3) != 0)
                {
                    wavNote.NoteSize += 4 - (wavNote.NoteSize & 3);
                }
            }

            var totalBlockCount = hcaInfo.BlockCount;

            if (hcaInfo.LoopFlag)
            {
                totalBlockCount += (hcaInfo.LoopEnd - hcaInfo.LoopStart) * audioParams.SimulatedLoopCount;
            }
            wavData.DataSize = totalBlockCount * 0x80 * 8 * wavRiff.FmtSamplingSize;
            wavRiff.RiffSize = (uint)(0x1c + (hcaInfo.Comment != null ? wavNote.NoteSize : 0) + Marshal.SizeOf(wavData) + wavData.DataSize);

            var bytesWritten = stream.Write(wavRiff, 0);

            if (hcaInfo.Comment != null)
            {
                var address = bytesWritten;
                bytesWritten += stream.Write(wavNote, bytesWritten);
                stream.Write(hcaInfo.Comment, bytesWritten);
                bytesWritten  = address + 8 + (int)wavNote.NoteSize;
                bytesWritten += 8 + (int)wavNote.NoteSize;
            }
            bytesWritten += stream.Write(wavData, bytesWritten);
            return(bytesWritten);
        }
예제 #3
0
 public HcaAudioStream(Stream baseStream, AudioParams audioParams)
     : this(baseStream, DecodeParams.Default, audioParams)
 {
 }