21 Nov '14 - 08:03 *
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 [2] 3 4 ... 13
  Reply  |  Print  
Author Topic: BASSWASAPI beta  (Read 108244 times)
ken
Posts: 666


« Reply #20 on: 5 May '10 - 08:20 »
Reply with quoteQuote

Just get "real" audio-devices was a tricky thing. Here I do it in C# with Bass.NET filling two comboboxes (cmbDevOut and cmbDevIn).  It can proberly made in outher ways, but this works for me...


        private void GetDevices()
        {
           

            BASS_WASAPI_DEVICEINFO info = new BASS_WASAPI_DEVICEINFO();

            for (int i = 0; BassWasapi.BASS_WASAPI_GetDeviceInfo(i, info); i++)
            {
                AudioDevice _AudioDevice = new AudioDevice();
                _AudioDevice.DeviceName = info.name;


                if (!info.IsInput)
                {
                    if (info.IsEnabled)
                    {
                        _AudioDevice.DeviceID = i;
                        cmbDevOut.Items.Add(_AudioDevice);
                    }
                }

                if (info.SupportsRecording)
                {
                    if (info.IsEnabled && info.IsLoopback == false)
                    {
                        _AudioDevice.DeviceID = i;
                        cmbDevIn.Items.Add(_AudioDevice);
                    }
                }
               
            }
        }


//my class for device infos
public class AudioDevice
    {
        public AudioDevice()
        { }

        public int DeviceID { get; set; }
        public string DeviceName { get; set; }

    }



And get Device id for BASSWasapi


AudioDevice _AudioDevice = (AudioDevice)cmbDevOut.SelectedItem;

_wasapi = new BassWasapiHandler(_AudioDevice.DeviceID, false, 48000, 2, 0, 0);

Logged
Ian @ un4seen
Administrator
Posts: 17169


« Reply #21 on: 5 May '10 - 14:32 »
Reply with quoteQuote

I'm trying to use the WASAPI "Exclusive" mode to achieve a "bit-perfect" rendering of "lossless" audio.  I don't have a problem with the sample data being converted (up to 24 "bits per sample") into 32 bit FP data.  But I want to be sure that the soundcard is rendering at that original bps or better (ex., 96kHz, 2 Channel @ 24 bits per sample). 

In your BASS_WASAPI_GetInfo method; the "format" field will return the devices "bits per sample" (bps); which is useful when inspecting the "mixer" format.  However it does not seem possible to "set" this field in the BASS_WASAPI_Init for Exclusive mode.  I would also have expected to see this in the BASS_WASAPI_CheckFormat method.

When using the IAudioClient interface directly; I can test and inititalize this using "IsFormatSupported" and "Initialize" with the correct WaveFormatEx structure.

Using your implementation; how do I ensure that a valid "bits per sample" is correctly selected in the soundcard/device?

To simplify matters, BASSWASAPI_Init always initializes the device to use the highest supported resolution, which is then available via the BASS_WASAPI_INFO "format" member. Note that is the format currently in use, not necesarily the "mix" format (which is always floating-point).

Just get "real" audio-devices was a tricky thing. Here I do it in C# with Bass.NET filling two comboboxes (cmbDevOut and cmbDevIn).  It can proberly made in outher ways, but this works for me...

...

That looks fine. The key thing is to store the device number (as you have done), ie. don't just use a list index to determine which device to initialize. The same applies to BASS device selectors.
Logged
Mike Wittman
Posts: 20


« Reply #22 on: 10 May '10 - 00:05 »
Reply with quoteQuote

Good Evening Ian; (2 questions)

I am looking for an easy way to get the current soundcard default "output format" (as in the Windows Control Panel)

It seems that when initializing WASAPI as "BASS_WASAPI_Init(-1, 0, 0, BASS_WASAPI_EXCLUSIVE, 0.4 , 0.05, WasapiProc, NULL)" I receive this information correctly. (NOTE: Uses mix format, but Exclusive Flag)

Is this a reliable method to achieve this goal?

