Esempio n. 1
0
        /// <summary>
        /// Midi out device callback handler.
        /// </summary>
        /// <param name="message">The type of callback event.</param>
        /// <param name="parameter1">First parameter dependent on <paramref name="message"/>.</param>
        /// <param name="parameter2">Second parameter dependent on <paramref name="message"/>.</param>
        /// <returns>Returns true when handled.</returns>
        protected override bool OnMessage(int message, IntPtr parameter1, IntPtr parameter2)
        {
            bool handled = true;

            switch ((uint)message)
            {
            case NativeMethods.MOM_OPEN:
                // don't change status here, MidiSafeHandle has not been set yet.
                break;

            case NativeMethods.MOM_CLOSE:
                Status         = MidiPortStatus.Closed;
                MidiSafeHandle = null;
                break;

            case NativeMethods.MOM_DONE:
                MidiBufferStream buffer = BufferManager.FindBuffer(parameter1);
                if (buffer != null)
                {
                    if (NextCallback != null)
                    {
                        NextCallback.LongData(buffer, MidiDataCallbackType.Done);
                    }

                    BufferManager.ReturnBuffer(buffer);
                }
                break;

            default:
                handled = false;
                break;
            }

            return(handled);
        }
Esempio n. 2
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;
                    }
                }
            }
        }
Esempio n. 3
0
        public virtual void ReturnBuffer(MidiBufferStream buffer)
        {
            Contract.Requires(buffer != null);
            Check.IfArgumentNull(buffer, "buffer");
            ThrowIfDisposed();
            if (!this.mapBuffers.ContainsKey(buffer.HeaderMemory))
            {
                throw new InvalidOperationException("Specified buffer is not owned by this instance.");
            }

            if (!this.usedBuffers.Contains(buffer))
            {
                throw new InvalidOperationException("Specified buffer was not in the used buffer list of this instance.");
            }

            if ((buffer.HeaderFlags & NativeMethods.MHDR_INQUEUE) > 0)
            {
                throw new InvalidOperationException(Properties.Resources.MidiBufferManager_BufferStillInQueue);
            }

            //// could be an error
            ////if ((buffer.HeaderFlags & NativeMethods.MHDR_DONE) == 0)
            ////{
            ////    throw new InvalidOperationException(Properties.Resources.MidiBufferManager_BufferNotDone);
            ////}

            lock (this.locker)
            {
                this.usedBuffers.Remove(buffer);
                this.unusedBuffers.Enqueue(buffer);
            }

            buffer.Position = 0;
        }
Esempio n. 4
0
        protected override void OnUnprepareBuffer(MidiBufferStream buffer)
        {
            Check.IfArgumentNull(buffer, "buffer");

            int result = NativeMethods.midiOutUnprepareHeader(
                MidiPort.MidiSafeHandle, buffer.ToIntPtr(), (uint)MemoryUtil.SizeOfMidiHeader);

            MidiOutPortBase.ThrowIfError(result);
        }
        protected override void OnPrepareBuffer(MidiBufferStream buffer)
        {
            Check.IfArgumentNull(buffer, "buffer");

            base.OnPrepareBuffer(buffer);

            // mark buffers as streams
            buffer.HeaderFlags |= NativeMethods.MHDR_ISSTRM;
        }
Esempio n. 6
0
        /// <summary>
        /// Adds the <paramref name="buffer"/> to the midi port.
        /// </summary>
        /// <param name="buffer">Must not be null.</param>
        private void AddBufferToPort(MidiBufferStream buffer)
        {
            Check.IfArgumentNull(buffer, "buffer");

            // make sure the stream is rewound.
            buffer.Position = 0;

            int result = NativeMethods.midiInAddBuffer(
                MidiPort.MidiSafeHandle,
                buffer.ToIntPtr(),
                (uint)MemoryUtil.SizeOfMidiHeader);

            MidiInPort.ThrowIfError(result);
        }
