我想在不从文件加载/流式传输的情况下播放响铃警报。
我可以在代码中嵌入它的信号或音调吗?我正在使用NAudio
.
我的目的是通过删除 IO 操作来提高性能。
我不想使用嵌入式资源。只有我想在代码中生成响铃警报。
使用 NAudio,您可以使用以下选项来执行此操作:
System.Media.SoundPlayer
就足够了)。play
第一种情况的示例来自 MSDN 上的Charles Petzold文章(但也请查看NAudio 文档):
class SineWaveOscillator : WaveProvider16 {
double phaseAngle;
public SineWaveOscillator(int sampleRate):
base(sampleRate, 1) {
}
public double Frequency { set; get; }
public short Amplitude { set; get; }
public override int Read(short[] buffer, int offset,
int sampleCount) {
for (int index = 0; index < sampleCount; index++) {
buffer[offset + index] =
(short)(Amplitude * Math.Sin(phaseAngle));
phaseAngle +=
2 * Math.PI * Frequency / WaveFormat.SampleRate;
if (phaseAngle > 2 * Math.PI)
phaseAngle -= 2 * Math.PI;
}
return sampleCount;
}
}
然后播放音调的代码很简单:
SineWaveOscillator osc = new SineWaveOscillator(44100);
osc.Frequency = 440;
osc.Amplitude = 8192;
WaveOut waveOut = new WaveOut();
waveOut.Init(osc);
waveOut.Play();
对于第二种情况(播放一串 MIDI 命令),请再次查看Charles Petzold 的另一篇文章。他的MidiStringPlayer
课程提供了你需要的一切(但你可能需要去掉 WPF 代码才能在你想要的地方使用它)。使用 NAudio 播放 MIDI 的基本代码是:
using (MidiOut midiOut = new MidiOut(0))
{
midiOut.Send(MidiMessage.StartNote(60, 127, 0).RawData);
Thread.Sleep(1000);
midiOut.Send(MidiMessage.StopNote(60, 0, 0).RawData);
Thread.Sleep(1000);
}
如果您确实需要从字符串中播放音符,那么您必须对其进行解析,代码太长,无法在此处发布,但在链接中您会找到所有内容。
对于 NAudio 解决方案看起来像这样
Test.Properties.Resources.aaa 这是 mp3 的路径
using (var ms = new MemoryStream(Test.Properties.Resources.aaa))
using (var rdr = new NAudio.Wave.Mp3FileReader(ms))
using (var wavStream = NAudio.Wave.WaveFormatConversionStream.CreatePcmStream(rdr))
using (var baStream = new NAudio.Wave.BlockAlignReductionStream(wavStream))
using (var waveOut = new NAudio.Wave.WaveOut(NAudio.Wave.WaveCallbackInfo.FunctionCallback())) {
waveOut.Init(baStream);
waveOut.Play();
while (waveOut.PlaybackState == NAudio.Wave.PlaybackState.Playing) {
System.Threading.Thread.Sleep(100);
}
}
您可以通过将任何类型的文件添加到资源中来将其嵌入到您的项目中。
在 Visual Studio 中,您可以通过资源 --> 添加资源 --> 添加现有文件来执行此操作。
在我的例子中,我将资源文件命名为 mySound。
SoundPlayer
然后您可以通过添加以资源为参数的文件来打开文件。
例如
SoundPlayer mysoundplayer = new SoundPlayer(MyAssemblyName.Properties.Resources.mySound);
mysoundplayer.Play();