示例#1
0
        void OnAudioFilterRead(float[] data, int channel)
        {
            Debug.Assert(this.channel == channel);
            int count = 0;

            while (count < data.Length)
            {
                if (currentBuffer == null || bufferHead >= currentBuffer.Length)
                {
                    sequencer.FillMidiEventQueue();
                    synthesizer.GetNext();
                    currentBuffer = synthesizer.WorkingBuffer;
                    bufferHead    = 0;
                }
                var length = Mathf.Min(currentBuffer.Length - bufferHead, data.Length - count);
                System.Array.Copy(currentBuffer, bufferHead, data, count, length);
                bufferHead += length;
                count      += length;
            }
        }
示例#2
0
        public SynthPlayer()
        {
            Logger.Debug("Initializing player");

            State = SynthPlayerState.Stopped;
            OnPlayerStateChanged(new PlayerStateChangedEventArgs(State));

            Logger.Debug("Opening output");
            Output = Platform.Platform.CreateOutput();

            Logger.Debug("Creating synthesizer");
            Synth     = new Synthesizer(Output.SampleRate, SynthConstants.AudioChannels, 441, 3, 100);
            Sequencer = new MidiFileSequencer(Synth);

            Sequencer.AddFinishedListener(Output.SequencerFinished);

            Output.Finished += () =>
            {
                // stop everything
                Stop();
                Logger.Debug("Finished playback");
                OnFinished();
            };
            Output.SampleRequest += () =>
            {
                // synthesize buffer
                Sequencer.FillMidiEventQueue();
                Synth.Synthesize();
                // send it to output
                Output.AddSamples(Synth.SampleBuffer);
            };
            Output.PositionChanged += pos =>
            {
                // log position
                FirePositionChanged(pos);
            };

            Output.Open();
        }
        public int Read(byte[] buffer, int offset, int count)
        {
            if (state != PlayerState.Playing)
            {
                if (state == PlayerState.Stopped)
                {
                    return(0);
                }
                else
                {
                    Array.Clear(buffer, offset, buffer.Length - offset);
                    return(count);
                }
            }
            int[] ccList = new int[16];
            while (circularBuffer.Count < count)
            {
                lock (lockObj)
                {
                    if (msgQueue.Count > 0)
                    {
                        while (msgQueue.Count > 0)
                        {
                            processMessage(msgQueue.Dequeue());
                        }
                    }
                    mseq.FillMidiEventQueue();
                    if (UpdateMidiControllers != null)
                    {
                        IEnumerator <MidiMessage> mmEnum = synth.MidiMessageEnumerator;
                        while (mmEnum.MoveNext())
                        {
                            if (mmEnum.Current.command == 0xC0)
                            {//program change
                                ccList[mmEnum.Current.channel] |= 0x1;
                            }
                            else if (mmEnum.Current.command == 0xE0)
                            {//pitch bend
                                ccList[mmEnum.Current.channel] |= 0x2;
                            }
                            else if (mmEnum.Current.command == 0xB0)
                            {
                                switch (mmEnum.Current.data1)
                                {
                                case 0x07:     //vol
                                    ccList[mmEnum.Current.channel] |= 0x4;
                                    break;

                                case 0x0A:     //pan
                                    ccList[mmEnum.Current.channel] |= 0x8;
                                    break;

                                case 0x0B:     //exp
                                    ccList[mmEnum.Current.channel] |= 0x10;
                                    break;

                                case 0x40:     //hold
                                    ccList[mmEnum.Current.channel] |= 0x20;
                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                    }
                    synth.GetNext(sbuff);
                    circularBuffer.Write(sbuff, 0, sbuff.Length);
                }
            }
            if (TimeUpdate != null)
            {
                TimeUpdate(mseq.CurrentTime, mseq.EndTime, synth.ActiveVoices);
            }
            if (UpdateMidiControllers != null)
            {
                UpdateMidiControllers(ccList);
            }
            return(circularBuffer.Read(buffer, offset, count));
        }