Esempio n. 7
0
        /// <summary>
        /// Returns the <paramref name="buffer"/> to the pool.
        /// </summary>
        /// <param name="buffer">Must not be null.</param>
        /// <remarks>Call this method when the <paramref name="buffer"/> is no longer needed.</remarks>
        public override void ReturnBuffer(MidiBufferStream buffer)
        {
            Check.IfArgumentNull(buffer, "buffer");

            // do not re-add buffers during a Reset (or Close) that is meant to return all
            // buffers from the MidiInPort to the buffer manager.
            if (!MidiPort.HasStatus(MidiPortStatus.Reset | MidiPortStatus.Closed))
            {
                // returned buffers are added to the midi in port again
                // to make them available for recording sysex.
                AddBufferToPort(buffer);
            }
            else
            {
                OnUnprepareBuffer(buffer);
                base.ReturnBuffer(buffer);
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Registers all buffers in the pool with the Midi In Port.
        /// </summary>
        /// <exception cref="InvalidOperationException">Thrown when the Midi In Port is not open.</exception>
        /// <remarks>After <see cref="M:MidiInPort.Reset"/> has been called, all buffers are
        /// returned to this buffer manager. Use this function to register all the (unused) buffers
        /// with the midi port again in order to receive long midi messages.
        /// Note that the <see cref="P:MidiInPort.IsOpen"/> must be true - the port must be open.</remarks>
        public void RegisterAllBuffers()
        {
            if (!MidiPort.IsOpen)
            {
                throw new InvalidOperationException(Properties.Resources.MidiInPort_PortNotOpen);
            }

            // add unused buffers to port
            MidiBufferStream buffer = RetrieveBuffer();

            while (buffer != null)
            {
                OnPrepareBuffer(buffer);
                AddBufferToPort(buffer);

                buffer = RetrieveBuffer();
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Retrieves a fresh (unused) buffer for the application to use.
        /// </summary>
        /// <returns>Returns null when no more buffers are unused.</returns>
        /// <remarks>This method is only called by the application logic for an <see cref="MidiOutPort"/>
        /// or a <see cref="MidiOutStreamPort"/>. The <see cref="MidiInPort"/> registers its own buffers.</remarks>
        public virtual MidiBufferStream RetrieveBuffer()
        {
            MidiBufferStream buffer = null;

            if (this.unusedBuffers.Count > 0)
            {
                lock (this.locker)
                {
                    if (this.unusedBuffers.Count > 0)
                    {
                        buffer = this.unusedBuffers.Dequeue();
                        this.usedBuffers.Add(buffer);
                    }
                }
            }

            return(buffer);
        }
Esempio n. 10
0
        public override void LongData(MidiBufferStream buffer)
        {
            Check.IfArgumentNull(buffer, "buffer");

            ////if ((buffer.HeaderFlags & NativeMethods.MHDR_PREPARED) == 0)
            ////{
            ////    throw new InvalidOperationException("LongData cannot be called with a MidiBufferStream that has not been prepared.");
            ////}

            buffer.BytesRecorded = buffer.Position;

            int result = NativeMethods.midiStreamOut(
                MidiSafeHandle,
                buffer.ToIntPtr(),
                (uint)MemoryUtil.SizeOfMidiHeader);

            ThrowIfError(result);
        }
Esempio n. 11
0
        /// <summary>
        /// Contract.
        /// </summary>
        /// <param name="buffer">Must not be null.</param>
        void IMidiDataSender.LongData(MidiBufferStream buffer)
        {
            Contract.Requires(buffer != null);

            throw new NotImplementedException();
        }
Esempio n. 12
0
 protected abstract void OnUnprepareBuffer(MidiBufferStream buffer);
Esempio n. 13
0
        /// <summary>
        /// Contract.
        /// </summary>
        /// <param name="buffer">Must not be null.</param>
        protected override void OnUnprepareBuffer(MidiBufferStream buffer)
        {
            Contract.Requires(buffer != null);

            throw new NotImplementedException();
        }
Esempio n. 14
0
        /// <summary>
        /// Contract.
        /// </summary>
        /// <param name="buffer">Must not be null.</param>
        /// <param name="timestamp">No contract.</param>
        void IMidiDataErrorReceiver.LongError(MidiBufferStream buffer, long timestamp)
        {
            Contract.Requires(buffer != null);

            throw new NotImplementedException();
        }
        /// <summary>
        /// Contract.
        /// </summary>
        /// <param name="buffer">Must not be null.</param>
        /// <param name="notificationType">No contract.</param>
        void IMidiDataCallback.LongData(MidiBufferStream buffer, MidiDataCallbackType notificationType)
        {
            Contract.Requires(buffer != null);

            throw new System.NotImplementedException();
        }