Namespace: Un4seen.Bass
Assembly: Bass.Net (in Bass.Net.dll) Version: 2.4.17.2
[DllImportAttribute("bass")] public static int BASS_StreamCreateFileUser( BASSStreamSystem system, BASSFlag flags, BASS_FILEPROCS procs, IntPtr user )
Parameters
- system
- Type: Un4seen.BassBASSStreamSystem
File system to use (one of the BASSStreamSystem):STREAMFILE_NOBUFFER Unbuffered. STREAMFILE_BUFFER Buffered. STREAMFILE_BUFFERPUSH Buffered, with the data pushed to BASS via BASS_StreamPutFileData(Int32, IntPtr, Int32). - flags
- Type: Un4seen.BassBASSFlag
Any combination of these flags (see BASSFlag):BASS_SAMPLE_FLOAT Use 32-bit floating-point sample data. WDM drivers or the BASS_STREAM_DECODE flag are required to use this flag in Windows. See Floating-point channels for more info. BASS_SAMPLE_MONO Decode/play the stream (MP3/MP2/MP1 only) in mono, reducing the CPU usage (if it was originally stereo). This flag is automatically applied if BASS_DEVICE_MONO was specified when calling BASS_Init(Int32, Int32, BASSInit, IntPtr, IntPtr). BASS_SAMPLE_3D Use 3D functionality. This is ignored if BASS_DEVICE_3D wasn't specified when calling BASS_Init(Int32, Int32, BASSInit, IntPtr, IntPtr). 3D streams must be mono. The SPEAKER flags can not be used together with this flag. BASS_SAMPLE_LOOP Loop the file. This flag can be toggled at any time using BASS_ChannelFlags(Int32, BASSFlag, BASSFlag). This flag is ignored when streaming in blocks (BASS_STREAM_BLOCK). BASS_STREAM_PRESCAN Enable pin-point accurate seeking (to the exact byte) on the MP3/MP2/MP1 stream. This also increases the time taken to create the stream, due to the entire file being pre-scanned for the seek points. This flag is ignored with "buffered" streams (buffered=). BASS_STREAM_RESTRATE Restrict the download rate of the file to the rate required to sustain playback. If this flag is not used, then the file will be downloaded as quickly as possible. This flag has no effect on "unbuffered" streams (buffered=). BASS_STREAM_BLOCK Download and play the file in smaller chunks. Uses a lot less memory than otherwise, but it's not possible to seek or loop the stream - once it's ended, the file must be opened again to play it again. This flag will automatically be applied when the file length is unknown. This flag also has the effect of resticting the download rate. This flag has no effect on "unbuffered" streams (buffered=). BASS_STREAM_AUTOFREE Automatically free the stream when it ends. This allows you to stream a file and forget about it, as BASS will automatically free the stream's resources when it has reached the end or when BASS_ChannelStop(Int32) (or BASS_Stop) is called. BASS_STREAM_DECODE Decode the sample data, without outputting it. Use BASS_ChannelGetData(Int32, IntPtr, Int32) to retrieve decoded sample data. The BASS_SAMPLE_SOFTWARE, BASS_SAMPLE_3D, BASS_SAMPLE_FX, BASS_STREAM_AUTOFREE and SPEAKER flags can not be used together with this flag. BASS_SPEAKER_xxx Speaker assignment flags. BASS_ASYNCFILE Read the file asynchronously. When enabled, the file is read and buffered in parallel with the decoding, to reduce the chances of the decoder being affected by I/O delays. This can be particularly useful with slow storage media and/or low latency output. The size of the file buffer is determined by the BASS_CONFIG_ASYNCFILE_BUFFER config option. This flag only applies when using the STREAMFILE_NOBUFFER system. - procs
- Type: Un4seen.BassBASS_FILEPROCS
The user defined file function (see BASS_FILEPROCS). - user
- Type: SystemIntPtr
User instance data to pass to the callback functions.
Return Value
Type: Int32If successful, the new stream's handle is returned, else 0 is returned. Use BASS_ErrorGetCode to get the error code.
The buffered file system (STREAMFILE_BUFFER) is what is used by BASS_StreamCreateURL(String, Int32, BASSFlag, DOWNLOADPROC, IntPtr). As the name suggests, data from the file is buffered so that it is readily available for decoding; BASS creates a thread dedicated to 'downloading' the data. This is ideal for when the data is coming from a source that has high latency, like the internet. It is not possible to seek in buffered file streams, until the download has reached the requested position; it is not possible to seek at all if it is being streamed in blocks. When streaming in blocks, it may be possible to reset the stream via BASS_ChannelSetPosition(Int32, Int64, BASSMode) with the BASS_POS_RESET flag, so that it is ready to process new data.
The push buffered file system (STREAMFILE_BUFFERPUSH) is the same, except that instead of the file data being pulled from the FILEREADPROC function in a "download" thread, the data is pushed to BASS via BASS_StreamPutFileData(Int32, IntPtr, Int32). A FILEREADPROC function is still required, to get the initial data used in the creation of the stream (see example below).
The unbuffered file system (STREAMFILE_NOBUFFER) is what is used by BASS_StreamCreateFile(String, Int64, Int64, BASSFlag). In this system, BASS does not do any intermediate buffering - it simply requests data from the file as and when it needs it. This means that reading (FILEREADPROC) must be quick, otherwise the decoding will be delayed and playback buffer underruns (old data repeated) are a possibility. It's not so important for seeking (FILESEEKPROC) to be fast, as that is generally not required during decoding, except when looping a file.
In all cases, BASS will automatically stall playback of the stream when insufficient data is available, and resume it when enough data does become available.
A copy is made of the procs callback function table, so it does not have to persist beyond this function call. This means it is not required to pin the procs instance, but it is still required to keep a reference as long as BASS uses the callback delegates in order to prevent the callbacks from being garbage collected.
ERROR CODE | Description |
---|---|
BASS_ERROR_INIT | BASS_Init(Int32, Int32, BASSInit, IntPtr, IntPtr) has not been successfully called. |
BASS_ERROR_NOTAVAIL | Only decoding channels (BASS_STREAM_DECODE) are allowed when using the "no sound" device. The BASS_STREAM_AUTOFREE flag is also unavailable to decoding channels. |
BASS_ERROR_ILLPARAM | system is not valid. |
BASS_ERROR_FILEFORM | The file's format is not recognised/supported. |
BASS_ERROR_UNSTREAMABLE | The file cannot be streamed using the buffered file system. This could be because an MP4 file's 'mdat' atom comes before its 'moov' atom. |
BASS_ERROR_NOTAUDIO | The file does not contain audio, or it also contains video and videos are disabled. |
BASS_ERROR_CODEC | The file uses a codec that's not available/supported. This can apply to WAV and AIFF files, and also MP3 files when using the "MP3-free" BASS version. |
BASS_ERROR_FORMAT | The sample format is not supported by the device/drivers. If the stream is more than stereo or the BASS_SAMPLE_FLOAT flag is used, it could be that they are not supported. |
BASS_ERROR_SPEAKER | The specified SPEAKER flags are invalid. The device/drivers do not support them, they are attempting to assign a stereo stream to a mono speaker or 3D functionality is enabled. |
BASS_ERROR_MEM | There is insufficient memory. |
BASS_ERROR_NO3D | Could not initialize 3D support. |
BASS_ERROR_UNKNOWN | Some other mystery problem! |
Platform-specific
Away from Windows, all mixing is done in software (by BASS), so the BASS_SAMPLE_SOFTWARE flag is unnecessary. The BASS_SAMPLE_FX flag is also ignored.
On Windows and Windows CE, ACM codecs are supported with compressed WAV files. Media Foundation codecs are also supported on Windows 7 and updated versions of Vista, including support for AAC/MP4 and WMA. On iOS and OSX, CoreAudio codecs are supported, adding support for any file formats that have a codec installed. Media Foundation and CoreAudio codecs are only tried after the built-in decoders and any plugins have rejected the file.
void Connect() { bufferobj = new Buffer(); stream = BASS_StreamCreateFileUser(STREAMFILE_BUFFERPUSH, ...); lock { BASS_StreamPutFileData(stream, ...); // feed remaining buffered data bufferobj = NULL; // don't need the buffer anymore } } void OnReceiveData(pointer buffer, int length) { lock { if (bufferobj) bufferobj.Write(buffer, length); else BASS_StreamPutFileData(stream, buffer, length); } } int FileReadProc(pointer buffer, int length, pointer user) { int todo = length; while (TRUE) { lock { done = bufferobj.Read(buffer, todo); } buffer += done; // move pointer todo -= done; if (todo == 0) break; if (!bufferobj.WaitForData(timeout)) // wait for more data break; // timed-out (or perhaps EOF) } return length - todo; }