Secondly, using the same technique but, substituting the mix format (0, 0) with a requested format (ex., 96000, 2); if the function returns true then; is this "output format" actually supported by the soundcard.

I am using these techniques now and they seem to work, but I wanted to verify this with you.

Thank-you;
Mike Wittman
Logged
Mike Wittman
Posts: 20


« Reply #23 on: 10 May '10 - 04:20 »
Reply with quoteQuote

Good Morning Ian;

With a little more testing this technique for discovering the "bit resolution" (see previous post) works fine until the frequency is NOT supported.  In which case; the error number returned is -1 (BASS_ERROR_UNKNOWN).  I believe it should be BASS_ERROR_FORMAT.

PS: This is in a tight  loop to "discover" some common rates like 44.1, 48 & 96 KHz

Your thoughts on all this ?

Regards .. Mike Wittman
Logged
Ian @ un4seen
Administrator
Posts: 17169


« Reply #24 on: 10 May '10 - 13:37 »
Reply with quoteQuote

I am looking for an easy way to get the current soundcard default "output format" (as in the Windows Control Panel)

It seems that when initializing WASAPI as "BASS_WASAPI_Init(-1, 0, 0, BASS_WASAPI_EXCLUSIVE, 0.4 , 0.05, WasapiProc, NULL)" I receive this information correctly. (NOTE: Uses mix format, but Exclusive Flag)

Is this a reliable method to achieve this goal?

That information is actually available without having to initialize the device, from BASS_GetDeviceInfo (see the "mixfreq" and "mixchans"). Perhaps you are using BASS_WASAPI_Init in order to get the shared mode output resolution too? That probably won't be reliable, as the user might not have chosen the highest available resolution, while BASS_WASAPI_Init will.

Secondly, using the same technique but, substituting the mix format (0, 0) with a requested format (ex., 96000, 2); if the function returns true then; is this "output format" actually supported by the soundcard.

Yes, so long as you don't use the BASS_WASAPI_AUTOFORMAT flag, a successful BASS_WASAPI_Init call means that the requested format is supported. You could also use BASS_WASAPI_CheckFormat for that purpose, which should be quicker, but that won't tell you the resolution (if you want to know that too).

With a little more testing this technique for discovering the "bit resolution" (see previous post) works fine until the frequency is NOT supported.  In which case; the error number returned is -1 (BASS_ERROR_UNKNOWN).  I believe it should be BASS_ERROR_FORMAT.

That does sound like it should result in BASS_ERROR_FORMAT, but I guess WASAPI is reporting something other than a format problem; I'll send you a debug version to find out what exactly.
Logged
Mike Wittman
Posts: 20


« Reply #25 on: 10 May '10 - 14:21 »
Reply with quoteQuote

Thanks Ian;

