Converting a frequency into a -1..1 float

雨燕双飞 提交于 2019-12-25 03:53:53

问题


I'm trying to play back a sound at a given pitch using (C#) XNA audio framework's SoundEffect class. So far, I have this (very basic)

public void playSynth(SoundEffect se, int midiNote) {
    float pitch = (float)functions.getMIDIFreq(midiNote) / ((float)functions.getMIDIFreq(127)/2);
    pitch-=1F;
    Debug.WriteLine("Note: {0}. Float: {1}",midiNote,pitch);
    synth = se.CreateInstance();
    synth.IsLooped = false;
    synth.Pitch = pitch;
    synth.Play();
}

Currently, the pitch played back is very off-key, because the math is wrong. The way this function works is I'm sending a MIDI note (0 through 127) to the function, using a function I made called getMIDIFreq to convert that note to a frequency - which works fine.

To call this function, I'm using this:

SoundEffect sound = SoundEffect.FromStream(TitleContainer.OpenStream(@"synth.wav"));
playSynth(sound,(int)midiNote);  //where midiNote is 0...127 number

where synth.wav is a simple C note I created in a DAW and exported. The whole point of this program is to play back the MIDI note given in that synth sound, but I'd gladly settle for a sine wave, or anything really. I can't use Console.Beep because it's extremely slow and not for playing entire songs with notes in rapid succession.

So my question is, how could I fix this code so it plays the sample at the right pitch? I realize I only have 2 octaves to work with here, so if there's a solution that involves generating a tone at a given frequency and is very fast, that would be even better.

Thanks!

EDIT: I'm making this a WinForms application, not an XNA game, but I have the framework downloaded and referenced in my project.


回答1:


You can't apply an arbitrary frequency. You can only lower pitch by an octave (half frequency) or raise it by an octave (double frequency). So, to calculate the pitch bend value, you first need to know the initial pitch of the sample.

Suppose your sample is 440 Hz A, and you want an A an octave down (220 Hz). The value you need is -1. yourPitch / initiPitch = 0.5 to 2.0. You will need to make that into the scale of -1 to +1. I can't tell you exactly how, because the documentation isn't clear if the scale is logarithmic or not. You would have to experiment, but this should get you started.



来源:https://stackoverflow.com/questions/14359881/converting-a-frequency-into-a-1-1-float

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!