Author Topic: Taking a mixer handle in another app  (Read 531 times)

Chris Oakley

  • Posts: 201
Taking a mixer handle in another app
« on: 29 Jul '22 - 10:27 »
Quick question - is it possible to use the id created by a mixer stream, in another application which is using BASS?

Ian @ un4seen

  • Administrator
  • Posts: 24589
Re: Taking a mixer handle in another app
« Reply #1 on: 29 Jul '22 - 14:16 »
No, the BASS handles are all process-specific, so it isn't possible to share them between multiple processes/apps. It is possible to transfer sample data (and other data) between processes though, eg. using pipes or sockets.

Chris Oakley

  • Posts: 201
Re: Taking a mixer handle in another app
« Reply #2 on: 29 Jul '22 - 15:01 »
Ahh that's interesting. Thanks Ian.

Chris Oakley

  • Posts: 201
Re: Taking a mixer handle in another app
« Reply #3 on: 29 Jul '22 - 19:17 »
Is there a tutorial or document that can assist with PCM data and sockets? I did try implementing something like this a few years back but had trouble with keeping the audio flow consistent.

Ian @ un4seen

  • Administrator
  • Posts: 24589
Re: Taking a mixer handle in another app
« Reply #4 on: 1 Aug '22 - 13:18 »
Unfortunately, I'm not aware of any such tutorials/documents, and it isn't something I've tried myself, but I guess it would basically be a server/client system, so you could look for some general examples of that. What did you try last time?

You would use BASS_StreamCreate to play the PCM data on the client-side. You could use either of the pull (STREAMPROC callback) or push (BASS_StreamPutData) mechanisms. If you use the former then the socket should be non-blocking, so that the STREAMPROC doesn't wait when there's no data.

Chris Oakley

  • Posts: 201
Re: Taking a mixer handle in another app
« Reply #5 on: 6 Aug '22 - 21:23 »
Sadly I don't have the code from last time, it was a small project I was tinkering with. I've written some new code and it's almost right, but the audio isn't either going out right or coming in right. I've stripped the process back to basics to see what I'm not understanding. So in the below code I've opened the file as a decode and then I'm wanting to push that to the push stream. The reason I want to do this of course if because I want to push the data across sockets. But until I get it playing properly like this, then it's never going to work on sockets.

Code: [Select]

    Private WithEvents bkgWorker As New BackgroundWorker With {.WorkerReportsProgress = True, .WorkerSupportsCancellation = True}

    Private Sub LoadFile()
        Dim _file As String = "d:\temp\2295.mp3" 'The file to load
        Bass.BASS_Init(0, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero) 'Initialise no sound device
        _stream = Bass.BASS_StreamCreateFile(_file, 0, 0, BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_SAMPLE_LOOP) 'Load a file and play it on loop
        Bass.BASS_Init(1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero) 'First output device
        _playstream = Bass.BASS_StreamCreatePush(44100, 2, BASSFlag.BASS_DEFAULT, IntPtr.Zero) 'Create a push stream for the incoming data
        Bass.BASS_ChannelPlay(_playstream, False) 'Play the push stream
        bkgWorker.RunWorkerAsync() 'Start the worker
    End Sub

    Private Sub bkgWorker_DoWork(sender As Object, e As DoWorkEventArgs) Handles bkgWorker.DoWork
        Do
            Dim _length As Integer = CInt(Bass.BASS_ChannelSeconds2Bytes(_stream, 0.03)) 'The length of the buffer for 30ms
            Dim _data(CInt(_length / 2) - 1) As Short 'Hold the buffer
            _length = Bass.BASS_ChannelGetData(_stream, _data, _length) 'Get the data
            Bass.BASS_StreamPutData(_playstream, _data, CInt((_data.Length - 1) / 2) - 1) 'Push it to the push stream
            Threading.Thread.Sleep(10)
        Loop Until bkgWorker.CancellationPending
    End Sub


I have a button on the form to call LoadFile. Maybe you can see what I'm doing wrong here.

Ian @ un4seen

  • Administrator
  • Posts: 24589
Re: Taking a mixer handle in another app
« Reply #6 on: 8 Aug '22 - 12:41 »
Code: [Select]
            _length = Bass.BASS_ChannelGetData(_stream, _data, _length) 'Get the data
            Bass.BASS_StreamPutData(_playstream, _data, CInt((_data.Length - 1) / 2) - 1) 'Push it to the push stream

The BASS_StreamPutData "length" parameter is in bytes, as is the BASS_ChannelGetData return value, so you can simply use the latter for the former:

Code: [Select]
            _length = Bass.BASS_ChannelGetData(_stream, _data, _length) 'Get the data
            if (_length > 0) Bass.BASS_StreamPutData(_playstream, _data, _length) 'Push it to the push stream

Chris Oakley

  • Posts: 201
Re: Taking a mixer handle in another app
« Reply #7 on: 8 Aug '22 - 13:02 »
Okay so I'm a little confused because I'm getting the data as a Short buffer, not a Byte buffer so I'm pushing it back to the stream as a Short as well. An array of Shorts will be half the size of the same array in Bytes.

Ian @ un4seen

  • Administrator
  • Posts: 24589
Re: Taking a mixer handle in another app
« Reply #8 on: 8 Aug '22 - 17:03 »
BASS_ChannelGetData and BASS_StreamPutData don't actually know what type of array is used. They just receive a pointer to a memory address in any case, and the "length" parameters tell how much data (in bytes) is wanted/provided there.

Chris Oakley

  • Posts: 201
Re: Taking a mixer handle in another app
« Reply #9 on: 8 Aug '22 - 18:18 »
What's confused me here is there are various overloads for GetChannelData http://bass.radio42.com/help/html/4fd95cfd-90f8-d535-9ee6-54c400bcf545.htm and it seems pretty stringent on what you use. For example the Byte one says "This overload uses a managed byte[] to reference the buffer data! SHOULD ONLY BE USED, if the stream was created with BASS_SAMPLE_8BITS!" but I'm using 16 bits.

Chris Oakley

  • Posts: 201
Re: Taking a mixer handle in another app
« Reply #10 on: 9 Aug '22 - 10:37 »
I should also add that the suggested change didn't work. It just throws back ILL_PARAM as an error.

Ian @ un4seen

  • Administrator
  • Posts: 24589
Re: Taking a mixer handle in another app
« Reply #11 on: 9 Aug '22 - 13:45 »
What's confused me here is there are various overloads for GetChannelData http://bass.radio42.com/help/html/4fd95cfd-90f8-d535-9ee6-54c400bcf545.htm and it seems pretty stringent on what you use. For example the Byte one says "This overload uses a managed byte[] to reference the buffer data! SHOULD ONLY BE USED, if the stream was created with BASS_SAMPLE_8BITS!" but I'm using 16 bits.

Those overloads are provided by BASS.Net so that the various possible array types can be used in .Net code. All of them translate to a single native BASS_ChannelGetData function in BASS.DLL that takes a void* parameter, which is basically a pointer to anything.

When just moving blocks of data around (like in your code above), it doesn't really matter what type you use (but I would suggest bytes). The type only really matters when you want to process the data.

I should also add that the suggested change didn't work. It just throws back ILL_PARAM as an error.

Is that error from BASS_StreamPutData? If so, it sounds like the sample format of the 2 streams might not match. Perhaps the 2295.mp3 file is mono? You can ensure the formats match by using BASS_ChannelGetInfo before creating the push stream, something like this:

Code: [Select]
        Dim info As BASS_CHANNELINFO = Bass.BASS_ChannelGetInfo(_stream)
        _playstream = Bass.BASS_StreamCreatePush(info.freq, info.chans, info.flags And (BASSFlag.BASS_SAMPLE_8BITS Or BASSFlag.BASS_SAMPLE_FLOAT), IntPtr.Zero) 'Create a push stream for the incoming data

Chris Oakley

  • Posts: 201
Re: Taking a mixer handle in another app
« Reply #12 on: 9 Aug '22 - 14:16 »
OH MY GOD!!!! It was a mono file... of all the files I could have chosen I chose a mono one. Still, that's a good thing because at least I know about that now.

Ultimately this will be sending out data from a mixer so it should always match.

Thanks for explaining the get data function more, that really helps understand what's going on.

Chris Oakley

  • Posts: 201
Re: Taking a mixer handle in another app
« Reply #13 on: 9 Aug '22 - 16:29 »
So now I just need to figure out how to synchronise the data streams as they could be in different apps or on different machines.

This means the app requesting the buffer may get the same buffer again depending on its cycles and then it would push that same data to the push stream which results in a weird, almost stretched audio, artifact.

Is there anything that can help with that or am I on my own, so to speak?


Ian @ un4seen

  • Administrator
  • Posts: 24589
Re: Taking a mixer handle in another app
« Reply #14 on: 9 Aug '22 - 17:49 »
As I see it, basically, the client would open a connection with the server and the server would send back audio data until the connection is closed (by itself or the client). The client could send an initial request (to tell the server what it wants) but there shouldn't be any need for individual buffer requests, unless that's how you want to do it? If the server just sends a stream of data then there should be no chance of repeated data.