Example #1
0
        /// <summary>
        /// Allocates the unmanaged memory for the midi headers and buffers.
        /// </summary>
        private void AllocateBuffers()
        {
            if (this.BufferSize > 0 && this.BufferCount > 0)
            {
                this.memHeaders = MemoryUtil.Alloc(MemoryUtil.SizeOfMidiHeader * this.BufferCount);
                this.memBuffers = MemoryUtil.Alloc(this.BufferSize * this.BufferCount);
                GC.AddMemoryPressure((MemoryUtil.SizeOfMidiHeader + this.BufferSize) * this.BufferCount);

                IntPtr headerMem = IntPtr.Add(this.memHeaders, 0);
                IntPtr bufferMem = IntPtr.Add(this.memBuffers, 0);

                for (int i = 0; i < this.BufferCount; i++)
                {
                    var buffer = new MidiBufferStream(headerMem, bufferMem, this.BufferSize, this.StreamAccess);

                    try
                    {
                        this.unusedBuffers.Enqueue(buffer);
                        this.mapBuffers.Add(headerMem, buffer);

                        headerMem = IntPtr.Add(headerMem, MemoryUtil.SizeOfMidiHeader);
                        bufferMem = IntPtr.Add(bufferMem, this.BufferSize);
                    }
                    catch
                    {
                        buffer.Dispose();
                        throw;
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// Reads a unsigned integer from the memory block at the <paramref name="byteOffset"/>.
        /// </summary>
        /// <param name="byteOffset">An offset from the start of the memory block where the writing should start.
        /// Make sure the <paramref name="byteOffset"/> is properly aligned (usually 16-bits).</param>
        /// <returns>Returns the value.</returns>
        public uint ReadUintAt(int byteOffset)
        {
            Check.IfArgumentOutOfRange(byteOffset, 0, int.MaxValue, nameof(byteOffset));

            var size = MemoryUtil.SizeOf(typeof(uint));

            ValidateAccess(byteOffset, size);

            IntPtr location = IntPtr.Add(_memory, byteOffset);

            return(*(uint *)location.ToPointer());
        }
Example #3
0
        /// <summary>
        /// Writes a <paramref name="value"/> to the specified <paramref name="byteOffset"/>.
        /// </summary>
        /// <param name="byteOffset">An offset from the start of the memory block where the writing should start.
        /// Make sure the <paramref name="byteOffset"/> is properly aligned (usually 16-bits).</param>
        /// <param name="value">The value to write.</param>
        public void WriteUintAt(int byteOffset, uint value)
        {
            Check.IfArgumentOutOfRange(byteOffset, 0, int.MaxValue, nameof(byteOffset));

            var size = MemoryUtil.SizeOf(typeof(uint));

            ValidateAccess(byteOffset, size);

            IntPtr location = IntPtr.Add(_memory, byteOffset);

            *(uint *)location.ToPointer() = value;
        }
Example #4
0
        /// <summary>
        /// Reads a unsigned integer from the memory block at the <paramref name="byteOffset"/>.
        /// </summary>
        /// <param name="byteOffset">An offset from the start of the memory block where the writing should start.
        /// Make sure the <paramref name="byteOffset"/> is properly aligned (usually 16-bits).</param>
        /// <returns>Returns the value.</returns>
        public uint ReadUintAt(int byteOffset)
        {
            Contract.Requires(byteOffset >= 0);

            var size = MemoryUtil.SizeOf(typeof(uint));

            this.ValidateAccess(byteOffset, size);

            IntPtr location = IntPtr.Add(this.memory, byteOffset);

            return(*(uint *)location.ToPointer());
        }
Example #5
0
        /// <summary>
        /// Writes a <paramref name="value"/> to the specified <paramref name="byteOffset"/>.
        /// </summary>
        /// <param name="byteOffset">An offset from the start of the memory block where the writing should start.
        /// Make sure the <paramref name="byteOffset"/> is properly aligned (usually 16-bits).</param>
        /// <param name="value">The value to write.</param>
        public void WriteUintAt(int byteOffset, uint value)
        {
            Contract.Requires(byteOffset >= 0);

            var size = MemoryUtil.SizeOf(typeof(uint));

            this.ValidateAccess(byteOffset, size);

            IntPtr location = IntPtr.Add(this.memory, byteOffset);

            *(uint *)location.ToPointer() = value;
        }
Example #6
0
        /// <summary>
        /// Frees the allocated memory.
        /// </summary>
        private void FreeBuffers()
        {
            if (this.memHeaders != IntPtr.Zero)
            {
                MemoryUtil.Free(this.memHeaders);
                this.memHeaders = IntPtr.Zero;
            }

            if (this.memBuffers != IntPtr.Zero)
            {
                MemoryUtil.Free(this.memBuffers);
                this.memBuffers = IntPtr.Zero;
            }

            var totalLength = (MemoryUtil.SizeOfMidiHeader + this.BufferSize) * this.BufferCount;

            if (totalLength > 0)
            {
                GC.RemoveMemoryPressure(totalLength);
            }
        }