Naudio:听不到声音
Posted
技术标签:
【中文标题】Naudio:听不到声音【英文标题】:Naudio: No audible sound 【发布时间】:2019-06-27 10:59:57 【问题描述】:我已尝试按照此处的教程进行操作:https://markheath.net/post/fire-and-forget-audio-playback-with ,出于我的目的对其进行了一些修改,但我无法从扬声器中听到任何声音。
我也尝试直接使用教程的代码也没有成功。然而,我知道我使用的声音文件是有效的,因为我可以通过其他播放器读取它。
这是我修改后的代码:
public class AudioPlaybackEngine : IDisposable
private readonly IWavePlayer outputDevice;
private readonly MixingSampleProvider mixer;
public readonly WaveFormat Format;
public AudioPlaybackEngine(int sampleRate = 44100, int channelCount = 2)
WaveOutEvent waveOutEvent = new WaveOutEvent();
outputDevice = waveOutEvent;
Format = WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channelCount);
mixer = new MixingSampleProvider(Format);
mixer.ReadFully = true;
waveOutEvent.DeviceNumber = -1;
Logger.writeLine("Selected sound device : " + waveOutEvent.DeviceNumber, "AudioPlaybackEngine");
outputDevice.Init(mixer);
outputDevice.Play();
public float MasterVolume
get return outputDevice.Volume;
set outputDevice.Volume = value;
/// <summary> Only use this if you want to play a sound a single time (not cached) </summary>
public void PlaySound(string fileName)
var input = new AudioFileReader(fileName);
AddMixerInput(new AutoDisposeFileReader(input));
private ISampleProvider ConvertToRightChannelCount(ISampleProvider input)
if (input.WaveFormat.Channels == mixer.WaveFormat.Channels)
return input;
if (input.WaveFormat.Channels == 1 && mixer.WaveFormat.Channels == 2)
return new MonoToStereoSampleProvider(input);
throw new NotImplementedException("Not yet implemented this channel count conversion");
/// <summary> Play new sounds here using new SoundInstance(cachedSound) </summary>
public void PlaySoundInstance(ISampleProvider soundInstance)
AddMixerInput(soundInstance);
public void StopSoundInstance(ISampleProvider soundInstance)
mixer.RemoveMixerInput(soundInstance);
private void AddMixerInput(ISampleProvider input)
mixer.AddMixerInput(ConvertToRightChannelCount(input));
private void RemoveMixerInput(ISampleProvider input)
mixer.RemoveMixerInput(input);
public void Dispose()
outputDevice.Dispose();
public static readonly AudioPlaybackEngine Instance = new AudioPlaybackEngine(44100, 2);
public class CachedSound
public float[] AudioData get; private set;
public WaveFormat WaveFormat get; private set;
public CachedSound(string audioFileName)
AudioFileReader afr = new AudioFileReader(audioFileName);
WaveToSampleProvider wts = new WaveToSampleProvider(new MediaFoundationResampler(new SampleToWaveProvider(afr), AudioPlaybackEngine.Instance.Format));
int samplesRead;
var wholeFile = new List<float>((int)(afr.Length / 4));
var readBuffer= new float[wts.WaveFormat.SampleRate * wts.WaveFormat.Channels];
while((samplesRead = wts.Read(readBuffer,0,readBuffer.Length)) > 0)
wholeFile.AddRange(readBuffer.Take(samplesRead));
WaveFormat = wts.WaveFormat;
AudioData = wholeFile.ToArray();
/// <summary> Class using a cached buffer as data and providing access to volume </summary>
public class SoundInstance : ISampleProvider
public readonly CachedSound cachedSound;
public long Position = 0;
public float Volume = 1f;
public bool LoopingEnabled = true;
public bool StopASAP = false;
public SoundInstance(CachedSound cachedSound)
this.cachedSound = cachedSound;
public int Read(float[] buffer, int offset, int count)
int totalBytesRead = 0;
while (totalBytesRead < count)
if (StopASAP)
return 0;
// we have reached the end of the file
if (cachedSound.AudioData.Length == Position)
if (LoopingEnabled)
Position = 0; // reset position if looping enabled
else
return totalBytesRead; // otherwise, stop reading.
// copy data
buffer[totalBytesRead + offset] = cachedSound.AudioData[Position] * Volume;
++Position;
++totalBytesRead;
return totalBytesRead;
public WaveFormat WaveFormat get return cachedSound.WaveFormat;
// This class automatically disposes the file reader that it contains.
class AutoDisposeFileReader : ISampleProvider
private readonly AudioFileReader reader;
private bool isDisposed;
public AutoDisposeFileReader(AudioFileReader reader)
this.reader = reader;
this.WaveFormat = reader.WaveFormat;
public int Read(float[] buffer, int offset, int count)
if (isDisposed)
return 0;
int read = reader.Read(buffer, offset, count);
if (read == 0)
reader.Dispose();
isDisposed = true;
return read;
public WaveFormat WaveFormat get; private set;
public class SoundManager
private Dictionary<string, CachedSound> _soundsInMemory = new Dictionary<string, CachedSound>();
private List<SoundInstance> _soundsInstances = new List<SoundInstance>();
public SoundManager()
public void unloadSound(string soundName)
if (_soundsInMemory.ContainsKey(soundName))
_soundsInMemory.Remove(soundName);
public void loadSound(string soundName, string fileName)
_soundsInMemory.Add(soundName, new CachedSound(fileName));
public CachedSound getLoadedSound(string soundName)
if (_soundsInMemory.ContainsKey(soundName))
return _soundsInMemory[soundName];
return null;
public SoundInstance createSoundInstance(string soundName, float volume = 1f, bool enableLooping = true)
SoundInstance sound = new SoundInstance(getLoadedSound(soundName));
sound.Volume = volume;
sound.LoopingEnabled = enableLooping;
//_soundsInstances.Add(sound);
return sound;
这是我现在开始声音的方式:
SoundManager sm = new SoundManager();
string soundName = "test";
sm.loadSound(soundName, "sounds/1.wav");
SoundInstance si = sm.createSoundInstance(soundName);
AudioPlaybackEngine.Instance.PlaySoundInstance(si);
有趣的是,我可以看到绿色条在 Windows 的“音量混合器”中上下移动,但“设置”面板->“扬声器的音量”中没有显示任何内容(而其他播放器应用程序确实在此处显示了一些内容)最后一个面板)。
请帮忙?
【问题讨论】:
目前看来音量设置为 1f。您可以将其设置为更高的值,例如 50 或 100f 吗? 我尝试将其修改为 100f,但我的扬声器也没有任何输出,尽管事实上“音量混合器”似乎为我的应用程序显示了一个完全饱和的绿色条。 “设置面板”中仍然没有任何内容,并且没有声音。 【参考方案1】:解决办法是去掉:
̶p̶u̶b̶l̶i̶c̶ ̶s̶t̶a̶t̶i̶c̶ ̶r̶e̶a̶d̶o̶n̶l̶y̶ ̶A̶u̶d̶i̶o̶P̶l̶a̶y̶b̶a̶c̶k̶E̶n̶g̶i̶n̶e̶ ̶I̶n̶s̶t̶a̶n̶c̶e̶ ̶=̶ ̶n̶e̶w̶ ̶A̶u̶d̶i̶o̶P̶l̶a̶y̶b̶a̶c̶k̶E̶n̶g̶i̶n̶e̶(̶4̶4̶1̶0̶0̶,̶ ̶2̶)̶;̶
并且在同一个线程中实例化它,而不是调用 PlaySound()。
【讨论】:
以上是关于Naudio:听不到声音的主要内容,如果未能解决你的问题,请参考以下文章