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; } }
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)); }