Sections

1. Introduction / The Sound Player

The WPFSVL makes a certain assumption about your application’s architecture. It assumes you’ll have some object, somewhere, that is in charge of monitoring audio playback. It also assumes you’ll be able to extend or wrap this object so
that it can implement certain interfaces that the WPFSVL can make use of. Since .NET is object-oriented, this is probably how you’re already controlling your audio playback, so it shouldn’t be much of a stretch. With regard to BASS.NET, most users
end up wrapping BASS.NET’s calls into some more object-oriented structure. In order to use WPFSVL, you’ll need to do the same.

All of the logic mentioned in this guide can be found in the samples included with the source code. I’ll do my best to keep this guide up to date, but I encourage you all to take a close look at that source code for the most up-to-date versions of
SoundPlayer implementation for BASS.NET.

It should also be noted that not ALL of the controls in the WPFSVL need a sound player object. Only the ones that have a method named
RegisterSoundPlayer() will require a sound player object.

2. Sound Player Basic Requirements (Property Change Notification)

All of the controls that need a Sound Player object will also require two things. 1.) The sound player must implement
INotifyPropertyChanged so the controls can be notified when something changes. 2.) The sound player must have an
IsPlaying property so the controls can know when sound is playing. Internally,
IsPlaying is used to stop animation timers and rendering loops when sound isn’t playing. Without it, some controls like the Spectrum Analyzer would cause the application to use a fair amount of processing power even while your sound application
idles and does nothing. Putting that together, you’ll end up a class scaffolding that looks like the code below.

An alternative way you may consider implementing
INotifyPropertyChanged is to make your sound player a
DependencyObject and implement the required properties as
DependencyProperties. I chose *not* to do that here because many of you will be implementing your sound player in an assembly that is separate from your presentation code and references. However, if your sound player is in the same assembly as your
UI, the
DependencyObject route may suit you well.

3. Basic Audio Playback

Chances are, if you’re here, you probably already have some sort of sound playback in your application and you’re just looking for ways to include some neat visualizations. My hope is that you won’t need to change anything too drastically
to make it work with the WPFSVL controls. That said, if you don’t already have a sound playback engine, are interested in seeing how I personally implemented one, or want some more information on why I implemented things the ways I did then this is the
section for you. Again, remember this is only my personal implementation of a sound player and you’re free to implement a sound player however you would like.

The first thing I know about my sound player is that I only need one of them. That is to say, I’m not going to be playing multiple files at the same time so I only need to be processing one sound stream at time. Only one stream means only one sound
player. As such, I’m going to use the
Singleton Pattern to ensure that only one instance of my sound player is ever instantiated. We’ll build on my code from section 2 with the code below.

We need to provide the basic file opening structure so we can open a file and start playing it.

We need to provide the right kind of public properties and methods from which the UI can control the playback.

Thus, take the code below and add it to the code you already have in the
BassEngine class. The normal flow would have the user calling OpenFile() and passing it a path, presumably through a “File > Open” dialog or something similar. Once passing it a valid path, we’ll mark
CanPlay as true. At this point, the user could call Play() (through something like a Play button). Pressing Play would, in turn, make the
Stop() and Pause() commands available through the
CanStop and CanPause properties respectively. Since
CanStop and CanPause will raise property changed notification, it is a great idea to bind button’s
IsEnabled properties in your UI to these properties.

4. Spectrum Analyzer Support

If you’ve done everything above, we’re very close to having support for the Spectrum Analyzer. The spectrum analyzer requires a few things of the sound player.

A mechanism to get FFT data that has been translated to real intensity values (i.e., it has already calculated out the imaginary values).

A way to know which value in the FFT array corresponds with a particular frequency.

The sound player must be marked indicating it has support for the Spectrum Analyzer. This is done by inheriting the
ISpectrumPlayer interface.

Luckily, BASS.NET makes the calculations in the first two requirements fairly trivial. We will, however, need to provide some information to BASS. First, we need to know the sample rate of the file we’re listening to. This is because the maximum frequency
of the song will be half of the sample rate. In other words, a file with a sample rate of 44.1 kHz will have a maximum frequency of 22.05kHz. To obtain the sample rate, we’ll add a little bit of code to the
OpenFile() method we wrote above. Unlike many other libraries, the rest of the sampling logic is taken care of for us, as is the FFT formula. Add the following code:

We’ve added the two methods required by ISpectrumPlayer,
GetFFTFrequencyIndex() and GetFFTData(). Now we should be able to add a Spectrum Analyzer to our Window and register the
BassEngine class as the Spectrum Analyzer’s sound player. Start with adding the actual Spectrum Analyzer control somewhere in your Window’s XAML. The sample below gives an example of referencing the WPFSVL namespace.

Would just like to say that the work you have done here is excellent. Truly impressive.

I am in the process of integrating your controls into an app i wrote to simplify my music library. I'm currently working on getting the Waveform to be displayed. If you have any documentation on this, or if you have a guest login for your TFS to see your code that would be such a huge help because I cant seem to open the samples.

Thanks again for your work, alot of time and effort must have gone into this!

I downloaded your sample and hoped to read it in VS1010. But the two integrated examples(Bass.net and NAdio) were in the tsf.codeplex.com/tsf/tsf27. I couldn't open them. So I can't learn the way you use your controls.