4 posts tagged “bass api”
In the absence of my coding articles I have created a starter kit for creating audio-visuals with the Bass.NET API. With this starter kit you will be able to have a nice starting point to work with Bass and different audio-visual techniques. The kit, once installed, can be run by hitting F5. You can immediately load up any of your favorite songs or a simple Shoutcast playlist. In a few of my future articles I will introduce some techniques for creating audio-visuals including: bars, waves and ambient lighting. Let's take a quick look at Adosi from where it stands.
Make sure that you have the following requirements before installing:
The Player
When you first start the program you will notice some of the interaction and animation touches that have been made. The entire interface has been designed so that when any audio-visual is added, any one of the components can be apart of the addition. There isn't much to it at this point, but we can however use it as a nice starting point. Let's go ahead and start modifying it. We are going to attempt to wire the bars-visual to the actual music.
Bars Audio-Visual
Before we can create our own audio-visual, we must first understand how most audio-visuals actually work. The idea is based on tracking two distinct variables in all audio: frequency and amplitude. In our case, to create an equalizer all we need to do is average amplitude values into a number of sections. The Bass api contains a simple method for obtaining all this data in the following snippet:
The first parameter refers to audio stream handle (known whenever you create a new channel stream) while the second parameter should be the buffer array created to hold the data itself. It's usually best to use a float array here but you can place doubles, bytes, ints or an IntPtr. The last parameter is the length of the data to receive from the stream. The best place to determine this amount is by using the following snippet:Bass.BASS_ChannelGetData(handle, buffer, length);
All you need to do to create the equalizer is create averages for the number of bars you want. Go ahead and check out the download for the completed version of the equalizer in my modifications below. The equalizer is the easiest to create, so in the future we'll have to get a little more serious in our visualizations.BASSData.BASS_DATA_FFT2048
- you can use any of the given values in the enumeration. Note the actual length in the comments (where 2048 FFT actually refers to 1024 allocated to a single buffer.
Internet radio, a phenomena that appeared in the early 90's that soon made it's way to it's grand stature today. Sure politics are trying to destroy it, but it's not going away any time soon. There is a great deal of history in Internet Radio from war protests to social networking. The latest advent in internet radio, Pandora, from the Music Genome Project, combines the analysis of each song to provide users the ability to listen to similar music; thus creating their own stations based on style, rhythms, lyrics and more. Nevertheless, I suggest you review the history on Wikipedia. I believe the next step in Internet Radio is playing from your mobile phone which doesn't seem that far off. [note project]
At any rate, our little music player doesn't seem to support internet radio at all. Well, I simply won't have that! Especially because supporting internet streams is so very simple with the Bass.NET api. In this tutorial you will learn to accomplish the following:
- Play streaming audio from an internet radio station.
- Visual C# Express (sorry, Visual C# Express 2005 is no longer available)
- Bass.NET 2.3 (scroll down until you find the .NET 2.0 link)
- Un4seen Bass api (top download link for Windows)
I am going to create a new Windows Form project called MyRadio. To start, you will need to add the reference to the Bass.NET api. Then copy the bass.dll to your output directory by including it in your project followed by setting the Copy to Output Directory property to Copy if newer. Your solution explorer should look like the following:
Once you have that setup look for the Player code from the previous tutorial. If you can't find it, you will find the code layout here.
We are going to modify this class to support internet radio streams. Open up the Player class and add the following code snippet.
public void LoadURL(string url)
{
stream = Bass.BASS_StreamCreateURL(url, 0,
BASSStream.BASS_SAMPLE_FLOAT, null, 0);
}
Bass provides this function for loading a stream from a url. In most cases, it won't matter if the stream is a file or a broadcasting stream; bass handles this for you.
You'll notice that this function looks a lot like our original. Except, instead of StreamCreateFile we are using StreamCreateURL. With the fourth parameter, specified as null, is a callback to the function to receive the stream as it's being downloaded. Also, the BASSStream contains a few flags that may allow us to obtain tags about the music including the title, author, genre and more. There are many flags that have a very specific purpose, but for now we are just going to use the default like in our previous case.
The only thing left for us to do is to provide access in our user interface. I have simply copied our previous UI and added a textbox to allow the url to be entered. When you're done, your user interface may look like the following.
There you go. Hit F5 type in an address to an internet radio station or an hosted song online and you should be good to go. In this tutorial you learned how to use Bass to stream internet radio. In my next tutorial I will be teaching you how to create your own playlist allowing for even more support for internet radio stations.
You will need the following requirements to complete this tutorial:
Recording from the Microphone
Recording: the process of capturing data or translating information to a format stored on a storage medium (or record). Lucky for us, analog-to-digital converters (ADC) take care of the translation for recording devices like a microphone. The only catch for us is providing a sampling rate against the analog wave. We used sampling when we streamed audio in our previous tutorial and we'll use it again here. The only difference about sampling from a recording device is that we are working with a different device. The code looks just about the same.
Setup a quick project that you can use for this tutorial. I created a new Windows Form project. You can create a whatever you like to complete the tutorial. Next, add a utility class called "RecordUtil.cs". Then add all the necessary references, make sure you set the Copy to Output Directory to "Copy if newer".
Add references
Taking a look at the left. Your solution explorer should contain the additions I mentioned before. That is:
- bass.dll
- bassenc.dll
- lame.exe
Having those in your project and output directory allows the final executing code to reference them without any issues running on different machines.
Next, we need to initialize the actual recording device. In the constructor of the RecordUtil place the following code snippet.
By initializing with the device 0, we will use the first recording device found by the Bass api.
Next, we're going to create the recording stream. You will need to set the sampling rate, the number of channels, BASSRecord flags, a callback function, and a user. The following code accomplishes this.
The first parameter is the sampling rate. This is the rate at which the analog wave is sampled (41000 times per second). The second parameter is the number of channels: 1 is mono, 2 is stereo. The third parameter is either the resolution (BASS_DEFAULT 16-bits, BASS_SAMPLE_8BITS 8-bit, BASS_SAMPLE_FLOAT - all of these choices will start the recording) BASS_RECORD_PAUSE starts the recording paused. Lastly, the fourth parameter is the callback function on each sample and the last parameter is the user associated with the recording.
Automatic versus manual recording
BASS has two methods of recording audio. When you do not specify null for the RECORDPROC callback function you must obtain the actual channel data using the BASS_ChannelGetData method. This is known as manual recording. Manual recording allows lower latency for full-duplex recording (i.e. playing the data as it's being recorded).
In an overloaded method for the BASS_RecordStart function, the third parameter is actually the period. The period defines the interval (in milliseconds) between calls to the callback function. The default is 100ms. (Minimum is 10ms, Maximum is 500ms).
If you do specify a callback to the RECORDPROC parameter, you are implementing automatic recording. All the data is obtained for you.
Then create the callback function and within the method you can simply return true. For the sake of this tutorial I will go into detail at a later post to explain the neat things you can access with the data.
LAME Encoder
In order to start recording with the parameter we chose, we need to use Channel_Play. But before we do that we are going to use the LAME encoder to stream the recording to an output file. Add the following code snippet:
I have added a field in the class called encoder. The EncoderLame class is in the Un4seen.Bass.Misc namespace. The first line simply constructs the encoder with the streaming channel (in our case the recording stream). Next, we set the OutputFile to the given path denoted output. The last lines of code are LAME specific variable configurations.
Aside from the bitrate and sample rate, Mode defines the encoding channel mode as in mono, stereo, join stereo.. etc. There are plenty of variables that you can configure, I have just configured the basics in this example. We want to sample at the same rate we created our recording channel at, use the default mode, encode according to quality, and have our bitrate at 192kbps (kilobits/sec).
Next, I have added four methods to handle different states in our recording program. They start out as the following:
The code here is pretty straight forward. When we call encoder.Start(null, 0) we are passing it a callback function and the associated user. The callback function allows us to work the encoding byte stream at each interval ourselves. This is very useful for us when we want to send the stream elsewhere like over a network.
The only thing left for us to do in this class is add the code for the Bass.Channel functions like we did in the previous tutorial on streaming audio. When you have that part done the final code should look like the following.
And there you go, the only missing piece is creating an interface the utilize this nice little recording utility. I've thrown a simple interface together to demonstrate this. When you're done with yours simply call the appropriate functions in the order: constructor, Initialize, Encode (with the output file), and setup a play, pause, and stop function.
Once you have your interface ready, you can make the calls to the functions you just created. When you're done your code should look something like the following code snippet.
Source code
There are plenty of instances where playing sounds, music or virtually anything else sound related is an absolute necessity. The problem, however, is the availability in C#.NET is limited. Fear not, I have a solution!
The following post introduces the BASS.NET Api for streaming sound. In this tutorial you will learn how to:
- Load Mp3 files and play them
- Visual C# Express (sorry, Visual C# Express 2005 is no longer available)
- Bass.NET 2.3 (scroll down until you find the .NET 2.0 link)
- Un4seen Bass api (top download link for Windows)
Within the .NET development environment the availability of playing audio is limited. For one, the SoundPlayer that ships with the .NET framework will currently work with wav files (understandable because of license agreements). Once more with WMA you have to use the Windows Media Player control that ships as a Com object. Nevertheless, there are altenatives. As stated on there website:
BASS is an audio library for use in Windows and Mac OSX software. Its purpose is to provide developers with powerful and efficient sample, stream (MP3, MP2, MP1, OGG, WAV, AIFF, custom generated, and more via add-ons), MOD music (XM, IT, S3M, MOD, MTM, UMX), MO3 music (MP3/OGG compressed MODs), and recording functions. All in a tiny DLL, under 100KB* in size.
On Windows, BASS requires DirectX 3 or above for output, and takes advantage of DirectSound and DirectSound3D hardware accelerated drivers, when available. On OSX, BASS uses CoreAudio for output, and OSX 10.3 or above is recommended. Both PowerPC and Intel Macs are supported.
If you have everything downloaded and installed in order then you are ready to begin. Start by creating a new windows project.I've named my project BassAudio. Right-click on your project and add the following reference.
This dll should be wherever you downloaded it to on your machine. If you forgot to download it see the third download link I mentioned above.
Next, you will want to add whatever song you like. I'm using an Mp3 song that I have on my machine. Just make sure the file will copy to the output directory.
Now that everything has been setup. We can start coding to the api.
Within the Bass api there are a number of varying things you can do with audio devices. For instance, you can work with 3D audio including velocity, position of the emitting sound, position of the listener, doppler effects... and much more.
I recommend taking a look at all that's available to you in the Un4seen.Bass.Bass functions. The nice part is that the majority of all the methods in this api are within the Bass class.
Whenever you're ready, initialize the default device with -1 for the first parameter.
The second parameter is the sampling rate. I recommend looking up the definition on either Wikipedia or HowStuffWorks since I'd rather not explain this part. Basically your audio device has a rate at which it can sample whatever particular input you're working with. Speakers will sample your song at such a rate, or your microphone will sample the audio coming in at such a rate. 44100 is just about the best quality for sampling you can get.
Creating the stream is pretty easy. All you have to do is call the function:
The parameters to this function are pretty much self-explanatory when you read the comments. The first is the location of the file, the second parameter is the offset to begin the streaming from, the length is how long to stream (0 is all), the last parameter is the BassStream flags. I recommend taking a look at the comments in the enumerations. They are all very helpful.
Note: When you work with unmanaged code, you have to be sure you save your references; otherwise, the .NET garbage collector will destroy the reference. To do this, I've simply placed the int stream at the top of the class.
Add a PlaySong, StopSong, and a destructor to your Player class.
The destructor in this class makes sure that all the resources are let go from the unmanaged part of the bass api. Okay, now that we have a simple player setup, let's actually use it! :D
By the end of your form you might have something like this:
And there you have it. Hit F5, load your song and click play. You should now be hearing you song.
In this tutorial you learned how to use an alternative sound api to stream sound to a audio device of your choosing. You figured out what sampling meant and you created a nice reusable sound player. In the my next audio tutorial, I'll show you how to use BASS to show a list of all your audio devices. Then we'll get into some microphone recording later on. Leave and questions and comments here if you like.