示例#1
0
文件: Playback.cs 项目: XAYRGA/JPlay
 public void NoteOn(byte num, byte key, byte velocity)
 {
     try
     {
         Instrument  instrument  = instrumentTable[new Tuple <byte, byte>(Bank, Instrument)];
         int         value       = instrument.GetSampleEntry(key).Value;
         Sample      sample      = soundData.SampleBanks[soundData.InstrumentBanks[Bank].Wsys][(short)instrument.Samples[value].Id];
         AudioBuffer audioBuffer = new AudioBuffer();
         audioBuffer.AudioBytes = sample.Data.Length;
         audioBuffer.Stream     = new DataStream(sample.Data.Length, canRead: true, canWrite: true);
         audioBuffer.Stream.Write(sample.Data, 0, sample.Data.Length);
         audioBuffer.PlayBegin  = 0;
         audioBuffer.PlayLength = 0;
         audioBuffer.LoopCount  = (sample.IsLooping ? 255 : 0);
         audioBuffer.LoopBegin  = sample.LoopStart;
         audioBuffer.LoopLength = 0;
         WaveFormat  sourceFormat = new WaveFormat(sample.SamplesPerSecond, sample.BitsPerSample, sample.Channels);
         SourceVoice sourceVoice  = new SourceVoice(engine, sourceFormat, VoiceFlags.None, 1024f);
         sourceVoice.SetOutputVoices(new VoiceSendDescriptor(submix));
         sourceVoice.SubmitSourceBuffer(audioBuffer, null);
         float num2 = XAudio2.SemitonesToFrequencyRatio((!instrument.IsPercussion) ? (key - sample.RootKey) : 0) * instrument.Samples[value].FrequenyMultiplier * instrument.FrequencyMultiplier;
         sourceVoice.SetFrequencyRatio(num2);
         sourceVoice.SetVolume(ValueToAmplitude(velocity));
         NoteData noteData = new NoteData(sourceVoice, num2, velocity, instrument.IsPercussion);
         if (instrument.IsPercussion)
         {
             noteData.PercussionPan = instrument.Samples[value].Pan.Value;
             sbyte b = (sbyte)(noteData.PercussionPan - 63);
             sourceVoice.SetOutputMatrix(1, 2, new float[2]
             {
                 0.5f - (float)b / 127f,
                 0.5f + (float)b / 127f
             });
         }
         else
         {
             sourceVoice.SetOutputMatrix(1, 2, outputMatrix);
         }
         noteData.BufferStream = audioBuffer.Stream;
         noteData.Voice.Start();
         voiceTable.Add(num, noteData);
         sourceFormat = null;
         GC.Collect();
     }
     catch
     {
     }
 }
示例#2
0
        /// <summary>
        /// Start to play a note, It will be stopped until you call "StopNote"
        /// </summary>
        /// <param name="notePitch"></param>
        public void PlayNote(int notePitch)
        {
            var asy = Task.Run(() =>
            {
                if ((Voice == null) || (Instrument == null))
                {
                    return;
                }

                //If we play another note
                if ((notePitch != PlayingPitch) || !IsPlaying || stopping)
                {
                    //Get the frequenc y of the pitch
                    var FrequencyRatio = XAudio2.SemitonesToFrequencyRatio(notePitch) / 2f;
                    //See if we should use another sample
                    var reloadNeeded = Instrument.ReloadNeeded(FrequencyRatio, ActualFrequencyRatio);
                    if (Instrument.IsPlugged || reloadNeeded || !IsPlaying || stopping)
                    {
                        ReloadBuffer(FrequencyRatio, reloadNeeded);
                    }
                    CancelStop.Set();
                    //Set the frequency ratio to the voice
                    var realFrequencyRatio = Instrument.GetCorrectFrequencyRatio(FrequencyRatio);
                    Voice.SetFrequencyRatio(realFrequencyRatio);
                    ActualFrequencyRatio = FrequencyRatio;
                    PlayingPitch         = notePitch;
                }

                //Start the play if needed
                if (!IsPlaying)
                {
                    Voice.Start();
                    Voice.SetVolume(1, XAudio2.CommitNow);
                }

                //update state
                IsPlaying = true;
            });
        }
示例#3
0
 public float SemitonesToFrequencyRatio(float semitones)
 {
     return(XAudio2.SemitonesToFrequencyRatio(semitones));
 }
示例#4
0
 /// <summary>
 /// Sets the frequency of the sound.
 /// </summary>
 /// <param name="f">The frequency ratio of the sound expressed in semitones.</param>
 public void setFrequency(float f)
 {
     voice.SetFrequencyRatio(XAudio2.SemitonesToFrequencyRatio(f));
 }