19 May '13 - 06:14 *
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 5 ... 12
  Reply  |  Print  
Author Topic: BASSWASAPI beta  (Read 71246 times)
fmcoder
Posts: 386


« Reply #40 on: 19 May '10 - 18:21 »
Reply with quoteQuote

just found the Speakers example, everything is there Smiley Sorry for bothering.
Logged
Ian @ un4seen
Administrator
Posts: 15244


« Reply #41 on: 20 May '10 - 16:18 »
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.

Regarding a solution, you could create a custom stream to use with BASS_SFX, which you would feed with data from BASSWASAPI. It could look something like this...

BASS_WASAPI_INFO wi;
BASS_WASAPI_GetInfo(&wi); // get WASAPI info
sfxstream=BASS_StreamCreate(wi.freq, wi.chans, BASS_SAMPLE_FLOAT|BASS_STREAM_DECODE, StreamProc, NULL); // create custom stream with same format

...

DWORD CALLBACK StreamProc(HSTREAM handle, void *buf, DWORD len, void *user)
{
DWORD c=BASS_WASAPI_GetData(buf, len); // get data from the WASAPI output
if (c==-1) c=0; // an error
    return c;
}

You would use the "sfxstream" handle in the BASS_SFX calls. You also need to use the BASS_WASAPI_BUFFER flag in your BASS_WASAPI_Init call to enable the BASS_WASAPI_GetData function.
Logged
fmcoder
Posts: 386


« Reply #42 on: 20 May '10 - 20:30 »
Reply with quoteQuote

Strange behaviour of WASAPI addon.
If I use the "-1" device number, everything works great. But if I use specific device number, like "2", all calls to BASS_WASAPI_* functions are successful, but there is no sound.
I checked, it makes calls to the WasapiProc.
What could it be?

Also, how can I control the output volume without using the BASS_WASAPI_SetVolume function (as it changes the global device volume in the system)? Write my own dsp?

Thanks.
« Last Edit: 20 May '10 - 20:43 by fmcoder » Logged
Ian @ un4seen
Administrator
Posts: 15244


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

Strange behaviour of WASAPI addon.
If I use the "-1" device number, everything works great. But if I use specific device number, like "2", all calls to BASS_WASAPI_* functions are successful, but there is no sound.
I checked, it makes calls to the WasapiProc.
What could it be?

Is device 2 an output device? Note that the device list contains both output and input devices, so you need to use BASS_WASAPI_GetDeviceInfo to find out which are which; you can find a demonstration of that in the RECTEST example.

Also, how can I control the output volume without using the BASS_WASAPI_SetVolume function (as it changes the global device volume in the system)? Write my own dsp?

Yes, you could write your own DSP to do that, or use BASS_FX's BASS_FX_BFX_VOLUME effect. If you're using BASSmix, another option is to make use of the sources' BASS_ATTRIB_VOL attribute (via BASS_ChannelSetAttribute).
Logged
fmcoder
Posts: 386


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

Is device 2 an output device? Note that the device list contains both output and input devices, so you need to use BASS_WASAPI_GetDeviceInfo to find out which are which; you can find a demonstration of that in the RECTEST example.
I will check this. Maybe, this is a problem. Thanks.

Yes, you could write your own DSP to do that, or use BASS_FX's BASS_FX_BFX_VOLUME effect. If you're using BASSmix, another option is to make use of the sources' BASS_ATTRIB_VOL attribute (via BASS_ChannelSetAttribute).
I'm using Splitter, i.e one Mixer channel splitted to many outputs. But it seems, that splitter doesn't takes source (which is mixer channel) volume into account. I'll try to play with DSP.
Logged
aybe
Posts: 129


« Reply #45 on: 26 May '10 - 14:08 »
Reply with quoteQuote

Hello,

I am getting the following error when using the library :

An incorrect version of BASSWASAPI was loaded !

Version loaded : 0.0
Version expected : 1.0


Any further calls produce weird results like 150 devices present ...

I have updated my Bass.Net reference with the DLL on the first post but it didn't help much ...

