21 May '13 - 08:21 *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
 
   Home   Help Search Login Register  
Pages: [1]
  Reply  |  Print  
Author Topic: C#.NET WASAPI  (Read 1689 times)
BaseHead
Posts: 91


« on: 18 Jul '11 - 10:54 »
Reply with quoteQuote

I've hit a brick wall trying to get the WASAPI Addon playing audio.
I'm managed to get all the other addons working (for the most part) but this one has me stumped.
Anyone have a C# test project they can share for me to look at so I can sort this out and figure out how it is intertwined with existing BASS?
not finding many examples with this one as with the others

thx so much!

Steve


Logged
BaseHead
Posts: 91


« Reply #1 on: 22 Jul '11 - 11:58 »
Reply with quoteQuote

Ok, got WASAPI running and the performance seems way better now!!
Especially after previously adding BassMix into the chain that really made my app feel sluggish.

Question:   How does this interact and connect with BassMix and Bass?
I figured I'd feed a Stream into the BassMix Mixer and then route the Mixer out the WASAPI but that doesn't seem to be the case.

Setting the BassMix Mixer as the Output source doesn't work like so.
_wasapi.AddOutputSource(Mixer1, BASSFlag.BASS_DEFAULT)
(Mixer1 being my BassMix Mixer)

Only setting the output source the same as what is feeding the BassMix mixer works but then I'm bypassing the BassMixer.

Also. if I disable the  Bass.BASS_ChannelPlay(Mixer1,false); code all the timers running off BassMix to draw the playhead  also still run as if there is some sort of automatic timing sync between WASAPI and BassMix  since BassMixes Play feature is currently disabled.


So the question is:
What is the best signal flow when using WASAPI and BassMix together so I can better visualize this relationship and get my head around this better?

Thx!

Steve

Logged
BaseHead
Posts: 91


« Reply #2 on: 25 Jul '11 - 12:27 »
Reply with quoteQuote

bummer that there are no responses to this yet.
maybe a simpler question....


How do you grab Stereo Meters using WASAPI without causing chopping playback?

My old NON-WASAPI code is this and works fine

  float[] level = new float[2]; // dealing with stereo
                    if (Bass.BASS_ChannelGetLevel(_SoundPlayer.Stream, level))
                    {
                        if (Bass.BASS_ChannelGetLevel(_SoundPlayer.Stream, level))
                        {
                            float left = level[0]; // the left level
                            float right = level[1]; // the right level
                            this.meterLeft.Dispatcher.BeginInvoke((Action)delegate()
                            {
                                this.meterLeft.Value = left * 100;
                            });

                            this.meterRight.Dispatcher.BeginInvoke((Action)delegate()
                            {
                                this.meterRight.Value = right * 100;
                            });
                        }
                    }

That same code causes choppy playback with WASAPI
So I decided to grab the internal mixer handle
(Bass.BASS_ChannelGetLevel(_SoundPlayer.InternalMixer, level))
Same problem.

Then I tried to grab changing it to BassMix.BASS_Mixer_ChannelGetLevel with both handles and it grabs nothing but the choppiness does go away.

How on earth do I get the level of the stream when using WASAPI without causing the choppy playback??    Cool

thx!

Steve

Logged
radio42
Posts: 4012


« Reply #3 on: 26 Jul '11 - 10:15 »
Reply with quoteQuote

WASAPI and ASIO are working pretty similar, both require a callback function (WASAPIPROC resp. ASIOPROC) which is called when sample data is needed for output. As such both need a 'decoding' stream on which "BASS_ChannelGetData" is called within the callback in order to provide that sample data. This means no buffer is involved!
As such you can not call "BASS_ChannelGetData" on the resp. output stream for ASIO or WASAPI!
This is the main difference as compared to a WDM output - as with WDM a buffer is always involved.

The main difference between ASIO and WASAPI is, that WASAPI only supports a fixed sample rate per outout channel.
This means, that a BASSmix mixer stream should be used in order to feed source streams which might have different sample rates.
Therefore the Bass.Net "BassWasapiHandler" helper class already creates such an internal mixer stream!
You can access it via the 'InternalMixer' property.
Sources can be added to it via the 'AddOutputSource' method.

In order to get e.g. the peak level values from the mixer you have three options:
a) use your own DSPPROC and do the math yourself
b) use the Bass.Net "DSP_PeakLevelMeter" class
c) use the 'BASS_MIXER_BUFFER' flag when adding a source to the 'InternalMixer'
Logged
BaseHead
Posts: 91


