WPF声音可视化库WaveformTimeline控件RegisterSoundPlayer传参问题
需求说明
导入音频文件后,使用Sound Visualization Library的WaveformTimeline控件展示对应音频波形。
当前已编写的基础音频加载逻辑代码如下:
string[] files = open.FileNames; foreach (string file in files) { wave = new NAudio.Wave.WaveFileReader(file); output = new NAudio.Wave.DirectSoundOut(); output.Init(new NAudio.Wave.WaveChannel32(wave)); output.Pause(); WaveformPlot.BeginInit(); WaveformPlot = new WaveformTimeline(); WaveformPlot.RegisterSoundPlayer(); }
现存问题
功能开发接近完成时,无法确定RegisterSoundPlayer()方法的传入参数。查阅官方文档、源码及历史参考资料后,已知该方法需要传入播放器实例,但参考资料中的API命名与当前库版本存在差异,无法直接适配。
可行解决方案
新版Sound Visualization Library的RegisterSoundPlayer()方法仅接受实现了库内置ISoundPlayer接口的实例作为参数,当前使用的NAudio原生DirectSoundOut类未实现该接口,无法直接传入,按以下步骤调整即可:
- 优先使用库内置的NAudio适配包装类
最新版Sound Visualization Library已经提供了NAudioSoundPlayer包装类,该类已经实现了ISoundPlayer接口,直接用它包装初始化好的DirectSoundOut实例传入即可,修正后的核心代码如下:string[] files = open.FileNames; foreach (string file in files) { var wave = new NAudio.Wave.WaveFileReader(file); var output = new NAudio.Wave.DirectSoundOut(); output.Init(new NAudio.Wave.WaveChannel32(wave)); output.Pause(); WaveformPlot.BeginInit(); WaveformPlot = new WaveformTimeline(); // 包装NAudio播放器实例后传入 var adaptedPlayer = new NAudioSoundPlayer(output); WaveformPlot.RegisterSoundPlayer(adaptedPlayer); // 补全缺失的EndInit调用,否则控件无法正常完成初始化 WaveformPlot.EndInit(); // 记得将初始化完成的WaveformPlot添加到界面对应布局容器中 } - 若当前版本无内置适配类,自行实现接口适配
如果使用的库版本找不到NAudioSoundPlayer类,自行编写一个类实现ISoundPlayer接口,将接口定义的播放、暂停、跳转、获取当前播放位置、获取音频总时长等成员,分别映射到DirectSoundOut和WaveFileReader的对应方法、属性即可,逻辑简单,不需要额外复杂处理。
额外注意事项
- 控件初始化必须成对调用
BeginInit()和EndInit(),原代码缺失EndInit()调用会导致波形渲染异常。 - 如果已经在XAML中声明了
WaveformTimeline控件,不要在后台代码中重复new新的实例,否则后台操作的控件实例和界面挂载的实例不是同一个,无法看到波形展示。
内容的提问来源于stack exchange,提问作者robert
相关产品推荐
相关产品推荐