Yes; it's ALL about the "bit resolution"!  I don't know if you follow "Audiophile" digital music threads; but in essence the guys that spend $20,00 on speakers  (I'm not in that league, by the way); don't want thier PC messing with the audio stream.  It's about RFI/EMI, jitter, signal compression or modification, you name it they hate it!

So I've developed an USB Isochronous/Asynchronous w/ rate feedback (DACless) soundcard and a "music librarian" for my Audiophile friends to keep the audio signal jitter-free and "pure" digital throughout the signal path.

In the Audiophile world of lossless digital music then; upsampling the bit resolution is ok, but frequency shifts are very controversial.  After a lot of hardware research; I found the recommendation to upsample frequency only in 2X increments; ie., 44.1 to 88.2 etc.  Yet, there is also a strong belief that modern PC's running DSP algorithmns can do this more effectively than hardware.  So at some point soon I'll be interested in your BASSmix product.

But for now; I'm just focusing on WASAPI in exclusive mode and doing exact frequency matches which will allow "upsampling" of the sample bit resolution.

PS: If I get this right, I'm sure there's "commercial potential" and then I can pay you the licensing fees you so richly deserve!
Logged
Ian @ un4seen
Administrator
Posts: 17169


« Reply #26 on: 11 May '10 - 13:34 »
Reply with quoteQuote

OK. It looks like one small change that could simplify/speed things for you would be to have BASS_WASAPI_CheckFormat return the supported resolution (BASS_WASAPI_FORMAT_xxx) rather than simply TRUE. Do you just want to be able to detect the (maximum) resolution, not set it? As you say, using a higher resolution than necessary (eg. 24-bit output for 16-bit data) won't break lossless output.

Btw, have you received the debug DLL version? It appears to have been delivered, so if you don't see it, please check your spam folder.
Logged
Mike Wittman
Posts: 20


« Reply #27 on: 11 May '10 - 15:53 »
Reply with quoteQuote

That would be great IAN  !

Using BASS_WASAPI_CheckFormat to get the "highest bit resolution" would be much less overhead !

What might be even more thorough; is being able to get the "exact" match, perhaps with an (ExactMatch) boolean prameter defaulted to false.  Where True says I need the exact resolution and False (default) returns the "highest" available.

PS: I've just sent you my debug results
Logged
Mike Wittman
Posts: 20


« Reply #28 on: 11 May '10 - 17:47 »
Reply with quoteQuote

Ian - I just reread your post and I missed the question in there ..

No - I do not need to "set" the bit resolution as long as BASS_WASAPI is using the highest available.  I just need to know what it is, so that I can display the difference (especially in case where it might be "down-sampled").

[STANDING on my SOAPBOX ..]

From an "audiophile purist" point of view; IF.. the BASS.dll decoder could be coerced into producing 24 bit samples (I know the DirectSound/Render side can't handle this), then there is an argument to stay in the "integer" world and hence, explicitly set "exact" bit resolutions on the device. 

This is for two reasons.  One; is that the compiler/cpu accuracy of converting an integer into a range of +1.0 to -1.0 (32bit fp) isn't truly exact and two; to eliminate the overhead of 2 conversions (back and forth), and just pump the output to WASAPI.

But overall your design decision to use 32bit float makes alot of sense; especially since quite a few CODEC's use it natively.  In fact; one obvious benefit of 32bit FP (that I can actually "hear") is enhanced Volume and Parametric EQ FX (or any DSP).

Unfortunately in the "lossless" rendering world; non-floating point formats (like FLAC, WAV and Apple Lossless) arguably "suffer" from it.

But life is about making "right" compromies, no?

Mike Wittman.
Logged
Mike Wittman
Posts: 20


« Reply #29 on: 12 May '10 - 15:41 »
Reply with quoteQuote

Ian;

In regards to my previous post, perhaps there's an alternative and "cleaner" solution ..

Since 95% of all music is recorded in the "redbook" format (i.e. 44100 Hhz, 16 bit, 2 Channel).  What if; you added and overloaded version of the WASAPIPROC callback function where the buffer points to integer data? 

This way, we could use the normal BASS decoder functions and pump "bit perfect" data thru WASAPI exclusive mode!

It also might open a "back door" to other integer formats such as 24 bit (getting more common) and 32 bit (studio recordings).

Just thinking out loud ..
Logged
Ian @ un4seen
Administrator
Posts: 17169


« Reply #30 on: 13 May '10 - 15:53 »
Reply with quoteQuote

Using BASS_WASAPI_CheckFormat to get the "highest bit resolution" would be much less overhead !

An update is in the BASSWASAPI package (see 1st post), in which the BASS_WASAPI_CheckFormat return value has been changed to a BASS_WASAPI_FORMAT value to indicate the maximum supported resolution. A new error code (BASS_ERROR_BUSY) has also been added for BASS_WASAPI_Init, to indicate that the device is busy, eg. in "exclusive" use by another process.

What might be even more thorough; is being able to get the "exact" match, perhaps with an (ExactMatch) boolean prameter defaulted to false.  Where True says I need the exact resolution and False (default) returns the "highest" available.

Do you mean checking the support for specific resolutions? So long as BASS always uses the highest available resolution (as is currently the case), I'm not sure there is really any need for that.

This is for two reasons.  One; is that the compiler/cpu accuracy of converting an integer into a range of +1.0 to -1.0 (32bit fp) isn't truly exact and two; to eliminate the overhead of 2 conversions (back and forth), and just pump the output to WASAPI.

32-bit floating-point can bit-perfectly maintain up to 24-bit integer data, so nothing will be lost in that conversion. If the source data isn't originally floating-point, it does mean some CPU overhead, but that is low. Note the lossy format decoders (eg. MP3/OGG/MPC/AAC) will generally produce floating-point data internally, so it is actually less overhead to keep them floating-point; I say "generally" as the Windows MP3 codec is an exception, as is WMA.

There are a few reasons for BASSWASAPI always using floating-point sample data, but primarilly it is to keep things simple; the user only has to use the BASS_SAMPLE_FLOAT flag when creating source streams regardless of the file format, and BASSWASAPI doesn't have to bother with converting between different integer resolutions (eg. if the user wants to play 24-bit data but the device only supports 16-bit). Another consideration is that BASS doesn't currently include 24-bit stream support, so the only way to play 24-bit files bit-perfectly is to use a floating-point stream anyway Smiley
Logged
Mike Wittman
Posts: 20


« Reply #31 on: 13 May '10 - 21:28 »
Reply with quoteQuote

Thanks for the update Ian;

The suggestion for an "ExactMatch" parameter in BASS_WASAPI_CheckFormat was to query the device to 1) get its absolute current setting (say retrieve the Windows default setting) and 2) build a list of all supported formats.  Purely "dashboard" stuff NOT a core function.

The changes you made to BASS_WASAPI_CheckFormat solved my problem with having to INIT to test every frequency/bit resolution combination - GREAT!

As you know I've already found use for the new BASS_ERROR_BUSY code !

As for 32 bit float vs 24 bit integers, I agree that arithemetically they can be proven equivalent.  But my years in the scientific and financial programming jungle has taught me that this is less true in the "wild".  Fractions with repeating patterns will be rounded or truncated after about the 8 significant digit and hence multiplying the result to get the original number back can be proven to be problematical  ( Huh what is effortless on a $2 calculator causes a microprocesser fits) Of course the margin of error is ridiculously low and doesn't have alot of significance here.

If however; I use the legal term "bit perfect" in marketing materials you can bet a $1000 that some Audiophile will plugin a digital loopback connection and compare the output sample by sample ! (and then want his money back)  Roll Eyes

I'm fine with 32bit FP as you've implemented it.
Logged
Ian @ un4seen
Administrator
Posts: 17169


« Reply #32 on: 14 May '10 - 16:45 »
Reply with quoteQuote

As for 32 bit float vs 24 bit integers, I agree that arithemetically they can be proven equivalent.  But my years in the scientific and financial programming jungle has taught me that this is less true in the "wild".  Fractions with repeating patterns will be rounded or truncated after about the 8 significant digit and hence multiplying the result to get the original number back can be proven to be problematical  ( Huh what is effortless on a $2 calculator causes a microprocesser fits) Of course the margin of error is ridiculously low and doesn't have alot of significance here.

That could be a problem if additional operations are performed on the data mid-sequence, but not so if it is just an integer->float->integer conversion sequence, unless there is something very wrong with the FPU Smiley

An explanation and additional information on the subject can be found here:

   http://en.wikipedia.org/wiki/Floating_point

Quote
Any integer with absolute value less than or equal to 224 can be exactly represented in the single precision format, and any integer with absolute value less than or equal to 253 can be exactly represented in the double precision format. Furthermore, a wide range of powers of 2 times such a number can be represented.
Logged
Mike Wittman
Posts: 20


« Reply #33 on: 15 May '10 - 16:13 »
Reply with quoteQuote

Do the DirectSound FX still work under WASAPI ? (I'm not opening a stream using the BASS_SAMPLE_FX flag)

How about DSP?

In other words; since we're opening streams as a decode, pretty much everthing you can do in decode should work in WASAPI, right?

I've never done a BASS_Init with a "no sound" device before, so I was wondering what signal processing  (if any) can be applied before "sample data" is sent to WASAPI via the "callback".
Logged
Ian @ un4seen
Administrator
Posts: 17169


« Reply #34 on: 17 May '10 - 15:23 »
Reply with quoteQuote

Yes, DSP/FX can be applied when using WASAPI output. An example of that can be found in the SYNTH example included in the BASSWASAPI package. DSP/FX can also be applied to any sample data via a "dummy" stream (with the same format as the data), something like this...

dummy = BASS_StreamCreate(freq, chans, BAS_SAMPLE_FLOAT|BASS_STREAM_DECODE, STREAMPROC_DUMMY, NULL); // create a dummy stream
BASS_ChannelSetFX(dummy, ...); // set some FX on it

...

BASS_ChannelGetData(dummy, data, datalen); // pass some sample data through the dummy stream

The reason that works is that dummy streams don't have any sample data of their own, so the BASS_ChannelGetData buffer content remains and gets passed through any DSP/FX that are on the dummy stream.
Logged
Mike Wittman
Posts: 20


« Reply #35 on: 17 May '10 - 16:07 »
Reply with quoteQuote

That's fantastic (FX/DSP) news .. a very comprehensive WASAPI solution  Cheesy

Regarding the use of the BASS mixer (for either WASAPI Shared OR Exclusive) .. I was wondering a bit about the "mixer" internals; since I've not used it before.

Is the mixer a wrapper around DirectSound or a custom implementation that you've developed yourself?  From my perspective, using the mixer to "upsample" WASAPI  (ex. 44.1 KHz to 88.2) could be very powerful (especially with DSP) .  How would you assess the BASS Mixer implementation in regards to such tasks?

Any downsides from your experience?

 
Logged
Ian @ un4seen
Administrator
Posts: 17169


« Reply #36 on: 18 May '10 - 14:50 »
Reply with quoteQuote

BASSmix uses its own mixing and resampling routines. It isn't the pinnacle of resampling, but it's not the worst either Smiley ... The BASS_MIXER_FILTER flag can be used (with BASS_Mixer_StreamAddChannel) to reduce aliasing; also see the BASS_CONFIG_MIXER_FILTER config option.
Logged
ifynk
Posts: 3


« Reply #37 on: 19 May '10 - 07:56 »
Reply with quoteQuote

Why when i use SFX the playing of song be faster?

And BASS_ChannelIsActive(FAudioStream) always return BASS_ACTIVE_PLAYING. How i can Play and Pause my Stream?

PS: Sorry for my poor english.
« Last Edit: 19 May '10 - 09:00 by ifynk » Logged
Ian @ un4seen
Administrator
Posts: 17169


« Reply #38 on: 19 May '10 - 14:51 »
Reply with quoteQuote

Why when i use SFX the playing of song be faster?

The problem there will be that the vis processing is taking data from the decoding channel (via BASS_ChannelGetData), and that data is then missing from the BASS_ChannelGetData call in your WASAPIPROC.

And BASS_ChannelIsActive(FAudioStream) always return BASS_ACTIVE_PLAYING. How i can Play and Pause my Stream?

You can use BASS_WASAPI_Stop (reset=FALSE) to pause the output, and then BASS_WASAPI_Start to resume it.

Note that with a decoding channel (BASS_STREAM_DECODE used at creation), BASS_ChannelIsActive indicates whether it has reached the end... BASS_ACTIVE_STOPPED = ended, BASS_ACTIVE_PLAYING = not.
Logged
fmcoder
Posts: 394


« Reply #39 on: 19 May '10 - 17:13 »
Reply with quoteQuote

Hello!
Just started to work with this addon. Seems to work fine, thanks.
It it possible to do speaker assignment when using WASAPI output?
Logged
Pages: 1 [2] 3 4 ... 13
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.20 | SMF © 2013, Simple Machines