Thank you !
Logged
radio42
Posts: 4012


« Reply #46 on: 26 May '10 - 16:42 »
Reply with quoteQuote

Please try this version (as it includes the latest WASAPI updates):

Pre v2.4.6.5:
  www.un4seen.com/filez/4/Bass24.Net_pre.zip
Logged
aybe
Posts: 129


« Reply #47 on: 26 May '10 - 18:34 »
Reply with quoteQuote

I've just tested the link you gave me,

It's almost ok (no more version error) BUT results are still completely wrong,
I am still getting +150 devices detected with BASS_WASAPI_GetDeviceInfos()  Huh

Any ideas ?

Thank you  Cheesy
Logged
ken
Posts: 630


« Reply #48 on: 26 May '10 - 22:12 »
Reply with quoteQuote

I've just tested the link you gave me,

It's almost ok (no more version error) BUT results are still completely wrong,
I am still getting +150 devices detected with BASS_WASAPI_GetDeviceInfos()  Huh

Any ideas ?

Thank you  Cheesy

aybe, try my code snipp for listing devices. I found that wasapi is very different to directx and asio:  http://www.un4seen.com/forum/?topic=11170.msg78373#msg78373
Logged
aybe
Posts: 129


« Reply #49 on: 27 May '10 - 15:03 »
Reply with quoteQuote

Alright thanks  Grin
Logged
aybe
Posts: 129


« Reply #50 on: 27 May '10 - 15:56 »
Reply with quoteQuote

Here is a quick & dirty utility I just made to have a better view of BassWasapi.

It retrieves all the devices then displays them in a sortable grid; I understood how it works now Grin

It's very basic but you'll see why there are so many devices detected.

So I decided to share it with you,


Create a WPF project and paste this code :

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Un4seen.BassWasapi;

namespace BassWasapiViewer{
    /// <summary>
    ///   Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window{
        private ListSortDirection _lastDirection = ListSortDirection.Ascending;
        private GridViewColumnHeader _lastHeaderClicked;

        public MainWindow(){
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e){
            var devices = new WasapiDevices();
        }


        private void GridViewColumnHeaderClickedHandler(object sender,
                                                        RoutedEventArgs e){
            var headerClicked =
                e.OriginalSource as GridViewColumnHeader;
            ListSortDirection direction;

            if (headerClicked != null)
            {
                if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
                {
                    if (headerClicked != _lastHeaderClicked)
                    {
                        direction = ListSortDirection.Ascending;
                    }
                    else
                    {
                        if (_lastDirection == ListSortDirection.Ascending)
                        {
                            direction = ListSortDirection.Descending;
                        }
                        else
                        {
                            direction = ListSortDirection.Ascending;
                        }
                    }

                    var header = headerClicked.Column.Header as string;
                    Sort(header, direction);

                    if (direction == ListSortDirection.Ascending)
                    {
                        headerClicked.Column.HeaderTemplate =
                            Resources["HeaderTemplateArrowUp"] as DataTemplate;
                    }
                    else
                    {
                        headerClicked.Column.HeaderTemplate =
                            Resources["HeaderTemplateArrowDown"] as DataTemplate;
                    }

                    // Remove arrow from previously sorted header
                    if (_lastHeaderClicked != null && _lastHeaderClicked != headerClicked)
                    {
                        _lastHeaderClicked.Column.HeaderTemplate = null;
                    }


                    _lastHeaderClicked = headerClicked;
                    _lastDirection = direction;
                }
            }
        }

        private void Sort(string sortBy, ListSortDirection direction){
            ICollectionView dataView =
                CollectionViewSource.GetDefaultView(lv.ItemsSource);

            dataView.SortDescriptions.Clear();
            var sd = new SortDescription(sortBy, direction);
            dataView.SortDescriptions.Add(sd);
            dataView.Refresh();
        }
    }

    internal class MyClass{
        public MyClass(BASS_WASAPI_DEVICEINFO deviceinfo){
            Defperiod = deviceinfo.defperiod;
            Flags = deviceinfo.flags;
            Id = deviceinfo.id;
            IsDefault = deviceinfo.IsDefault;
            IsEnabled = deviceinfo.IsEnabled;
            IsInitialized = deviceinfo.IsInitialized;
            IsInput = deviceinfo.IsInput;
            IsLoopback = deviceinfo.IsLoopback;
            Minperiod = deviceinfo.minperiod;
            Mixchans = deviceinfo.mixchans;
            Mixfreq = deviceinfo.mixfreq;
            Name = deviceinfo.name;
            SupportsRecording = deviceinfo.SupportsRecording;
            Type = deviceinfo.type;
        }

        public float Defperiod { get; private set; }
        public BASSWASAPIDeviceInfo Flags { get; private set; }
        public string Id { get; private set; }
        public bool IsDefault { get; private set; }
        public bool IsEnabled { get; private set; }
        public bool IsInitialized { get; private set; }
        public bool IsInput { get; private set; }
        public bool IsLoopback { get; private set; }
        public float Minperiod { get; private set; }
        public int Mixchans { get; private set; }
        public int Mixfreq { get; private set; }
        public string Name { get; private set; }
        public bool SupportsRecording { get; private set; }
        public BASSWASAPIDeviceType Type { get; private set; }
    }

    internal class WasapiDevices : ObservableCollection<MyClass>{
        public WasapiDevices(){
            var bassWasapiGetDeviceInfos = BassWasapi.BASS_WASAPI_GetDeviceInfos();
            foreach (var bassWasapiGetDeviceInfo in bassWasapiGetDeviceInfos)
            {
                Add(new MyClass(bassWasapiGetDeviceInfo));
            }
        }
    }
}

<Window x:Class="BassWasapiViewer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:BassWasapiViewer="clr-namespace:BassWasapiViewer"
        Title="MainWindow"
        Height="350"
        Width="525"
        Loaded="Window_Loaded">
    <Window.Resources>

        <BassWasapiViewer:WasapiDevices x:Key="wasapi">

        </BassWasapiViewer:WasapiDevices>

    </Window.Resources>
    <Grid>
        <ListView x:Name="lv"
                  DataContext="{Binding Source={StaticResource wasapi}}"
                  ItemsSource="{Binding }"
                  GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler">

            <ListView.View>
                <GridView AllowsColumnReorder="True">

                    <GridViewColumn Header="Name"
                                    DisplayMemberBinding="{Binding Path=Name}" />
                    <GridViewColumn Header="Type"
                                    DisplayMemberBinding="{Binding Path=Type}" />
                    <GridViewColumn Header="Flags"
                                    DisplayMemberBinding="{Binding Path=Flags}" />

                    <GridViewColumn Header="IsDefault"
                                    DisplayMemberBinding="{Binding Path=IsDefault}" />
                    <GridViewColumn Header="IsEnabled"
                                    DisplayMemberBinding="{Binding Path=IsEnabled}" />
                    <GridViewColumn Header="IsInitialized"
                                    DisplayMemberBinding="{Binding Path=IsInitialized}" />
                    <GridViewColumn Header="IsInput"
                                    DisplayMemberBinding="{Binding Path=IsInput}" />
                    <GridViewColumn Header="IsLoopback"
                                    DisplayMemberBinding="{Binding Path=IsLoopback}" />
                    <GridViewColumn Header="SupportsRecording"
                                    DisplayMemberBinding="{Binding Path=SupportsRecording}" />

                    <GridViewColumn Header="Defperiod"
                                    DisplayMemberBinding="{Binding Path=Defperiod}" />
                    <GridViewColumn Header="Minperiod"
                                    DisplayMemberBinding="{Binding Path=Minperiod}" />
                    <GridViewColumn Header="Mixchans"
                                    DisplayMemberBinding="{Binding Path=Mixchans}" />
                    <GridViewColumn Header="Mixfreq"
                                    DisplayMemberBinding="{Binding Path=Mixfreq}" />
                    <GridViewColumn Header="Id"
                                    DisplayMemberBinding="{Binding Path=Id}" />
                </GridView>
            </ListView.View>

        </ListView>
    </Grid>
</Window>


See ya !
Logged
aybe
Posts: 129


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

I fixed it, input devices cannot have a proc that is null !

 Grin

I'm currently having issues for EXCLUSIVE, every time I get either BASS_ERROR_ILLPARAM or BASS_ERROR_UNKNOWN.
Any parameters set for period never work. No problems when using SHARED though ...

I tried also another (Edirol UA-101) device (beside the integrated one) but it's the same.
I also checked the control panel, they are all allowed to be exclusive.

Any ideas ?

Thank you !

           var list = new List<WasapiDevice>();
            var deviceInfos = BassWasapi.BASS_WASAPI_GetDeviceInfos();
            for (int index = 0; index < deviceInfos.Length; index++)
            {
                var deviceInfo = deviceInfos[index];
                if (!deviceInfo.IsEnabled) continue;

                // Try exclusive init
                if (!BassWasapi.BASS_WASAPI_Init(index, deviceInfo.mixfreq, deviceInfo.mixchans,
                                                 BASSWASAPIInit.BASS_WASAPI_EXCLUSIVE, 8, 2, null,
                                                 IntPtr.Zero))
                {
                    var bassError = ErrCheck();
                    continue;
                }

                // Get extra infos and add this device to list
                var info = BassWasapi.BASS_WASAPI_GetInfo();
                if (info != null)
                    list.Add(new WasapiDevice(index, deviceInfo, info));

                // Done with it
                if (!BassWasapi.BASS_WASAPI_Free())
                {
                    var bassError = ErrCheck();
                }
            }
[/s]
« Last Edit: 27 May '10 - 20:28 by aybe » Logged
martin
Posts: 34


« Reply #52 on: 29 May '10 - 08:07 »
Reply with quoteQuote

Hi,
firstly thank you very much for this great addon!

What is the easiest way to filter out all input devices and display only the playback devices while using BassWasapi.BASS_WASAPI_GetDeviceInfo?

The other way round it is easy, but of course nearly all playback devices are at the same time input devices as well...

Thank you!
Martin
Logged
Ian @ un4seen
Administrator
Posts: 15244


« Reply #53 on: 31 May '10 - 16:34 »
Reply with quoteQuote

Input devices (including loopback devices) can be identified by the BASS_DEVICE_INPUT flag in the BASS_WASAPI_DEVICEINFO.flags member, so you would do something like this...

BASS_WASAPI_DEVICEINFO info;
BASS_WASAPI_GetDeviceInfo(device, &info); // get device info
if (!(info.flags&BASS_DEVICE_INPUT)) { // check that it isn't an input device
// do something with it, eg. add to a list
}

As mentioned earlier in this thread, if you are planning to use a list as a device selector, be sure to retain the device number too (for use in the BASS_WASAPI_Init call). You can find an example of that in the RECTEST.C source file in the BASSWASAPI package.
Logged
ken
Posts: 630


« Reply #54 on: 5 Jun '10 - 13:26 »
Reply with quoteQuote

I'm trying to use "BASS_Mixer_ChannelGetPositionEx" with Bass.NET (based on the "contest" example. But get error on Lock:

Quote
Cannot marshal 'return value': Invalid managed/unmanaged type combination (Single must be paired with R4).

How should I do it? Here is my code for getting position in C#.

public TimeSpan GetPosition
{
      get
      {
               
                TimeSpan _ts = new TimeSpan();

                BassWasapi.BASS_WASAPI_Lock(true);
                int _delay = BassWasapi.BASS_WASAPI_GetData(null,(int)Un4seen.Bass.BASSData.BASS_DATA_AVAILABLE);
                _ts = TimeSpan.FromSeconds(Bass.BASS_ChannelBytes2Seconds(_channel1, BassMix.BASS_Mixer_ChannelGetPositionEx(_channel1, BASSMode.BASS_POS_MUSIC_ORDERS, _delay)));
                BassWasapi.BASS_WASAPI_Lock(false);

            return _ts;
      }
}


BTW, is there a 64-bit version of BASSWASAPI?

/Ken
Logged
radio42
Posts: 4012


« Reply #55 on: 5 Jun '10 - 22:16 »
Reply with quoteQuote

Have you created the mixer with the BASS_MIXER_POSEX flag.

I just made a little test and it seems I am unable to reproduce the issue - here it is working fine without any issues.
So are you probably mixing any 32-/64-bit codes?
What is your app running at? Compiled for x86 or x64?
And what versions are you using?
Logged
ken
Posts: 630


« Reply #56 on: 6 Jun '10 - 12:32 »
Reply with quoteQuote

Have you created the mixer with the BASS_MIXER_POSEX flag.

I did not at first, but adding BASS_MIXER_POSEX give me the same error. This is a 32-bit computer (Windows 7 32) I was asking x64 for future needs.

Here is how I add mixer and wasapi, wish works perfect until posEx:
  Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_UPDATEPERIOD, 0);
            Bass.BASS_Init(-1, audioDevOut.MixFreq, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero);

            _mixer = BassMix.BASS_Mixer_StreamCreate(audioDevOut.MixFreq, 2, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_MIXER_NONSTOP | BASSFlag.BASS_MIXER_POSEX);

            _BassWasapiHandlerOut = new BassWasapiHandler(audioDevOut.DeviceID, false, audioDevOut.MixFreq, 2, BufferOut, 0);

            bool _retInit = _BassWasapiHandlerOut.Init();

     
            _BassWasapiHandlerOut.AddOutputSource(_mixer, BASSFlag.BASS_DEFAULT);

            bool _retStart = _BassWasapiHandlerOut.Start();


Bass.dll v2.4.5.19
Bass.Net.dll v2.4.6.5
bassmix.dll v2.4.4.2 (from wasapi)
basswasapi.dll v0.0.0.3
Logged
Ian @ un4seen
Administrator
Posts: 15244


« Reply #57 on: 7 Jun '10 - 15:22 »
Reply with quoteQuote

                _ts = TimeSpan.FromSeconds(Bass.BASS_ChannelBytes2Seconds(_channel1, BassMix.BASS_Mixer_ChannelGetPositionEx(_channel1, BASSMode.BASS_POS_MUSIC_ORDERS, _delay)));

I don't know if it is the cause of your troubles, but judging by the BASS_ChannelBytes2Seconds call, I guess that is meant to be BASS_POS_BYTE rather than BASS_POS_MUSIC_ORDERS?

BTW, is there a 64-bit version of BASSWASAPI?

Yep, a 64-bit DLL is now included in the BASSWASAPI package (see 1st post).
Logged
radio42
Posts: 4012


« Reply #58 on: 7 Jun '10 - 15:43 »
Reply with quoteQuote

Oh yes, that should be the troublesome line, as BASS_POS_MUSIC_ORDERS would return -1 for the BASS_Mixer_ChannelGetPositionEx call.
So it should definitly be BASS_POS_BYTE !
Logged
ken
Posts: 630


« Reply #59 on: 7 Jun '10 - 16:11 »
Reply with quoteQuote

Oh yes, that should be the troublesome line, as BASS_POS_MUSIC_ORDERS would return -1 for the BASS_Mixer_ChannelGetPositionEx call.
So it should definitly be BASS_POS_BYTE !

Oh, yes that is totally wrong...

But my code hangs on BassWasapi.BASS_WASAPI_Lock(true);

It do work with just:
int _delay = BassWasapi.BASS_WASAPI_GetData(null, (int)Un4seen.Bass.BASSData.BASS_DATA_AVAILABLE);
_ts = TimeSpan.FromSeconds(Bass.BASS_ChannelBytes2Seconds(_channel1, BassMix.BASS_Mixer_ChannelGetPositionEx(_channel1, BASSMode.BASS_POS_BYTES, _delay)));

do I need BassWasapi.BASS_WASAPI_Lock(true) ? What does it do?

/Ken
Logged
Pages: 1 2 [3] 4 5 ... 12
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines