Namespace: Un4seen.Bass
Assembly: Bass.Net (in Bass.Net.dll) Version: 2.4.17.2
Parameters
- buffer
- Type: SystemIntPtr
The pointer to the buffer containing the downloaded data... Zero = finished downloading. - length
- Type: SystemInt32
The number of bytes in the buffer... 0 = HTTP or ICY tags. - user
- Type: SystemIntPtr
The user instance data given when BASS_StreamCreateURL(String, Int32, BASSFlag, DOWNLOADPROC, IntPtr) was called.
The callback will be called before the BASS_StreamCreateURL(String, Int32, BASSFlag, DOWNLOADPROC, IntPtr) call returns (if it's successful), with the initial downloaded data. So any initialization (eg. creating the file if writing to disk) needs to be done either before the call, or in the callback function.
When the BASS_STREAM_STATUS flag is specified in the BASS_StreamCreateURL(String, Int32, BASSFlag, DOWNLOADPROC, IntPtr) call, HTTP and ICY tags may be passed to the callback during connection, before any stream data is received. The tags are given exactly as would be returned by BASS_ChannelGetTags(Int32, BASSTag). You can destinguish between HTTP and ICY tags by checking what the first string starts with ("HTTP" or "ICY").
A download callback function could be used in conjunction with a BASS_SYNC_META sync set via BASS_ChannelSetSync(Int32, BASSSync, Int64, SYNCPROC, IntPtr), to save individual tracks to disk from a Shoutcast stream.
NOTE: When you pass an instance of a callback delegate to one of the BASS functions, this delegate object will not be reference counted. This means .NET would not know, that it might still being used by BASS. The Garbage Collector might (re)move the delegate instance, if the variable holding the delegate is not declared as global. So make sure to always keep your delegate instance in a variable which lives as long as BASS needs it, e.g. use a global variable or member.
private FileStream _fs = null; private DOWNLOADPROC _myDownloadProc; private byte[] _data; // local data buffer ... _myDownloadProc = new DOWNLOADPROC(MyDownload); int stream = Bass.BASS_StreamCreateURL("http://www.asite.com/afile.mp3", 0, BASSFlag.BASS_DEFAULT, _myDownloadProc, IntPtr.Zero); ... private void MyDownload(IntPtr buffer, int length, IntPtr user) { if (_fs == null) { // create the file _fs = File.OpenWrite( "output.mp3" ); } if (buffer == IntPtr.Zero) { // finished downloading _fs.Flush(); _fs.Close(); } else { // increase the data buffer as needed if (_data == null || _data.Length < length) _data = new byte[length]; // copy from managed to unmanaged memory Marshal.Copy(buffer, _data, 0, length); // write to file _fs.Write( _data, 0, length ); } }
// within your download callback method... // assuming you have created a: BinaryWriter bw = new BinaryWriter(_fs); unsafe { // simply cast the given IntPtr to a native pointer to short values // assuming you receive 16-bit sample data here short *data = (short*)buffer; for (int a = 0; a < length/2; a++) { // write the received sample data to a local file bw.Write( data[a] ); } }