« Reply #4 on: 26 Jul '11 - 10:46 »
Reply with quoteQuote

Thx Radio for making me not feel on a desert island anymore.....hehehehe
This description is really helping to visualize and understand much better!

I've been tinkering with meter "C" option already all day and can't quite figure out were to add the BUFFER flag when init'g wasapi with that great handler you made... Cool

  if (Bass.BASS_ChannelIsActive(Stream) != BASSActive.BASS_ACTIVE_PLAYING)
            {         
             Stream = Bass.BASS_StreamCreateFile(path, 0, 0, BASSFlag.BASS_STREAM_DECODE );   //BassMix 16 bit and WASAPI             
            }
             
            if (Stream != 0)
            {
                Mixer1 = BassMix.BASS_Mixer_StreamCreate(48000, 2, BASSFlag.BASS_STREAM_DECODE);
                BassMix.BASS_Mixer_StreamAddChannel(Mixer1, Stream, BASSFlag.BASS_SPEAKER_FRONT);
             
                _wasapi = new BassWasapiHandler(_Device1, false, 48000, 2, .1f, 0f); // assign WASAPI output in shared-mode0 
               _wasapi.AddOutputSource(Mixer1, BASSFlag.BASS_DEFAULT);// add the source channel
                _wasapi.Init();
                _wasapi.Start();

            }

Is it possible to add the BUFFER flag in there or do I have to go with the other way to init like below?
But I haven't had much luck with that version either I must admit

BassWasapi.BASS_WASAPI_Init(_Device1, 48000, 2, BASSWASAPIInit.BASS_WASAPI_BUFFER, 0.1f, 0f, null, IntPtr.Zero);

thx so much!

Steve

p.s. My early posts of not being able to feed BassMix to the WASAPI output was cuz I was missing the DECODE flag... Undecided
I figured that out this morning actually, but it's always good to see you confirm that one.... Grin
Logged
BaseHead
Posts: 91


« Reply #5 on: 26 Jul '11 - 12:06 »
Reply with quoteQuote

Radio!
Believe it or not, I already had your Bass.Net "DSP_PeakLevelMeter" class in my program. (Option B)
Not sure if I popped it in while messing around ages ago or my contract coder did a while back.
It wasn't working, but I went thru your example in the docs and repaired it...... Grin

one question:  What are the priority min/max values and which way is high/lower priority?  Mine is set to 1000 right now
peakLevelMeter = new DSP_PeakLevelMeter(Stream, 1000);

just wondering

If you can still answer the question to (Option C) that would be great for future reference and might come in handy..... Smiley

thx for all the WASAPI help!!

Steve
Logged
radio42
Posts: 4012


« Reply #6 on: 26 Jul '11 - 12:50 »
Reply with quoteQuote

The priority is the same as for any BASS DSP - meaning a bigger number means a higher priority.
DSPs with higher priority are called before those with lower.
E.g. a DSP with a priority of 1000 is called before another DSP with a priority of e.g. 1 or -100.

The peak levels (Left channel="LevelL" and Right channel="LevelR") are integer values between 0 (-inf.dB) and 32768 (0dB) - or higher, if the channel is floating-point. Use the "LevelL_dBV" and "LevelR_dBV" properties, if you want these integer peak values already converted into dB values (to a reference voltage of 1.0).

Regarding the Option C:
As said, the 'BASS_MIXER_BUFFER' flag should be used when adding a source to the mixer, e.g. with the "BASS_Mixer_StreamAddChannel" resp. the "_wasapi.AddOutputSource" method.

Also note, that in your code example you are still creating your 'own' mixer - which wouldn't be needed, as the "BassWasapiHandler" is already doing so! As such you are adding a mixer as a source to the BassWasapiHandler - is that intended?
Why aren't you using your 'Stream' directly with '_wasapi.AddOutputSource'?


Logged
BaseHead
Posts: 91


« Reply #7 on: 27 Jul '11 - 06:04 »
Reply with quoteQuote

Adding my own mixer was intended, but only cuz I wasn't sure what was the correct way.
Now I do know the correct way (thx to you) and I ditched that mixer!

I'm really digging WASAPI now. 
I tore it out of my code and went back to direct sound 2 times before, but I'm not going back now.... Grin
It all feels right now in the app

thx for all the info!!
It's all starting to make more and more sense!

Steve

Logged
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines