我有一个C#Windows Forms应用程序,它连接到第三方设备,感应环境中的变化。我想在一个可更新的线程上运行一个不断运行的音调。根据我传入线程的值,频率会变高或变低。我可以指出这个例子或想法吗?我的声音生成不太流畅,我不确定Beep(int,int)是否可行。
谢谢!
答案 0 :(得分:0)
The NAudio NuGet-Package is quite easy to use. I have a working snipped here that you can modify if you want:
void Main()
{
var sine = new SineGenerator();
var waveOut = new WaveOut();
waveOut.DesiredLatency = 100;
waveOut.Init(sine);
waveOut.Play();
var random = new Random();
while (true)
{
Thread.Sleep(100);
sine.Frequency = random.Next(100, 500);
}
waveOut.Stop();
}
public class SineGenerator : IWaveProvider
{
private WaveFormat waveFormat;
private int sample;
public SineGenerator()
: this(44100, 1)
{
Frequency = 1000;
Amplitude = 0.25f;
}
public float Frequency { get; set;}
public float Amplitude { get; set; }
public SineGenerator(int sampleRate, int channels)
{
SetWaveFormat(sampleRate, channels);
}
public void SetWaveFormat(int sampleRate, int channels)
{
this.waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channels);
}
public int Read(byte[] buffer, int offset, int count)
{
WaveBuffer waveBuffer = new WaveBuffer(buffer);
int samplesRequired = count / 4;
int samplesRead = this.Read(waveBuffer.FloatBuffer, offset / 4, samplesRequired);
return samplesRead * 4;
}
public int Read(float[] buffer, int offset, int sampleCount)
{
int sampleRate = WaveFormat.SampleRate;
int channels = WaveFormat.Channels;
double p = 2.0 * Math.PI / channels * Frequency;
for (int n = 0; n < sampleCount; n += channels)
{
float value = (float)(Amplitude * Math.Sin((sample * p) / sampleRate));
var b = Convert.ToByte((value + 0.5) * 255);
value = (float)b / 255;
for (int c = 0; c < channels; c++)
{
buffer[n + offset + c] = value;
}
sample += channels;
if (sample == int.MaxValue) sample = 0;
}
return sampleCount;
}
public WaveFormat WaveFormat
{
get { return waveFormat; }
}
}
See also this thread for more solutions.